summaryrefslogtreecommitdiffstats
path: root/ldap/c-sdk/libraries/libldap/saslbind.c
diff options
context:
space:
mode:
Diffstat (limited to 'ldap/c-sdk/libraries/libldap/saslbind.c')
-rw-r--r--ldap/c-sdk/libraries/libldap/saslbind.c877
1 files changed, 0 insertions, 877 deletions
diff --git a/ldap/c-sdk/libraries/libldap/saslbind.c b/ldap/c-sdk/libraries/libldap/saslbind.c
deleted file mode 100644
index 5cbe73bbf..000000000
--- a/ldap/c-sdk/libraries/libldap/saslbind.c
+++ /dev/null
@@ -1,877 +0,0 @@
-/* ***** BEGIN LICENSE BLOCK *****
- * Version: MPL 1.1/GPL 2.0/LGPL 2.1
- *
- * The contents of this file are subject to the Mozilla Public License Version
- * 1.1 (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- * http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS IS" basis,
- * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
- * for the specific language governing rights and limitations under the
- * License.
- *
- * The Original Code is Mozilla Communicator client code, released
- * March 31, 1998.
- *
- * The Initial Developer of the Original Code is
- * Netscape Communications Corporation.
- * Portions created by the Initial Developer are Copyright (C) 1998-1999
- * the Initial Developer. All Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the terms of
- * either of the GNU General Public License Version 2 or later (the "GPL"),
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- * in which case the provisions of the GPL or the LGPL are applicable instead
- * of those above. If you wish to allow use of your version of this file only
- * under the terms of either the GPL or the LGPL, and not to allow others to
- * use your version of this file under the terms of the MPL, indicate your
- * decision by deleting the provisions above and replace them with the notice
- * and other provisions required by the GPL or the LGPL. If you do not delete
- * the provisions above, a recipient may use your version of this file under
- * the terms of any one of the MPL, the GPL or the LGPL.
- *
- * ***** END LICENSE BLOCK ***** */
-#include "ldap-int.h"
-
-#ifdef LDAP_SASLIO_HOOKS
-/*
- * Global SASL Init data
- */
-
-static int
-nsldapi_sasl_fail()
-{
- return( SASL_FAIL );
-}
-
-sasl_callback_t client_callbacks[] = {
- { SASL_CB_GETOPT, nsldapi_sasl_fail, NULL },
- { SASL_CB_GETREALM, NULL, NULL },
- { SASL_CB_USER, NULL, NULL },
- { SASL_CB_CANON_USER, NULL, NULL },
- { SASL_CB_AUTHNAME, NULL, NULL },
- { SASL_CB_PASS, NULL, NULL },
- { SASL_CB_ECHOPROMPT, NULL, NULL },
- { SASL_CB_NOECHOPROMPT, NULL, NULL },
- { SASL_CB_LIST_END, NULL, NULL }
-};
-
-int
-nsldapi_sasl_cvterrno( LDAP *ld, int err, char *msg )
-{
- int rc = LDAP_LOCAL_ERROR;
-
- switch (err) {
- case SASL_OK:
- rc = LDAP_SUCCESS;
- break;
- case SASL_NOMECH:
- rc = LDAP_AUTH_UNKNOWN;
- break;
- case SASL_BADSERV:
- rc = LDAP_CONNECT_ERROR;
- break;
- case SASL_DISABLED:
- case SASL_ENCRYPT:
- case SASL_EXPIRED:
- case SASL_NOUSERPASS:
- case SASL_NOVERIFY:
- case SASL_PWLOCK:
- case SASL_TOOWEAK:
- case SASL_UNAVAIL:
- case SASL_WEAKPASS:
- rc = LDAP_INAPPROPRIATE_AUTH;
- break;
- case SASL_BADAUTH:
- case SASL_NOAUTHZ:
- rc = LDAP_INVALID_CREDENTIALS;
- break;
- case SASL_NOMEM:
- rc = LDAP_NO_MEMORY;
- break;
- case SASL_NOUSER:
- rc = LDAP_NO_SUCH_OBJECT;
- break;
- case SASL_CONTINUE:
- case SASL_FAIL:
- case SASL_INTERACT:
- default:
- rc = LDAP_LOCAL_ERROR;
- break;
- }
-
- LDAP_SET_LDERRNO( ld, rc, NULL, msg );
- return( rc );
-}
-
-#ifdef LDAP_SASLIO_GET_MECHS_FROM_SERVER
-/*
- * Get available SASL Mechanisms supported by the server
- */
-
-static int
-nsldapi_get_sasl_mechs ( LDAP *ld, char **pmech )
-{
- char *attr[] = { "supportedSASLMechanisms", NULL };
- char **values, **v, *mech, *m;
- LDAPMessage *res, *e;
- struct timeval timeout;
- int slen, rc;
-
- if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
- return( LDAP_PARAM_ERROR );
- }
-
- timeout.tv_sec = SEARCH_TIMEOUT_SECS;
- timeout.tv_usec = 0;
-
- rc = ldap_search_st( ld, "", LDAP_SCOPE_BASE,
- "objectclass=*", attr, 0, &timeout, &res );
-
- if ( rc != LDAP_SUCCESS ) {
- return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
- }
-
- e = ldap_first_entry( ld, res );
- if ( e == NULL ) {
- ldap_msgfree( res );
- if ( ld->ld_errno == LDAP_SUCCESS ) {
- LDAP_SET_LDERRNO( ld, LDAP_NO_SUCH_OBJECT, NULL, NULL );
- }
- return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
- }
-
- values = ldap_get_values( ld, e, "supportedSASLMechanisms" );
- if ( values == NULL ) {
- ldap_msgfree( res );
- LDAP_SET_LDERRNO( ld, LDAP_NO_SUCH_ATTRIBUTE, NULL, NULL );
- return( LDAP_NO_SUCH_ATTRIBUTE );
- }
-
- slen = 0;
- for(v = values; *v != NULL; v++ ) {
- slen += strlen(*v) + 1;
- }
- if ( (mech = NSLDAPI_CALLOC(1, slen)) == NULL) {
- ldap_value_free( values );
- ldap_msgfree( res );
- LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
- return( LDAP_NO_MEMORY );
- }
- m = mech;
- for(v = values; *v; v++) {
- if (v != values) {
- *m++ = ' ';
- }
- slen = strlen(*v);
- strncpy(m, *v, slen);
- m += slen;
- }
- *m = '\0';
-
- ldap_value_free( values );
- ldap_msgfree( res );
-
- *pmech = mech;
-
- return( LDAP_SUCCESS );
-}
-#endif /* LDAP_SASLIO_GET_MECHS_FROM_SERVER */
-
-int
-nsldapi_sasl_secprops(
- const char *in,
- sasl_security_properties_t *secprops )
-{
- int i;
- char **props = NULL;
- char *inp;
- unsigned sflags = 0;
- sasl_ssf_t max_ssf = 0;
- sasl_ssf_t min_ssf = 0;
- unsigned maxbufsize = 0;
- int got_sflags = 0;
- int got_max_ssf = 0;
- int got_min_ssf = 0;
- int got_maxbufsize = 0;
-
- if (in == NULL) {
- return LDAP_PARAM_ERROR;
- }
- inp = nsldapi_strdup(in);
- if (inp == NULL) {
- return LDAP_PARAM_ERROR;
- }
- props = ldap_str2charray( inp, "," );
- NSLDAPI_FREE( inp );
-
- if( props == NULL || secprops == NULL ) {
- return LDAP_PARAM_ERROR;
- }
-
- for( i=0; props[i]; i++ ) {
- if( strcasecmp(props[i], "none") == 0 ) {
- got_sflags++;
-
- } else if( strcasecmp(props[i], "noactive") == 0 ) {
- got_sflags++;
- sflags |= SASL_SEC_NOACTIVE;
-
- } else if( strcasecmp(props[i], "noanonymous") == 0 ) {
- got_sflags++;
- sflags |= SASL_SEC_NOANONYMOUS;
-
- } else if( strcasecmp(props[i], "nodict") == 0 ) {
- got_sflags++;
- sflags |= SASL_SEC_NODICTIONARY;
-
- } else if( strcasecmp(props[i], "noplain") == 0 ) {
- got_sflags++;
- sflags |= SASL_SEC_NOPLAINTEXT;
-
- } else if( strcasecmp(props[i], "forwardsec") == 0 ) {
- got_sflags++;
- sflags |= SASL_SEC_FORWARD_SECRECY;
-
- } else if( strcasecmp(props[i], "passcred") == 0 ) {
- got_sflags++;
- sflags |= SASL_SEC_PASS_CREDENTIALS;
-
- } else if( strncasecmp(props[i],
- "minssf=", sizeof("minssf")) == 0 ) {
- if( isdigit( props[i][sizeof("minssf")] ) ) {
- got_min_ssf++;
- min_ssf = atoi( &props[i][sizeof("minssf")] );
- } else {
- return LDAP_NOT_SUPPORTED;
- }
-
- } else if( strncasecmp(props[i],
- "maxssf=", sizeof("maxssf")) == 0 ) {
- if( isdigit( props[i][sizeof("maxssf")] ) ) {
- got_max_ssf++;
- max_ssf = atoi( &props[i][sizeof("maxssf")] );
- } else {
- return LDAP_NOT_SUPPORTED;
- }
-
- } else if( strncasecmp(props[i],
- "maxbufsize=", sizeof("maxbufsize")) == 0 ) {
- if( isdigit( props[i][sizeof("maxbufsize")] ) ) {
- got_maxbufsize++;
- maxbufsize = atoi( &props[i][sizeof("maxbufsize")] );
- if( maxbufsize &&
- (( maxbufsize < SASL_MIN_BUFF_SIZE )
- || (maxbufsize > SASL_MAX_BUFF_SIZE ))) {
- return( LDAP_PARAM_ERROR );
- }
- } else {
- return( LDAP_NOT_SUPPORTED );
- }
- } else {
- return( LDAP_NOT_SUPPORTED );
- }
- }
-
- if(got_sflags) {
- secprops->security_flags = sflags;
- }
- if(got_min_ssf) {
- secprops->min_ssf = min_ssf;
- }
- if(got_max_ssf) {
- secprops->max_ssf = max_ssf;
- }
- if(got_maxbufsize) {
- secprops->maxbufsize = maxbufsize;
- }
-
- ldap_charray_free( props );
- return( LDAP_SUCCESS );
-}
-#endif /* LDAP_SASLIO_HOOKS */
-
-static int
-nsldapi_sasl_bind_s(
- LDAP *ld,
- const char *dn,
- const char *mechanism,
- const struct berval *cred,
- LDAPControl **serverctrls,
- LDAPControl **clientctrls,
- struct berval **servercredp,
- LDAPControl ***responsectrls
-)
-{
- int err, msgid;
- LDAPMessage *result;
-
- LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_sasl_bind_s\n", 0, 0, 0 );
-
- if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
- return( LDAP_PARAM_ERROR );
- }
-
- if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) {
- LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
- return( LDAP_NOT_SUPPORTED );
- }
-
- if ( ( err = ldap_sasl_bind( ld, dn, mechanism, cred, serverctrls,
- clientctrls, &msgid )) != LDAP_SUCCESS )
- return( err );
-
- if ( ldap_result( ld, msgid, 1, (struct timeval *) 0, &result ) == -1 )
- return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
-
- /* Get the controls sent by the server if requested */
- if ( responsectrls ) {
- if ( ( err = ldap_parse_result( ld, result, &err, NULL, NULL,
- NULL, responsectrls, 0 )) != LDAP_SUCCESS )
- return( err );
- }
-
- err = ldap_parse_sasl_bind_result( ld, result, servercredp, 0 );
- if (err != LDAP_SUCCESS && err != LDAP_SASL_BIND_IN_PROGRESS) {
- ldap_msgfree( result );
- return( err );
- }
-
- return( ldap_result2error( ld, result, 1 ) );
-}
-
-#ifdef LDAP_SASLIO_HOOKS
-static int
-nsldapi_sasl_do_bind( LDAP *ld, const char *dn,
- const char *mechs, unsigned flags,
- LDAP_SASL_INTERACT_PROC *callback, void *defaults,
- LDAPControl **sctrl, LDAPControl **cctrl, LDAPControl ***rctrl )
-{
- sasl_interact_t *prompts = NULL;
- sasl_conn_t *ctx = NULL;
- sasl_ssf_t *ssf = NULL;
- const char *mech = NULL;
- int saslrc, rc;
- struct berval ccred;
- unsigned credlen;
- int stepnum = 1;
- char *sasl_username = NULL;
-
- if (rctrl) {
- /* init to NULL so we can call ldap_controls_free below */
- *rctrl = NULL;
- }
-
- if (NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3) {
- LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
- return( LDAP_NOT_SUPPORTED );
- }
-
- /* shouldn't happen */
- if (callback == NULL) {
- return( LDAP_LOCAL_ERROR );
- }
-
- if ( (rc = nsldapi_sasl_open(ld, NULL, &ctx, 0)) != LDAP_SUCCESS ) {
- return( rc );
- }
-
- ccred.bv_val = NULL;
- ccred.bv_len = 0;
-
- LDAPDebug(LDAP_DEBUG_TRACE, "Starting SASL/%s authentication\n",
- (mechs ? mechs : ""), 0, 0 );
-
- do {
- saslrc = sasl_client_start( ctx,
- mechs,
- &prompts,
- (const char **)&ccred.bv_val,
- &credlen,
- &mech );
-
- LDAPDebug(LDAP_DEBUG_TRACE, "Doing step %d of client start for SASL/%s authentication\n",
- stepnum, (mech ? mech : ""), 0 );
- stepnum++;
-
- if( saslrc == SASL_INTERACT &&
- (callback)(ld, flags, defaults, prompts) != LDAP_SUCCESS ) {
- break;
- }
- } while ( saslrc == SASL_INTERACT );
-
- ccred.bv_len = credlen;
-
- if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
- return( nsldapi_sasl_cvterrno( ld, saslrc, nsldapi_strdup( sasl_errdetail( ctx ) ) ) );
- }
-
- stepnum = 1;
-
- do {
- struct berval *scred;
- int clientstepnum = 1;
-
- scred = NULL;
-
- if (rctrl) {
- /* if we're looping again, we need to free any controls set
- during the previous loop */
- /* NOTE that this assumes we only care about the controls
- returned by the last call to nsldapi_sasl_bind_s - if
- we care about _all_ controls, we will have to figure out
- some way to append them each loop go round */
- ldap_controls_free(*rctrl);
- *rctrl = NULL;
- }
-
- LDAPDebug(LDAP_DEBUG_TRACE, "Doing step %d of bind for SASL/%s authentication\n",
- stepnum, (mech ? mech : ""), 0 );
- stepnum++;
-
- /* notify server of a sasl bind step */
- rc = nsldapi_sasl_bind_s(ld, dn, mech, &ccred,
- sctrl, cctrl, &scred, rctrl);
-
- if ( ccred.bv_val != NULL ) {
- ccred.bv_val = NULL;
- }
-
- if ( rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS ) {
- ber_bvfree( scred );
- return( rc );
- }
-
- if( rc == LDAP_SUCCESS && saslrc == SASL_OK ) {
- /* we're done, no need to step */
- if( scred ) {
- if ( scred->bv_len == 0 ) { /* MS AD sends back empty screds */
- LDAPDebug(LDAP_DEBUG_ANY,
- "SASL BIND complete - ignoring empty credential response\n",
- 0, 0, 0);
- ber_bvfree( scred );
- } else {
- /* but server provided us with data! */
- LDAPDebug(LDAP_DEBUG_TRACE,
- "SASL BIND complete but invalid because server responded with credentials - length [%u]\n",
- scred->bv_len, 0, 0);
- ber_bvfree( scred );
- LDAP_SET_LDERRNO( ld, LDAP_LOCAL_ERROR,
- NULL, "Error during SASL handshake - invalid server credential response" );
- return( LDAP_LOCAL_ERROR );
- }
- }
- break;
- }
-
- /* perform the next step of the sasl bind */
- do {
- LDAPDebug(LDAP_DEBUG_TRACE, "Doing client step %d of bind step %d for SASL/%s authentication\n",
- clientstepnum, stepnum, (mech ? mech : "") );
- clientstepnum++;
- saslrc = sasl_client_step( ctx,
- (scred == NULL) ? NULL : scred->bv_val,
- (scred == NULL) ? 0 : scred->bv_len,
- &prompts,
- (const char **)&ccred.bv_val,
- &credlen );
-
- if( saslrc == SASL_INTERACT &&
- (callback)(ld, flags, defaults, prompts)
- != LDAP_SUCCESS ) {
- break;
- }
- } while ( saslrc == SASL_INTERACT );
-
- ccred.bv_len = credlen;
- ber_bvfree( scred );
-
- if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
- return( nsldapi_sasl_cvterrno( ld, saslrc, nsldapi_strdup( sasl_errdetail( ctx ) ) ) );
- }
- } while ( rc == LDAP_SASL_BIND_IN_PROGRESS );
-
- if ( rc != LDAP_SUCCESS ) {
- return( rc );
- }
-
- if ( saslrc != SASL_OK ) {
- return( nsldapi_sasl_cvterrno( ld, saslrc, nsldapi_strdup( sasl_errdetail( ctx ) ) ) );
- }
-
- saslrc = sasl_getprop( ctx, SASL_USERNAME, (const void **) &sasl_username );
- if ( (saslrc == SASL_OK) && sasl_username ) {
- LDAPDebug(LDAP_DEBUG_TRACE, "SASL identity: %s\n", sasl_username, 0, 0);
- }
-
- saslrc = sasl_getprop( ctx, SASL_SSF, (const void **) &ssf );
- if( saslrc == SASL_OK ) {
- if( ssf && *ssf ) {
- LDAPDebug(LDAP_DEBUG_TRACE,
- "SASL install encryption, for SSF: %lu\n",
- (unsigned long) *ssf, 0, 0 );
- nsldapi_sasl_install( ld, NULL );
- }
- }
-
- return( rc );
-}
-#endif /* LDAP_SASLIO_HOOKS */
-
-
-/*
- * ldap_sasl_bind - authenticate to the ldap server. The dn, mechanism,
- * and credentials of the entry to which to bind are supplied. An LDAP
- * error code is returned and if LDAP_SUCCESS is returned *msgidp is set
- * to the id of the request initiated.
- *
- * Example:
- * struct berval creds;
- * LDAPControl **ctrls;
- * int err, msgid;
- * ... fill in creds with credentials ...
- * ... fill in ctrls with server controls ...
- * err = ldap_sasl_bind( ld, "cn=manager, o=university of michigan, c=us",
- * "mechanismname", &creds, ctrls, NULL, &msgid );
- */
-int
-LDAP_CALL
-ldap_sasl_bind(
- LDAP *ld,
- const char *dn,
- const char *mechanism,
- const struct berval *cred,
- LDAPControl **serverctrls,
- LDAPControl **clientctrls,
- int *msgidp
-)
-{
- BerElement *ber;
- int rc, simple, msgid, ldapversion;
-
- /*
- * The ldapv3 bind request looks like this:
- * BindRequest ::= SEQUENCE {
- * version INTEGER,
- * name DistinguishedName, -- who
- * authentication CHOICE {
- * simple [0] OCTET STRING, -- passwd
- * sasl [3] SaslCredentials -- v3 only
- * }
- * }
- * SaslCredentials ::= SEQUENCE {
- * mechanism LDAPString,
- * credentials OCTET STRING
- * }
- * all wrapped up in an LDAPMessage sequence.
- */
-
- LDAPDebug( LDAP_DEBUG_TRACE, "ldap_sasl_bind\n", 0, 0, 0 );
-
- if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
- return( LDAP_PARAM_ERROR );
- }
-
- if ( msgidp == NULL ) {
- LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
- return( LDAP_PARAM_ERROR );
- }
-
- if ( ( ld->ld_options & LDAP_BITOPT_RECONNECT ) != 0 ) {
- nsldapi_handle_reconnect( ld );
- }
-
- simple = ( mechanism == LDAP_SASL_SIMPLE );
- ldapversion = NSLDAPI_LDAP_VERSION( ld );
-
- /* only ldapv3 or higher can do sasl binds */
- if ( !simple && ldapversion < LDAP_VERSION3 ) {
- LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
- return( LDAP_NOT_SUPPORTED );
- }
-
- LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
- msgid = ++ld->ld_msgid;
- LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
-
- if ( dn == NULL )
- dn = "";
-
- if ( ld->ld_cache_on && ld->ld_cache_bind != NULL ) {
- LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
- if ( (rc = (ld->ld_cache_bind)( ld, msgid, LDAP_REQ_BIND, dn,
- cred, LDAP_AUTH_SASL )) != 0 ) {
- *msgidp = rc;
- LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
- return( LDAP_SUCCESS );
- }
- LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
- }
-
- /* create a message to send */
- if (( rc = nsldapi_alloc_ber_with_options( ld, &ber ))
- != LDAP_SUCCESS ) {
- return( rc );
- }
-
- /* fill it in */
- if ( simple ) { /* simple bind; works in LDAPv2 or v3 */
- struct berval tmpcred;
-
- if ( cred == NULL ) {
- tmpcred.bv_val = "";
- tmpcred.bv_len = 0;
- cred = &tmpcred;
- }
- rc = ber_printf( ber, "{it{isto}", msgid, LDAP_REQ_BIND,
- ldapversion, dn, LDAP_AUTH_SIMPLE, cred->bv_val,
- cred->bv_len );
-
- } else { /* SASL bind; requires LDAPv3 or better */
- if ( cred == NULL || cred->bv_val == NULL || cred->bv_len == 0) {
- rc = ber_printf( ber, "{it{ist{s}}", msgid,
- LDAP_REQ_BIND, ldapversion, dn, LDAP_AUTH_SASL,
- mechanism );
- } else {
- rc = ber_printf( ber, "{it{ist{so}}", msgid,
- LDAP_REQ_BIND, ldapversion, dn, LDAP_AUTH_SASL,
- mechanism, cred->bv_val,
- cred->bv_len );
- }
- }
-
- if ( rc == -1 ) {
- LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
- ber_free( ber, 1 );
- return( LDAP_ENCODING_ERROR );
- }
-
- if ( (rc = nsldapi_put_controls( ld, serverctrls, 1, ber ))
- != LDAP_SUCCESS ) {
- ber_free( ber, 1 );
- return( rc );
- }
-
- /* send the message */
- rc = nsldapi_send_initial_request( ld, msgid, LDAP_REQ_BIND,
- (char *)dn, ber );
- *msgidp = rc;
- return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS );
-}
-
-/*
- * ldap_sasl_bind_s - bind to the ldap server using sasl authentication
- * The dn, mechanism, and credentials of the entry to which to bind are
- * supplied. LDAP_SUCCESS is returned upon success, the ldap error code
- * otherwise.
- *
- * Example:
- * struct berval creds;
- * ... fill in creds with credentials ...
- * ldap_sasl_bind_s( ld, "cn=manager, o=university of michigan, c=us",
- * "mechanismname", &creds )
- */
-int
-LDAP_CALL
-ldap_sasl_bind_s(
- LDAP *ld,
- const char *dn,
- const char *mechanism,
- const struct berval *cred,
- LDAPControl **serverctrls,
- LDAPControl **clientctrls,
- struct berval **servercredp
-)
-{
- return ( nsldapi_sasl_bind_s( ld, dn, mechanism, cred,
- serverctrls, clientctrls, servercredp, NULL ) );
-}
-
-#ifdef LDAP_SASLIO_HOOKS
-/*
- * SASL Authentication Interface: ldap_sasl_interactive_bind_s
- *
- * This routine takes a DN, SASL mech list, and a SASL callback
- * and performs the necessary sequencing to complete a SASL bind
- * to the LDAP connection ld. The user provided callback can
- * use an optionally provided set of default values to complete
- * any necessary interactions.
- *
- * Currently imposes the following restrictions:
- * A mech list must be provided
- * LDAP_SASL_INTERACTIVE mode requires a callback
- */
-int
-LDAP_CALL
-ldap_sasl_interactive_bind_s( LDAP *ld, const char *dn,
- const char *saslMechanism,
- LDAPControl **sctrl, LDAPControl **cctrl, unsigned flags,
- LDAP_SASL_INTERACT_PROC *callback, void *defaults )
-{
- return ldap_sasl_interactive_bind_ext_s( ld, dn,
- saslMechanism, sctrl, cctrl, flags, callback,
- defaults, NULL );
-}
-
-/*
- * ldap_sasl_interactive_bind_ext_s
- *
- * This function extends ldap_sasl_interactive_bind_s by allowing
- * controls received from the server to be returned as rctrl. The
- * caller must pass in a valid LDAPControl** pointer and free the
- * array of controls when finished with them e.g.
- * LDAPControl **retctrls = NULL;
- * ...
- * ldap_sasl_interactive_bind_ext_s(ld, ...., &retctrls);
- * ...
- * ldap_controls_free(retctrls);
- * Only the controls from the server during the last bind step are returned -
- * intermediate controls (if any, usually not) are discarded.
- */
-int
-LDAP_CALL
-ldap_sasl_interactive_bind_ext_s( LDAP *ld, const char *dn,
- const char *saslMechanism,
- LDAPControl **sctrl, LDAPControl **cctrl, unsigned flags,
- LDAP_SASL_INTERACT_PROC *callback, void *defaults, LDAPControl ***rctrl )
-{
-#ifdef LDAP_SASLIO_GET_MECHS_FROM_SERVER
- char *smechs;
-#endif
- int rc;
-
- LDAPDebug( LDAP_DEBUG_TRACE, "ldap_sasl_interactive_bind_s\n", 0, 0, 0 );
-
- if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
- return( LDAP_PARAM_ERROR );
- }
-
- if ((flags == LDAP_SASL_INTERACTIVE) && (callback == NULL)) {
- return( LDAP_PARAM_ERROR );
- }
-
- LDAP_MUTEX_LOCK(ld, LDAP_SASL_LOCK );
-
- if( saslMechanism == NULL || *saslMechanism == '\0' ) {
-#ifdef LDAP_SASLIO_GET_MECHS_FROM_SERVER
- rc = nsldapi_get_sasl_mechs( ld, &smechs );
- if( rc != LDAP_SUCCESS ) {
- LDAP_MUTEX_UNLOCK(ld, LDAP_SASL_LOCK );
- return( rc );
- }
- saslMechanism = smechs;
-#else
- LDAP_MUTEX_UNLOCK(ld, LDAP_SASL_LOCK );
- return( LDAP_PARAM_ERROR );
-#endif /* LDAP_SASLIO_GET_MECHS_FROM_SERVER */
- }
-
- rc = nsldapi_sasl_do_bind( ld, dn, saslMechanism,
- flags, callback, defaults, sctrl, cctrl, rctrl);
-
- LDAP_MUTEX_UNLOCK(ld, LDAP_SASL_LOCK );
- return( rc );
-}
-#else /* LDAP_SASLIO_HOOKS */
-/* stubs for platforms that do not support SASL */
-int
-LDAP_CALL
-ldap_sasl_interactive_bind_s( LDAP *ld, const char *dn,
- const char *saslMechanism,
- LDAPControl **sctrl, LDAPControl **cctrl, unsigned flags,
- LDAP_SASL_INTERACT_PROC *callback, void *defaults )
-{
- return LDAP_SUCCESS;
-}
-
-int
-LDAP_CALL
-ldap_sasl_interactive_bind_ext_s( LDAP *ld, const char *dn,
- const char *saslMechanism,
- LDAPControl **sctrl, LDAPControl **cctrl, unsigned flags,
- LDAP_SASL_INTERACT_PROC *callback, void *defaults, LDAPControl ***rctrl )
-{
- return LDAP_SUCCESS;
-}
-#endif /* LDAP_SASLIO_HOOKS */
-
-
-/* returns an LDAP error code that indicates if parse succeeded or not */
-int
-LDAP_CALL
-ldap_parse_sasl_bind_result(
- LDAP *ld,
- LDAPMessage *res,
- struct berval **servercredp,
- int freeit
-)
-{
- BerElement ber;
- int rc, err;
- ber_int_t along;
- ber_len_t len;
- char *m, *e;
-
- LDAPDebug( LDAP_DEBUG_TRACE, "ldap_parse_sasl_bind_result\n", 0, 0, 0 );
-
- /*
- * the ldapv3 SASL bind response looks like this:
- *
- * BindResponse ::= [APPLICATION 1] SEQUENCE {
- * COMPONENTS OF LDAPResult,
- * serverSaslCreds [7] OCTET STRING OPTIONAL
- * }
- *
- * all wrapped up in an LDAPMessage sequence.
- */
-
- if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) ||
- !NSLDAPI_VALID_LDAPMESSAGE_BINDRESULT_POINTER( res )) {
- return( LDAP_PARAM_ERROR );
- }
-
- /* only ldapv3 or higher can do sasl binds */
- if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) {
- LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
- return( LDAP_NOT_SUPPORTED );
- }
-
- if ( servercredp != NULL ) {
- *servercredp = NULL;
- }
-
- ber = *(res->lm_ber); /* struct copy */
-
- /* skip past message id, matched dn, error message ... */
- rc = ber_scanf( &ber, "{iaa}", &along, &m, &e );
-
- if ( rc != LBER_ERROR &&
- ber_peek_tag( &ber, &len ) == LDAP_TAG_SASL_RES_CREDS ) {
- rc = ber_get_stringal( &ber, servercredp );
- }
-
- if ( freeit ) {
- ldap_msgfree( res );
- }
-
- if ( rc == LBER_ERROR ) {
- err = LDAP_DECODING_ERROR;
- } else {
- err = (int) along;
- }
-
- LDAP_SET_LDERRNO( ld, err, m, e );
- /* this is a little kludge for the 3.0 Barracuda/hammerhead relese */
- /* the docs state that the return is either LDAP_DECODING_ERROR */
- /* or LDAP_SUCCESS. Here we match the docs... it's cleaner in 3.1 */
-
- if ( LDAP_DECODING_ERROR == err ) {
- return (LDAP_DECODING_ERROR);
- } else {
- return( LDAP_SUCCESS );
- }
-}
-