openldap/contrib/slapd-modules/vc/vc.c
2010-12-30 15:49:34 +00:00

157 lines
3.6 KiB
C

/* vc.c - LDAP Verify Credentials extop (no spec yet) */
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
*
* Copyright 2010 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
* Public License.
*
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
/* ACKNOWLEDGEMENTS:
* This work was initially developed by Pierangelo Masarati for inclusion
* in OpenLDAP Software.
*/
/*
* LDAP Verify Credentials: suggested by Kurt Zeilenga
* no spec yet
*/
#include "portable.h"
#include "slap.h"
#include "ac/string.h"
static const struct berval vc_exop_oid_bv = BER_BVC(LDAP_EXOP_VERIFY_CREDENTIALS);
static int
vc_exop(
Operation *op,
SlapReply *rs )
{
int rc = LDAP_SUCCESS;
ber_tag_t tag;
ber_len_t len = -1;
BerElementBuffer berbuf;
BerElement *ber = (BerElement *)&berbuf;
struct berval reqdata = BER_BVNULL;
if ( op->ore_reqdata == NULL || op->ore_reqdata->bv_len == 0 ) {
rs->sr_text = "empty request data field in VerifyCredentials exop";
return LDAP_PROTOCOL_ERROR;
}
ber_dupbv_x( &reqdata, op->ore_reqdata, op->o_tmpmemctx );
/* ber_init2 uses reqdata directly, doesn't allocate new buffers */
ber_init2( ber, &reqdata, 0 );
tag = ber_scanf( ber, "{" /*}*/ );
if ( tag != LBER_SEQUENCE ) {
rs->sr_err = LDAP_PROTOCOL_ERROR;
goto done;
}
tag = ber_peek_tag( ber, &len );
if ( tag == LBER_INTEGER ) {
ber_int_t version;
struct berval bdn;
ber_tag_t authtag;
struct berval cred;
struct berval ndn;
Attribute a = { 0 };
/* simple */
/* version */
tag = ber_scanf( ber, "i", &version );
if ( tag == LBER_ERROR || version != 3 ) {
rs->sr_err = LDAP_PROTOCOL_ERROR;
goto done;
}
/* DN, authtag, cred */
tag = ber_scanf( ber, "mtm", &bdn, &authtag, &cred );
if ( tag == LBER_ERROR || authtag != LDAP_AUTH_SIMPLE ) {
rs->sr_err = LDAP_PROTOCOL_ERROR;
goto done;
}
rc = dnNormalize( 0, NULL, NULL, &bdn, &ndn, op->o_tmpmemctx );
if ( rc != LDAP_SUCCESS ) {
rs->sr_err = LDAP_PROTOCOL_ERROR;
goto done;
}
a.a_desc = slap_schema.si_ad_userPassword;
rc = backend_attribute( op, NULL, &ndn, a.a_desc, &a.a_vals, ACL_AUTH );
if ( rc != LDAP_SUCCESS || a.a_vals == NULL ) {
rs->sr_err = LDAP_INVALID_CREDENTIALS;
} else {
a.a_nvals = a.a_vals;
for ( a.a_numvals = 0; !BER_BVISNULL( &a.a_nvals[a.a_numvals] ); a.a_numvals++ )
;
rc = slap_passwd_check( op, NULL, &a, &cred, &rs->sr_text );
if ( rc != 0 ) {
rs->sr_err = LDAP_INVALID_CREDENTIALS;
} else {
rs->sr_err = LDAP_SUCCESS;
rs->sr_rspoid = NULL;
rs->sr_rspdata = NULL;
}
}
op->o_tmpfree( ndn.bv_val, op->o_tmpmemctx );
op->o_tmpfree( a.a_vals, op->o_tmpmemctx );
} else {
/* SASL */
if ( tag == LDAP_TAG_EXOP_VERIFY_CREDENTIALS_COOKIE ) {
} else {
}
}
tag = ber_skip_tag( ber, &len );
if ( len || tag != LBER_DEFAULT ) {
rs->sr_err = LDAP_PROTOCOL_ERROR;
goto done;
}
done:;
op->o_tmpfree( reqdata.bv_val, op->o_tmpmemctx );
return rs->sr_err;
}
static int
vc_initialize( void )
{
int rc;
rc = load_extop2( (struct berval *)&vc_exop_oid_bv,
SLAP_EXOP_HIDE, vc_exop, 0 );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY,
"vc_initialize: unable to register VerifyCredentials exop: %d.\n",
rc, 0, 0 );
}
return rc;
}
int
init_module( int argc, char *argv[] )
{
return vc_initialize();
}