X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fsaslauthz.c;h=2f6fd33d48aa4e5d6fcf374afd933e9767a9da6b;hb=5ed0fc37494b835aeeb39bd55ee6d71cedad8143;hp=335ae6384383890367ba754ff1d727da232f6dfe;hpb=f07015dad2d6ccdbe5b8360bfbc601b13baae894;p=openldap
diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c
index 335ae63843..2f6fd33d48 100644
--- a/servers/slapd/saslauthz.c
+++ b/servers/slapd/saslauthz.c
@@ -1,7 +1,7 @@
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software .
*
- * Copyright 1998-2005 The OpenLDAP Foundation.
+ * Copyright 1998-2007 The OpenLDAP Foundation.
* Portions Copyright 2000 Mark Adamson, Carnegie Mellon.
* All rights reserved.
*
@@ -148,7 +148,7 @@ int slap_parse_user( struct berval *id, struct berval *user,
* u[.mech[/realm]]:user
*/
- user->bv_val = strchr( id->bv_val, ':' );
+ user->bv_val = ber_bvchr( id, ':' );
if ( BER_BVISNULL( user ) ) {
return LDAP_PROTOCOL_ERROR;
}
@@ -156,20 +156,19 @@ int slap_parse_user( struct berval *id, struct berval *user,
user->bv_val++;
user->bv_len = id->bv_len - ( user->bv_val - id->bv_val );
- mech->bv_val = strchr( id->bv_val, '.' );
+ mech->bv_val = ber_bvchr( id, '.' );
if ( !BER_BVISNULL( mech ) ) {
mech->bv_val[ 0 ] = '\0';
mech->bv_val++;
+ mech->bv_len = user->bv_val - mech->bv_val - 1;
- realm->bv_val = strchr( mech->bv_val, '/' );
+ realm->bv_val = ber_bvchr( mech, '/' );
if ( !BER_BVISNULL( realm ) ) {
realm->bv_val[ 0 ] = '\0';
realm->bv_val++;
mech->bv_len = realm->bv_val - mech->bv_val - 1;
realm->bv_len = user->bv_val - realm->bv_val - 1;
- } else {
- mech->bv_len = user->bv_val - mech->bv_val - 1;
}
} else {
@@ -203,7 +202,6 @@ int slap_parse_user( struct berval *id, struct berval *user,
return LDAP_SUCCESS;
}
-#ifdef SLAP_AUTHZ_SYNTAX
int
authzValidate(
Syntax *syntax,
@@ -341,7 +339,8 @@ is_dn: bv.bv_len = in->bv_len - ( bv.bv_val - in->bv_val );
member_at = BER_BVNULL;
bv.bv_val = in->bv_val + STRLENOF( "group" );
- group_dn.bv_val = strchr( bv.bv_val, ':' );
+ bv.bv_len = in->bv_len - STRLENOF( "group" );
+ group_dn.bv_val = ber_bvchr( &bv, ':' );
if ( group_dn.bv_val == NULL ) {
/* last chance: assume it's a(n exact) DN ... */
bv.bv_val = in->bv_val;
@@ -355,8 +354,9 @@ is_dn: bv.bv_len = in->bv_len - ( bv.bv_val - in->bv_val );
*/
if ( bv.bv_val[ 0 ] == '/' ) {
group_oc.bv_val = &bv.bv_val[ 1 ];
+ group_oc.bv_len = group_dn.bv_val - group_oc.bv_val;
- member_at.bv_val = strchr( group_oc.bv_val, '/' );
+ member_at.bv_val = ber_bvchr( &group_oc, '/' );
if ( member_at.bv_val ) {
AttributeDescription *ad = NULL;
const char *text = NULL;
@@ -368,13 +368,10 @@ is_dn: bv.bv_len = in->bv_len - ( bv.bv_val - in->bv_val );
if ( rc != LDAP_SUCCESS ) {
return rc;
}
+ }
- } else {
- group_oc.bv_len = group_dn.bv_val - group_oc.bv_val;
-
- if ( oc_bvfind( &group_oc ) == NULL ) {
- return LDAP_INVALID_SYNTAX;
- }
+ if ( oc_bvfind( &group_oc ) == NULL ) {
+ return LDAP_INVALID_SYNTAX;
}
}
@@ -668,7 +665,8 @@ is_dn: bv.bv_len = val->bv_len - ( bv.bv_val - val->bv_val );
char *ptr;
bv.bv_val = val->bv_val + STRLENOF( "group" );
- group_dn.bv_val = strchr( bv.bv_val, ':' );
+ bv.bv_len = val->bv_len - STRLENOF( "group" );
+ group_dn.bv_val = ber_bvchr( &bv, ':' );
if ( group_dn.bv_val == NULL ) {
/* last chance: assume it's a(n exact) DN ... */
bv.bv_val = val->bv_val;
@@ -681,9 +679,12 @@ is_dn: bv.bv_len = val->bv_len - ( bv.bv_val - val->bv_val );
* are present in schema...
*/
if ( bv.bv_val[ 0 ] == '/' ) {
+ ObjectClass *oc = NULL;
+
group_oc.bv_val = &bv.bv_val[ 1 ];
+ group_oc.bv_len = group_dn.bv_val - group_oc.bv_val;
- member_at.bv_val = strchr( group_oc.bv_val, '/' );
+ member_at.bv_val = ber_bvchr( &group_oc, '/' );
if ( member_at.bv_val ) {
AttributeDescription *ad = NULL;
const char *text = NULL;
@@ -698,18 +699,14 @@ is_dn: bv.bv_len = val->bv_len - ( bv.bv_val - val->bv_val );
member_at = ad->ad_cname;
- } else {
- ObjectClass *oc = NULL;
-
- group_oc.bv_len = group_dn.bv_val - group_oc.bv_val;
-
- oc = oc_bvfind( &group_oc );
- if ( oc == NULL ) {
- return LDAP_INVALID_SYNTAX;
- }
+ }
- group_oc = oc->soc_cname;
+ oc = oc_bvfind( &group_oc );
+ if ( oc == NULL ) {
+ return LDAP_INVALID_SYNTAX;
}
+
+ group_oc = oc->soc_cname;
}
group_dn.bv_val++;
@@ -921,7 +918,6 @@ authzPretty(
return rc;
}
-#endif /* SLAP_AUTHZ_SYNTAX */
static int
slap_parseURI(
@@ -938,9 +934,7 @@ slap_parseURI(
int rc;
LDAPURLDesc *ludp;
-#ifdef SLAP_ORDERED_PRETTYNORM
struct berval idx;
-#endif /* SLAP_ORDERED_PRETTYNORM */
assert( uri != NULL && !BER_BVISNULL( uri ) );
BER_BVZERO( base );
@@ -954,12 +948,11 @@ slap_parseURI(
rc = LDAP_PROTOCOL_ERROR;
-#ifdef SLAP_ORDERED_PRETTYNORM
idx = *uri;
if ( idx.bv_val[ 0 ] == '{' ) {
char *ptr;
- ptr = strchr( idx.bv_val, '}' ) + 1;
+ ptr = ber_bvchr( &idx, '}' ) + 1;
assert( ptr != (void *)1 );
@@ -967,7 +960,6 @@ slap_parseURI(
idx.bv_val = ptr;
uri = &idx;
}
-#endif /* SLAP_ORDERED_PRETTYNORM */
/*
* dn[.]:
@@ -1113,7 +1105,8 @@ is_dn: bv.bv_len = uri->bv_len - (bv.bv_val - uri->bv_val);
char *tmp;
bv.bv_val = uri->bv_val + STRLENOF( "group" );
- group_dn.bv_val = strchr( bv.bv_val, ':' );
+ bv.bv_len = uri->bv_len - STRLENOF( "group" );
+ group_dn.bv_val = ber_bvchr( &bv, ':' );
if ( group_dn.bv_val == NULL ) {
/* last chance: assume it's a(n exact) DN ... */
bv.bv_val = uri->bv_val;
@@ -1123,20 +1116,21 @@ is_dn: bv.bv_len = uri->bv_len - (bv.bv_val - uri->bv_val);
if ( bv.bv_val[ 0 ] == '/' ) {
group_oc.bv_val = &bv.bv_val[ 1 ];
+ group_oc.bv_len = group_dn.bv_val - group_oc.bv_val;
- member_at.bv_val = strchr( group_oc.bv_val, '/' );
+ member_at.bv_val = ber_bvchr( &group_oc, '/' );
if ( member_at.bv_val ) {
group_oc.bv_len = member_at.bv_val - group_oc.bv_val;
member_at.bv_val++;
member_at.bv_len = group_dn.bv_val - member_at.bv_val;
} else {
- group_oc.bv_len = group_dn.bv_val - group_oc.bv_val;
BER_BVSTR( &member_at, SLAPD_GROUP_ATTR );
}
} else {
BER_BVSTR( &group_oc, SLAPD_GROUP_CLASS );
+ BER_BVSTR( &member_at, SLAPD_GROUP_ATTR );
}
group_dn.bv_val++;
group_dn.bv_len = uri->bv_len - ( group_dn.bv_val - uri->bv_val );
@@ -1320,7 +1314,8 @@ int slap_sasl_rewrite_config(
return rc;
}
-int slap_sasl_rewrite_destroy( void )
+static int
+slap_sasl_rewrite_destroy( void )
{
if ( sasl_rwinfo ) {
rewrite_info_delete( &sasl_rwinfo );
@@ -1380,32 +1375,59 @@ int slap_sasl_regexp_config( const char *match, const char *replace )
reg = &SaslRegexp[nSaslRegexp];
- reg->sr_match = ch_strdup( match );
- reg->sr_replace = ch_strdup( replace );
-
#ifdef SLAP_AUTH_REWRITE
rc = slap_sasl_regexp_rewrite_config( "sasl-regexp", 0,
match, replace, AUTHID_CONTEXT );
- if ( rc == LDAP_SUCCESS ) nSaslRegexp++;
- return rc;
#else /* ! SLAP_AUTH_REWRITE */
/* Precompile matching pattern */
- rc = regcomp( ®->sr_workspace, reg->sr_match, REG_EXTENDED|REG_ICASE );
+ rc = regcomp( ®->sr_workspace, match, REG_EXTENDED|REG_ICASE );
if ( rc ) {
Debug( LDAP_DEBUG_ANY,
- "SASL match pattern %s could not be compiled by regexp engine\n",
- reg->sr_match, 0, 0 );
+ "SASL match pattern %s could not be compiled by regexp engine\n",
+ match, 0, 0 );
+#ifdef ENABLE_REWRITE
+ /* Dummy block to force symbol references in librewrite */
+ if ( slapMode == ( SLAP_SERVER_MODE|SLAP_TOOL_MODE )) {
+ rewrite_info_init( 0 );
+ }
+#endif
return( LDAP_OTHER );
}
- rc = slap_sasl_rx_off( reg->sr_replace, reg->sr_offset );
- if ( rc != LDAP_SUCCESS ) return rc;
-
- nSaslRegexp++;
- return( LDAP_SUCCESS );
+ rc = slap_sasl_rx_off( replace, reg->sr_offset );
#endif /* ! SLAP_AUTH_REWRITE */
+ if ( rc == LDAP_SUCCESS ) {
+ reg->sr_match = ch_strdup( match );
+ reg->sr_replace = ch_strdup( replace );
+
+ nSaslRegexp++;
+ }
+
+ return rc;
+}
+
+void
+slap_sasl_regexp_destroy( void )
+{
+ if ( SaslRegexp ) {
+ int n;
+
+ for ( n = 0; n < nSaslRegexp; n++ ) {
+ ch_free( SaslRegexp[ n ].sr_match );
+ ch_free( SaslRegexp[ n ].sr_replace );
+#ifndef SLAP_AUTH_REWRITE
+ regfree( &SaslRegexp[ n ].sr_workspace );
+#endif /* SLAP_AUTH_REWRITE */
+ }
+
+ ch_free( SaslRegexp );
+ }
+
+#ifdef SLAP_AUTH_REWRITE
+ slap_sasl_rewrite_destroy();
+#endif /* SLAP_AUTH_REWRITE */
}
void slap_sasl_regexp_unparse( BerVarray *out )
@@ -1571,24 +1593,25 @@ static int slap_authz_regexp( struct berval *in, struct berval *out,
}
/* This callback actually does some work...*/
-static int sasl_sc_sasl2dn( Operation *o, SlapReply *rs )
+static int sasl_sc_sasl2dn( Operation *op, SlapReply *rs )
{
- struct berval *ndn = o->o_callback->sc_private;
+ struct berval *ndn = op->o_callback->sc_private;
- if (rs->sr_type != REP_SEARCH) return 0;
+ if ( rs->sr_type != REP_SEARCH ) return LDAP_SUCCESS;
/* We only want to be called once */
if ( !BER_BVISNULL( ndn ) ) {
- o->o_tmpfree(ndn->bv_val, o->o_tmpmemctx);
+ op->o_tmpfree( ndn->bv_val, op->o_tmpmemctx );
BER_BVZERO( ndn );
Debug( LDAP_DEBUG_TRACE,
- "slap_sc_sasl2dn: search DN returned more than 1 entry\n", 0, 0, 0 );
- return -1;
+ "%s: slap_sc_sasl2dn: search DN returned more than 1 entry\n",
+ op->o_log_prefix, 0, 0 );
+ return LDAP_UNAVAILABLE; /* short-circuit the search */
}
- ber_dupbv_x(ndn, &rs->sr_entry->e_nname, o->o_tmpmemctx);
- return 0;
+ ber_dupbv_x( ndn, &rs->sr_entry->e_nname, op->o_tmpmemctx );
+ return LDAP_SUCCESS;
}
@@ -1601,23 +1624,11 @@ static int sasl_sc_smatch( Operation *o, SlapReply *rs )
{
smatch_info *sm = o->o_callback->sc_private;
- if ( rs->sr_type != REP_SEARCH ) {
- if ( rs->sr_err != LDAP_SUCCESS ) {
- sm->match = -1;
- }
- return 0;
- }
-
- if ( sm->match == 1 ) {
- sm->match = -1;
- return 0;
- }
+ if (rs->sr_type != REP_SEARCH) return 0;
if (dn_match(sm->dn, &rs->sr_entry->e_nname)) {
sm->match = 1;
-
- } else {
- sm->match = -1;
+ return LDAP_UNAVAILABLE; /* short-circuit the search */
}
return 0;
@@ -1672,13 +1683,7 @@ slap_sasl_match( Operation *opx, struct berval *rule,
/* NOTE: don't normalize rule if authz syntax is enabled */
rc = slap_parseURI( opx, rule, &base, &op.o_req_ndn,
- &op.ors_scope, &op.ors_filter, &op.ors_filterstr,
-#ifdef SLAP_AUTHZ_SYNTAX
- 0
-#else /* ! SLAP_AUTHZ_SYNTAX */
- 1
-#endif /* ! SLAP_AUTHZ_SYNTAX */
- );
+ &op.ors_scope, &op.ors_filter, &op.ors_filterstr, 0 );
if( rc != LDAP_SUCCESS ) goto CONCLUDED;
@@ -1825,7 +1830,7 @@ exact_match:
op.o_tag = LDAP_REQ_SEARCH;
op.o_ndn = *authc;
op.o_callback = &cb;
- op.o_time = slap_get_time();
+ slap_op_time( &op.o_time, &op.o_tincr );
op.o_do_not_cache = 1;
op.o_is_auth_check = 1;
/* use req_ndn as req_dn instead of non-pretty base of uri */
@@ -1843,7 +1848,7 @@ exact_match:
op.o_bd->be_search( &op, &rs );
- if (sm.match == 1) {
+ if (sm.match) {
rc = LDAP_SUCCESS;
} else {
rc = LDAP_INAPPROPRIATE_AUTH;
@@ -1877,14 +1882,18 @@ slap_sasl_check_authz( Operation *op,
AttributeDescription *ad,
struct berval *authc )
{
- int rc;
- BerVarray vals = NULL;
+ int rc,
+ do_not_cache = op->o_do_not_cache;
+ BerVarray vals = NULL;
Debug( LDAP_DEBUG_TRACE,
"==>slap_sasl_check_authz: does %s match %s rule in %s?\n",
assertDN->bv_val, ad->ad_cname.bv_val, searchDN->bv_val);
+ /* ITS#4760: don't cache group access */
+ op->o_do_not_cache = 1;
rc = backend_attribute( op, NULL, searchDN, ad, &vals, ACL_AUTH );
+ op->o_do_not_cache = do_not_cache;
if( rc != LDAP_SUCCESS ) goto COMPLETE;
/* Check if the *assertDN matches any *vals */
@@ -1964,9 +1973,7 @@ slap_sasl2dn(
case LDAP_SCOPE_BASE:
case LDAP_SCOPE_ONELEVEL:
case LDAP_SCOPE_SUBTREE:
-#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE:
-#endif
/* do a search */
break;
@@ -1993,7 +2000,7 @@ slap_sasl2dn(
op.o_tag = LDAP_REQ_SEARCH;
op.o_ndn = opx->o_conn->c_ndn;
op.o_callback = &cb;
- op.o_time = slap_get_time();
+ slap_op_time( &op.o_time, &op.o_tincr );
op.o_do_not_cache = 1;
op.o_is_auth_check = 1;
op.ors_deref = LDAP_DEREF_NEVER;
@@ -2052,7 +2059,8 @@ int slap_sasl_authorized( Operation *op,
Debug( LDAP_DEBUG_TRACE,
"==>slap_sasl_authorized: can %s become %s?\n",
- authcDN->bv_val, authzDN->bv_val, 0 );
+ authcDN->bv_len ? authcDN->bv_val : "(null)",
+ authzDN->bv_len ? authzDN->bv_val : "(null)", 0 );
/* If person is authorizing to self, succeed */
if ( dn_match( authcDN, authzDN ) ) {