static struct berval ext_bv = { sizeof("EXTERNAL")-1, "EXTERNAL" };
-int slap_sasl_getdn( Connection *conn, char *id,
+int slap_sasl_getdn( Connection *conn, char *id, int len,
char *user_realm, struct berval *dn, int flags )
{
char *c1;
- int rc, len, is_dn = 0;
+ int rc, is_dn = 0;
sasl_conn_t *ctx;
struct berval dn2;
return( LDAP_SUCCESS );
}
ctx = conn->c_sasl_context;
- len = strlen( id );
+ if ( len == 0 ) len = strlen( id );
/* An authcID needs to be converted to authzID form */
if( flags & FLAG_GETDN_AUTHCID ) {
{
/* check SASL external for X.509 style DN and */
/* convert to dn:<dn> form */
- dn->bv_val = ldap_dcedn2dn( id );
- dn->bv_len = strlen(dn->bv_val);
+ dnDCEnormalize( id, dn );
is_dn = SET_DN;
} else {
/* XXX do we need to check sasldb as well? */
/* XXX can we do both steps at once? */
- rc = slap_sasl_getdn( conn, (char *)username, NULL, &dn,
+ rc = slap_sasl_getdn( conn, (char *)username, 0, NULL, &dn,
FLAG_GETDN_AUTHCID | FLAG_GETDN_FINAL );
if ( rc != LDAP_SUCCESS ) {
sasl_seterror( sconn, 0, ldap_err2string( rc ) );
in ? in : "<empty>" );
#endif
- rc = slap_sasl_getdn( conn, (char *)in, (char *)user_realm, &dn,
+ rc = slap_sasl_getdn( conn, (char *)in, inlen, (char *)user_realm, &dn,
(flags == SASL_CU_AUTHID) ? FLAG_GETDN_AUTHCID : FLAG_GETDN_AUTHZID );
if ( rc != LDAP_SUCCESS ) {
sasl_seterror( sconn, 0, ldap_err2string( rc ) );
Connection *conn = (Connection *)context;
struct berval authcDN, authzDN;
char *realm;
- int rc, equal = 1;
+ int rc, equal = 1, ext = 0;
#ifdef NEW_LOGGING
LDAP_LOG(( "sasl", LDAP_LEVEL_ENTRY,
if ( requested_user )
equal = !strcmp( auth_identity, requested_user );
- realm = strchr( auth_identity, '@' );
- if ( realm )
- *realm++ = '\0';
+ /* If using SASL-EXTERNAL, don't modify the ID in any way */
+ if ( conn->c_sasl_bind_mech.bv_len == ext_bv.bv_len
+ && ( strcasecmp( ext_bv.bv_val, conn->c_sasl_bind_mech.bv_val ) == 0 )
+ && auth_identity[0] == '/' ) {
+ ext = 1;
+ realm = NULL;
+ } else {
+ /* Else look for an embedded realm in the name */
+ realm = strchr( auth_identity, '@' );
+ if ( realm ) *realm++ = '\0';
+ }
- rc = slap_sasl_getdn( conn, auth_identity, realm ? realm : (char *)def_realm,
+ rc = slap_sasl_getdn( conn, auth_identity, alen, realm ? realm : (char *)def_realm,
&authcDN, FLAG_GETDN_AUTHCID );
if ( realm )
realm[-1] = '@';
return SASL_OK;
}
- realm = strchr( requested_user, '@' );
- if ( realm )
- *realm++ = '\0';
+ if ( ext ) {
+ realm = NULL;
+ } else {
+ realm = strchr( requested_user, '@' );
+ if ( realm ) *realm++ = '\0';
+ }
- rc = slap_sasl_getdn( conn, requested_user, realm ? realm : (char *)def_realm,
+ rc = slap_sasl_getdn( conn, requested_user, rlen, realm ? realm : (char *)def_realm,
&authzDN, FLAG_GETDN_AUTHZID );
if ( realm )
realm[-1] = '@';
static int
slap_sasl_authorize(
void *context,
- const char *authcid,
- const char *authzid,
+ char *authcid,
+ char *authzid,
const char **user,
const char **errstr)
{
struct berval authcDN, authzDN;
- int rc;
+ int rc, ext = 0;
Connection *conn = context;
- char *realm;
+ char *realm, *xrealm;
*user = NULL;
/* Convert the identities to DN's. If no authzid was given, client will
be bound as the DN matching their username */
- rc = slap_sasl_getdn( conn, (char *)authcid, realm, &authcDN, FLAG_GETDN_AUTHCID );
+ if ( conn->c_sasl_bind_mech.bv_len == ext_bv.bv_len
+ && ( strcasecmp( ext_bv.bv_val, conn->c_sasl_bind_mech.bv_val ) == 0 )
+ && authcid[0] == '/' ) {
+ ext = 1;
+ xrealm = NULL;
+ } else {
+ xrealm = strchr( authcid, '@' );
+ if ( xrealm ) *xrealm++ = '\0';
+ }
+ rc = slap_sasl_getdn( conn, (char *)authcid, 0, xrealm ? xrealm : realm, &authcDN, FLAG_GETDN_AUTHCID );
+ if ( xrealm ) xrealm[-1] = '@';
if( rc != LDAP_SUCCESS ) {
*errstr = ldap_err2string( rc );
return SASL_NOAUTHZ;
*errstr = NULL;
return SASL_OK;
}
- rc = slap_sasl_getdn( conn, (char *)authzid, realm, &authzDN, FLAG_GETDN_AUTHZID );
+ if ( ext ) {
+ xrealm = NULL;
+ } else {
+ xrealm = strchr( authzid, '@' );
+ if ( xrealm ) *xrealm++ = '\0';
+ }
+ rc = slap_sasl_getdn( conn, (char *)authzid, 0, xrealm ? xrealm : realm, &authzDN, FLAG_GETDN_AUTHZID );
+ if ( xrealm ) xrealm[-1] = '@';
if( rc != LDAP_SUCCESS ) {
ch_free( authcDN.bv_val );
*errstr = ldap_err2string( rc );
NULL, "no SASL username", NULL, NULL );
} else {
- rc = slap_sasl_getdn( conn, username, realm, edn, FLAG_GETDN_FINAL );
+ rc = slap_sasl_getdn( conn, username, 0, realm, edn, FLAG_GETDN_FINAL );
if( rc == LDAP_SUCCESS ) {
sasl_ssf_t *ssf = NULL;
*/
static struct berval *
-asn1_integer2str(ASN1_INTEGER *a)
+asn1_integer2str(ASN1_INTEGER *a, struct berval *bv)
{
char buf[256];
char *p;
*--p = '-';
}
- return ber_bvstrdup(p);
+ return ber_str2bv( p, 0, 1, bv );
}
/* Get a DN in RFC2253 format from a X509_NAME internal struct */
-static struct berval *
-dn_openssl2ldap(X509_NAME *name)
+int
+dn_openssl2ldap(X509_NAME *name, struct berval *out)
{
- char issuer_dn[1024];
- BIO *bio;
-
- bio = BIO_new(BIO_s_mem());
- if ( !bio ) {
-#ifdef NEW_LOGGING
- LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
- "dn_openssl2ldap: error creating BIO_s_mem: %s\n",
- ERR_error_string(ERR_get_error(),NULL)));
-#else
- Debug( LDAP_DEBUG_ARGS, "dn_openssl2ldap: "
- "error creating BIO: %s\n",
- ERR_error_string(ERR_get_error(),NULL), NULL, NULL );
-#endif
- return NULL;
- }
- X509_NAME_print_ex(bio, name, 0, XN_FLAG_RFC2253);
-
- BIO_gets(bio, issuer_dn, 1024);
+ char buf[2048], *p;
- BIO_free(bio);
- return ber_bvstrdup(issuer_dn);
+ p = X509_NAME_oneline( name, buf, sizeof( buf ) );
+ return dnDCEnormalize( p, out );
}
/*
{
X509 *xcert;
unsigned char *p = in->bv_val;
- struct berval *serial;
- struct berval *issuer_dn;
- struct berval *bv_tmp;
+ struct berval serial;
+ struct berval issuer_dn;
xcert = d2i_X509(NULL, &p, in->bv_len);
if ( !xcert ) {
return LDAP_INVALID_SYNTAX;
}
- serial = asn1_integer2str(xcert->cert_info->serialNumber);
- if ( !serial ) {
+ if ( !asn1_integer2str(xcert->cert_info->serialNumber, &serial) ) {
X509_free(xcert);
return LDAP_INVALID_SYNTAX;
}
- issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
- if ( !issuer_dn ) {
+ if ( dn_openssl2ldap(X509_get_issuer_name(xcert), &issuer_dn ) != LDAP_SUCCESS ) {
X509_free(xcert);
- ber_bvfree(serial);
+ ber_memfree(serial.bv_val);
return LDAP_INVALID_SYNTAX;
}
- /* Actually, dn_openssl2ldap returns in a normalized format, but
- it is different from our normalized format */
- bv_tmp = issuer_dn;
- if ( dnNormalize(NULL, bv_tmp, &issuer_dn) != LDAP_SUCCESS ) {
- X509_free(xcert);
- ber_bvfree(serial);
- ber_bvfree(bv_tmp);
- return LDAP_INVALID_SYNTAX;
- }
- ber_bvfree(bv_tmp);
X509_free(xcert);
- out->bv_len = serial->bv_len + issuer_dn->bv_len + sizeof(" $ ");
+ out->bv_len = serial.bv_len + issuer_dn.bv_len + sizeof(" $ ");
out->bv_val = ch_malloc(out->bv_len);
p = out->bv_val;
- AC_MEMCPY(p, serial->bv_val, serial->bv_len);
- p += serial->bv_len;
+ AC_MEMCPY(p, serial.bv_val, serial.bv_len);
+ p += serial.bv_len;
AC_MEMCPY(p, " $ ", sizeof(" $ ")-1);
p += 3;
- AC_MEMCPY(p, issuer_dn->bv_val, issuer_dn->bv_len);
- p += issuer_dn->bv_len;
+ AC_MEMCPY(p, issuer_dn.bv_val, issuer_dn.bv_len);
+ p += issuer_dn.bv_len;
*p++ = '\0';
#ifdef NEW_LOGGING
out->bv_val, NULL, NULL );
#endif
- ber_bvfree(serial);
- ber_bvfree(issuer_dn);
+ ber_memfree(serial.bv_val);
+ ber_memfree(issuer_dn.bv_val);
return LDAP_SUCCESS;
}
static int
serial_and_issuer_parse(
struct berval *assertion,
- struct berval **serial,
- struct berval **issuer_dn
+ struct berval *serial,
+ struct berval *issuer_dn
)
{
char *begin;
bv.bv_len = end-begin+1;
bv.bv_val = begin;
- *serial = ber_dupbv(NULL, &bv);
+ ber_dupbv(serial, &bv);
/* now extract the issuer, remember p was at the dollar sign */
- begin = p+1;
- end = assertion->bv_val+assertion->bv_len-1;
- while (ASCII_SPACE(*begin))
- begin++;
- /* should we trim spaces at the end too? is it safe always? */
+ if ( issuer_dn ) {
+ begin = p+1;
+ end = assertion->bv_val+assertion->bv_len-1;
+ while (ASCII_SPACE(*begin))
+ begin++;
+ /* should we trim spaces at the end too? is it safe always? */
- bv.bv_len = end-begin+1;
- bv.bv_val = begin;
- dnNormalize( NULL, &bv, issuer_dn );
+ bv.bv_len = end-begin+1;
+ bv.bv_val = begin;
+ dnNormalize2( NULL, &bv, issuer_dn );
+ }
return LDAP_SUCCESS;
}
{
X509 *xcert;
unsigned char *p = value->bv_val;
- struct berval *serial;
- struct berval *issuer_dn;
- struct berval *asserted_serial;
- struct berval *asserted_issuer_dn;
+ struct berval serial;
+ struct berval issuer_dn;
+ struct berval asserted_serial;
+ struct berval asserted_issuer_dn;
int ret;
xcert = d2i_X509(NULL, &p, value->bv_len);
return LDAP_INVALID_SYNTAX;
}
- serial = asn1_integer2str(xcert->cert_info->serialNumber);
- issuer_dn = dn_openssl2ldap(X509_get_issuer_name(xcert));
+ asn1_integer2str(xcert->cert_info->serialNumber, &serial);
+ dn_openssl2ldap(X509_get_issuer_name(xcert), &issuer_dn);
X509_free(xcert);
flags,
slap_schema.si_syn_integer,
slap_schema.si_mr_integerMatch,
- serial,
- asserted_serial);
+ &serial,
+ &asserted_serial);
if ( ret == LDAP_SUCCESS ) {
if ( *matchp == 0 ) {
/* We need to normalize everything for dnMatch */
flags,
slap_schema.si_syn_distinguishedName,
slap_schema.si_mr_distinguishedNameMatch,
- issuer_dn,
- asserted_issuer_dn);
+ &issuer_dn,
+ &asserted_issuer_dn);
}
}
#ifdef NEW_LOGGING
LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
"certificateExactMatch: %d\n %s $ %s\n %s $ %s\n",
- *matchp, serial->bv_val, issuer_dn->bv_val,
- asserted_serial->bv_val, asserted_issuer_dn->bv_val));
+ *matchp, serial.bv_val, issuer_dn.bv_val,
+ asserted_serial.bv_val, asserted_issuer_dn.bv_val));
#else
Debug( LDAP_DEBUG_ARGS, "certificateExactMatch "
"%d\n\t\"%s $ %s\"\n",
- *matchp, serial->bv_val, issuer_dn->bv_val );
+ *matchp, serial.bv_val, issuer_dn.bv_val );
Debug( LDAP_DEBUG_ARGS, "\t\"%s $ %s\"\n",
- asserted_serial->bv_val, asserted_issuer_dn->bv_val,
+ asserted_serial.bv_val, asserted_issuer_dn.bv_val,
NULL );
#endif
- ber_bvfree(serial);
- ber_bvfree(issuer_dn);
- ber_bvfree(asserted_serial);
- ber_bvfree(asserted_issuer_dn);
+ ber_memfree(serial.bv_val);
+ ber_memfree(issuer_dn.bv_val);
+ ber_memfree(asserted_serial.bv_val);
+ ber_memfree(asserted_issuer_dn.bv_val);
return ret;
}
BerVarray keys;
X509 *xcert;
unsigned char *p;
- struct berval * serial;
+ struct berval serial;
/* we should have at least one value at this point */
assert( values != NULL && values[0].bv_val != NULL );
return LDAP_INVALID_SYNTAX;
}
- serial = asn1_integer2str(xcert->cert_info->serialNumber);
+ asn1_integer2str(xcert->cert_info->serialNumber, &serial);
X509_free(xcert);
integerNormalize( slap_schema.si_syn_integer,
- serial,
+ &serial,
&keys[i] );
- ber_bvfree(serial);
+ ber_memfree(serial.bv_val);
#ifdef NEW_LOGGING
LDAP_LOG(( "schema", LDAP_LEVEL_ENTRY,
"certificateExactIndexer: returning: %s\n",
BerVarray *keysp )
{
BerVarray keys;
- struct berval *asserted_serial;
- struct berval *asserted_issuer_dn;
+ struct berval asserted_serial;
serial_and_issuer_parse(assertValue,
&asserted_serial,
- &asserted_issuer_dn);
+ NULL);
keys = ch_malloc( sizeof( struct berval ) * 2 );
- integerNormalize( syntax, asserted_serial, &keys[0] );
+ integerNormalize( syntax, &asserted_serial, &keys[0] );
keys[1].bv_val = NULL;
*keysp = keys;
- ber_bvfree(asserted_serial);
- ber_bvfree(asserted_issuer_dn);
+ ber_memfree(asserted_serial.bv_val);
return LDAP_SUCCESS;
}
#endif