X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fsaslauthz.c;h=fb4764d71b98c2d1cb319039e2cb88893b2aa2c1;hb=7fe91339dfd08d6c4168c8493f5c1f0faca6ba54;hp=106dca9112a9f736e770c5ca46e479bd30fff2e5;hpb=474dfbc8fd75aed0376695ccc2f8c092a7a1bc6f;p=openldap diff --git a/servers/slapd/saslauthz.c b/servers/slapd/saslauthz.c index 106dca9112..fb4764d71b 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-2009 The OpenLDAP Foundation. * Portions Copyright 2000 Mark Adamson, Carnegie Mellon. * All rights reserved. * @@ -202,7 +202,6 @@ int slap_parse_user( struct berval *id, struct berval *user, return LDAP_SUCCESS; } -#ifdef SLAP_AUTHZ_SYNTAX int authzValidate( Syntax *syntax, @@ -459,20 +458,6 @@ done: return( rc ); } -#if 0 -int -authzMatch( - int *matchp, - slap_mask_t flags, - Syntax *syntax, - MatchingRule *mr, - struct berval *value, - void *assertedValue ) -{ - return octetStringMatch( matchp, flags, syntax, mr, value, assertedValue ); -} -#endif - static int authzPrettyNormal( struct berval *val, @@ -919,7 +904,6 @@ authzPretty( return rc; } -#endif /* SLAP_AUTHZ_SYNTAX */ static int slap_parseURI( @@ -936,9 +920,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 ); @@ -952,7 +934,6 @@ slap_parseURI( rc = LDAP_PROTOCOL_ERROR; -#ifdef SLAP_ORDERED_PRETTYNORM idx = *uri; if ( idx.bv_val[ 0 ] == '{' ) { char *ptr; @@ -965,7 +946,6 @@ slap_parseURI( idx.bv_val = ptr; uri = &idx; } -#endif /* SLAP_ORDERED_PRETTYNORM */ /* * dn[.]: @@ -1136,6 +1116,7 @@ is_dn: bv.bv_len = uri->bv_len - (bv.bv_val - uri->bv_val); } 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 ); @@ -1245,7 +1226,7 @@ is_dn: bv.bv_len = uri->bv_len - (bv.bv_val - uri->bv_val); done: if( rc != LDAP_SUCCESS ) { - if( *filter ) filter_free_x( op, *filter ); + if( *filter ) filter_free_x( op, *filter, 1 ); BER_BVZERO( base ); BER_BVZERO( fstr ); } else { @@ -1319,7 +1300,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 ); @@ -1379,38 +1361,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 ); - } + /* 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 ) @@ -1576,24 +1579,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; } @@ -1606,23 +1610,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; @@ -1673,17 +1665,11 @@ slap_sasl_match( Operation *opx, struct berval *rule, Debug( LDAP_DEBUG_TRACE, "===>slap_sasl_match: comparing DN %s to rule %s\n", - assertDN->bv_val, rule->bv_val, 0 ); + assertDN->bv_len ? assertDN->bv_val : "(null)", rule->bv_val, 0 ); /* 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; @@ -1713,7 +1699,7 @@ exact_match: /* leave room for at least one char of attributeType, * one for '=' and one for ',' */ - if ( d < STRLENOF( "x=,") ) { + if ( d < (int) STRLENOF( "x=,") ) { goto CONCLUDED; } @@ -1820,7 +1806,7 @@ exact_match: "slap_sasl_match: performing internal search (base=%s, scope=%d)\n", op.o_req_ndn.bv_val, op.ors_scope, 0 ); - op.o_bd = select_backend( &op.o_req_ndn, 0, 1 ); + op.o_bd = select_backend( &op.o_req_ndn, 1 ); if(( op.o_bd == NULL ) || ( op.o_bd->be_search == NULL)) { rc = LDAP_INAPPROPRIATE_AUTH; goto CONCLUDED; @@ -1848,7 +1834,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; @@ -1857,7 +1843,7 @@ exact_match: CONCLUDED: if( !BER_BVISNULL( &op.o_req_dn ) ) slap_sl_free( op.o_req_dn.bv_val, opx->o_tmpmemctx ); if( !BER_BVISNULL( &op.o_req_ndn ) ) slap_sl_free( op.o_req_ndn.bv_val, opx->o_tmpmemctx ); - if( op.ors_filter ) filter_free_x( opx, op.ors_filter ); + if( op.ors_filter ) filter_free_x( opx, op.ors_filter, 1 ); if( !BER_BVISNULL( &op.ors_filterstr ) ) ch_free( op.ors_filterstr.bv_val ); Debug( LDAP_DEBUG_TRACE, @@ -1882,14 +1868,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 */ @@ -1949,7 +1939,7 @@ slap_sasl2dn( } /* Must do an internal search */ - op.o_bd = select_backend( &op.o_req_ndn, 0, 1 ); + op.o_bd = select_backend( &op.o_req_ndn, 1 ); switch ( op.ors_scope ) { case LDAP_X_SCOPE_EXACT: @@ -1969,9 +1959,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; @@ -2027,7 +2015,7 @@ FINISHED: slap_sl_free( op.o_req_ndn.bv_val, opx->o_tmpmemctx ); } if( op.ors_filter ) { - filter_free_x( opx, op.ors_filter ); + filter_free_x( opx, op.ors_filter, 1 ); } if( !BER_BVISNULL( &op.ors_filterstr ) ) { ch_free( op.ors_filterstr.bv_val ); @@ -2050,14 +2038,20 @@ int slap_sasl_authorized( Operation *op, int rc = LDAP_INAPPROPRIATE_AUTH; /* User binding as anonymous */ - if ( authzDN == NULL ) { + if ( !authzDN || !authzDN->bv_len || !authzDN->bv_val ) { rc = LDAP_SUCCESS; goto DONE; } + /* User is anonymous */ + if ( !authcDN || !authcDN->bv_len || !authcDN->bv_val ) { + goto DONE; + } + 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 ) ) {