Skip to content
Snippets Groups Projects
Commit 80e5e3fe authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

First cut at SASL routines.

parent 613bf0b0
Branches
Tags
No related merge requests found
......@@ -291,6 +291,10 @@ SOURCE=.\print.c
# End Source File
# Begin Source File
SOURCE=.\references.c
# End Source File
# Begin Source File
SOURCE=.\request.c
# End Source File
# Begin Source File
......@@ -299,6 +303,10 @@ SOURCE=.\result.c
# End Source File
# Begin Source File
SOURCE=.\sasl.c
# End Source File
# Begin Source File
SOURCE=.\sbind.c
# End Source File
# Begin Source File
......
/*
* Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
/*
* BindRequest ::= SEQUENCE {
* version INTEGER,
* name DistinguishedName, -- who
* authentication CHOICE {
* simple [0] OCTET STRING -- passwd
#ifdef HAVE_KERBEROS
* krbv42ldap [1] OCTET STRING
* krbv42dsa [2] OCTET STRING
#endif
* sasl [3] SaslCredentials -- LDAPv3
* }
* }
*
* BindResponse ::= SEQUENCE {
* COMPONENTS OF LDAPResult,
* serverSaslCreds OCTET STRING OPTIONAL -- LDAPv3
* }
*
*/
#include "portable.h"
#include <stdio.h>
#include <ac/socket.h>
#include <ac/string.h>
#include <ac/time.h>
#include "ldap-int.h"
/*
* ldap_sasl_bind - bind to the ldap server (and X.500). The dn, mechanism, and
* credentials of the entry to which to bind are supplied. The message id
* of the request initiated is provided upon successful (LDAP_SUCCESS) return.
*
* Example:
* ldap_sasl_bind( ld, "cn=manager, o=university of michigan, c=us",
* "mechanism", "secret", NULL, NULL, &msgid )
*/
int
ldap_sasl_bind(
LDAP *ld,
LDAP_CONST char *dn,
LDAP_CONST char *mechanism,
struct berval *cred,
LDAPControl **sctrls,
LDAPControl **cctrls,
int *msgidp )
{
BerElement *ber;
int rc;
Debug( LDAP_DEBUG_TRACE, "ldap_sasl_bind\n", 0, 0, 0 );
assert( ld != NULL );
assert( LDAP_VALID( ld ) );
assert( msgidp != NULL );
if( msgidp == NULL ) {
ld->ld_errno = LDAP_PARAM_ERROR;
return ld->ld_errno;
}
if( mechanism != LDAP_SASL_SIMPLE
&& ld->ld_version < LDAP_VERSION3)
{
ld->ld_errno = LDAP_NOT_SUPPORTED;
return ld->ld_errno;
}
if ( dn == NULL )
dn = "";
/* create a message to send */
if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
ld->ld_errno = LDAP_NO_MEMORY;
return ld->ld_errno;
}
assert( BER_VALID( ber ) );
if( mechanism == LDAP_SASL_SIMPLE ) {
/* simple bind */
rc = ber_printf( ber, "{it{istO}" /*}*/,
++ld->ld_msgid, LDAP_REQ_BIND,
ld->ld_version, dn, LDAP_AUTH_SIMPLE,
cred );
} else if ( cred == NULL ) {
/* SASL bind w/o creditials */
rc = ber_printf( ber, "{it{ist{s}}" /*}*/,
++ld->ld_msgid, LDAP_REQ_BIND,
ld->ld_version, dn, LDAP_AUTH_SASL,
mechanism );
} else {
/* SASL bind w/ creditials */
rc = ber_printf( ber, "{it{ist{sO}}" /*}*/,
++ld->ld_msgid, LDAP_REQ_BIND,
ld->ld_version, dn, LDAP_AUTH_SASL,
mechanism, cred );
}
if( rc == -1 ) {
ld->ld_errno = LDAP_ENCODING_ERROR;
ber_free( ber, 1 );
return( -1 );
}
/* Put Server Controls */
if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
ber_free( ber, 1 );
return ld->ld_errno;
}
if ( ber_printf( ber, /*{*/ "}" ) == -1 ) {
ld->ld_errno = LDAP_ENCODING_ERROR;
ber_free( ber, 1 );
return ld->ld_errno;
}
#ifndef LDAP_NOCACHE
if ( ld->ld_cache != NULL ) {
ldap_flush_cache( ld );
}
#endif /* !LDAP_NOCACHE */
/* send the message */
*msgidp = ldap_send_initial_request( ld, LDAP_REQ_BIND, dn, ber );
if(*msgidp < 0)
return ld->ld_errno;
return LDAP_SUCCESS;
}
/*
* ldap_sasl_bind_s - bind to the ldap server (and X.500) using simple
* authentication. The dn and password of the entry to which to bind are
* supplied. LDAP_SUCCESS is returned upon success, the ldap error code
* otherwise.
*
* Example:
* ldap_sasl_bind_s( ld, "cn=manager, o=university of michigan, c=us",
* "mechanism", "secret", NULL, NULL, &servercred )
*/
int
ldap_sasl_bind_s(
LDAP *ld,
LDAP_CONST char *dn,
LDAP_CONST char *mechanism,
struct berval *cred,
LDAPControl **sctrls,
LDAPControl **cctrls,
struct berval **servercredp )
{
int rc, msgid;
LDAPMessage *result;
struct berval *scredp = NULL;
Debug( LDAP_DEBUG_TRACE, "ldap_sasl_bind_s\n", 0, 0, 0 );
/* do a quick !LDAPv3 check... ldap_sasl_bind will do the rest. */
if( servercredp != NULL ) {
if (ld->ld_version < LDAP_VERSION3) {
ld->ld_errno = LDAP_NOT_SUPPORTED;
return ld->ld_errno;
}
*servercredp = NULL;
}
rc = ldap_sasl_bind( ld, dn, mechanism, cred, sctrls, cctrls, &msgid );
if ( rc != LDAP_SUCCESS ) {
return( rc );
}
if ( ldap_result( ld, msgid, 1, NULL, &result ) == -1 ) {
return( ld->ld_errno ); /* ldap_result sets ld_errno */
}
/* parse the results */
scredp = NULL;
if( servercredp != NULL ) {
rc = ldap_parse_sasl_bind_result( ld, result, &scredp, 0 );
}
if( rc != LDAP_SUCCESS ) {
ldap_msgfree( result );
return( rc );
}
rc = ldap_result2error( ld, result, 1 );
if( rc == LDAP_SUCCESS ) {
if( servercredp != NULL ) {
*servercredp = scredp;
}
} else if (scredp != NULL ) {
ber_bvfree(scredp);
}
return rc;
}
/*
* Parse BindResponse:
*
* BindResponse ::= [APPLICATION 1] SEQUENCE {
* COMPONENTS OF LDAPResult,
* serverSaslCreds [7] OCTET STRING OPTIONAL }
*
* LDAPResult ::= SEQUENCE {
* resultCode ENUMERATED,
* matchedDN LDAPDN,
* errorMessage LDAPString,
* referral [3] Referral OPTIONAL }
*/
int
ldap_parse_sasl_bind_result(
LDAP *ld,
LDAPMessage *res,
struct berval **servercredp,
int freeit )
{
ber_int_t errcode;
struct berval* scred;
ber_tag_t tag;
BerElement *ber;
Debug( LDAP_DEBUG_TRACE, "ldap_parse_sasl_bind_result\n", 0, 0, 0 );
assert( ld != NULL );
assert( LDAP_VALID( ld ) );
assert( res != NULL );
if ( ld == NULL || res == NULL ) {
return LDAP_PARAM_ERROR;
}
if(servercredp != NULL) {
if( ld->ld_version < LDAP_VERSION2 ) {
return LDAP_NOT_SUPPORTED;
}
*servercredp = NULL;
}
if( res->lm_msgtype == LDAP_RES_BIND ) {
ld->ld_errno = LDAP_PARAM_ERROR;
return ld->ld_errno;
}
errcode = LDAP_SUCCESS;
scred = NULL;
if ( ld->ld_error ) {
LDAP_FREE( ld->ld_error );
ld->ld_error = NULL;
}
if ( ld->ld_matched ) {
LDAP_FREE( ld->ld_matched );
ld->ld_matched = NULL;
}
/* parse results */
ber = ber_dup( res->lm_ber );
if ( ld->ld_version < LDAP_VERSION2 ) {
tag = ber_scanf( ber, "{ia}",
&errcode, &ld->ld_error );
} else {
ber_len_t len;
tag = ber_scanf( ber, "{iaa" /*}*/,
&errcode, &ld->ld_matched, &ld->ld_error );
if( tag != LBER_ERROR ) {
tag = ber_peek_tag(ber, &len);
}
if( tag == LDAP_TAG_REFERRAL ) {
/* skip 'em */
tag = ber_scanf( ber, "x" );
if( tag != LBER_ERROR ) {
tag = ber_peek_tag(ber, &len);
}
}
/* need to clean out misc items */
if( tag == LDAP_TAG_SASL_RES_CREDS ) {
tag = ber_scanf( ber, "O", &scred );
}
}
if ( tag == LBER_ERROR ) {
errcode = LDAP_DECODING_ERROR;
}
if( ber != NULL ) {
ber_free( ber, 0 );
}
/* return */
if ( errcode == LDAP_SUCCESS && servercredp != NULL ) {
*servercredp = scred;
} else if ( scred != NULL ) {
ber_bvfree( scred );
}
if ( freeit ) {
ldap_msgfree( res );
}
ld->ld_errno = errcode;
return( ld->ld_errno );
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment