Пример #1
0
/*
 * If the entry exists in cache, it is returned in locked status;
 * otherwise, if the parent exists, if it may generate volatile 
 * descendants an attempt to generate the required entry is
 * performed and, if successful, the entry is returned
 */
int
monitor_cache_dn2entry(
	Operation		*op,
	SlapReply		*rs,
	struct berval		*ndn,
	Entry			**ep,
	Entry			**matched )
{
	monitor_info_t *mi = (monitor_info_t *)op->o_bd->be_private;
	int 			rc;
	struct berval		p_ndn = BER_BVNULL;
	Entry 			*e_parent;
	monitor_entry_t 	*mp;
		
	assert( mi != NULL );
	assert( ndn != NULL );
	assert( ep != NULL );
	assert( matched != NULL );

	*matched = NULL;

	if ( !dnIsSuffix( ndn, &op->o_bd->be_nsuffix[ 0 ] ) ) {
		return( -1 );
	}

	rc = monitor_cache_get( mi, ndn, ep );
       	if ( !rc && *ep != NULL ) {
		return( 0 );
	}

	/* try with parent/ancestors */
	if ( BER_BVISNULL( ndn ) ) {
		BER_BVSTR( &p_ndn, "" );

	} else {
		dnParent( ndn, &p_ndn );
	}

	rc = monitor_cache_dn2entry( op, rs, &p_ndn, &e_parent, matched );
	if ( rc || e_parent == NULL ) {
		return( -1 );
	}

	mp = ( monitor_entry_t * )e_parent->e_private;
	rc = -1;
	if ( mp->mp_flags & MONITOR_F_VOLATILE_CH ) {
		/* parent entry generates volatile children */
		rc = monitor_entry_create( op, rs, ndn, e_parent, ep );
	}

	if ( !rc ) {
		monitor_cache_lock( *ep );
		monitor_cache_release( mi, e_parent );

	} else {
		*matched = e_parent;
	}
	
	return( rc );
}
Пример #2
0
int
monitor_back_modify( Operation *op, SlapReply *rs )
{
	int 		rc = 0;
	monitor_info_t	*mi = ( monitor_info_t * )op->o_bd->be_private;
	Entry		*matched;
	Entry		*e;

	Debug(LDAP_DEBUG_ARGS, "monitor_back_modify:\n", 0, 0, 0);

	/* acquire and lock entry */
	monitor_cache_dn2entry( op, rs, &op->o_req_ndn, &e, &matched );
	if ( e == NULL ) {
		rs->sr_err = LDAP_NO_SUCH_OBJECT;
		if ( matched ) {
			if ( !access_allowed_mask( op, matched,
					slap_schema.si_ad_entry,
					NULL, ACL_DISCLOSE, NULL, NULL ) )
			{
				/* do nothing */ ;
			} else {
				rs->sr_matched = matched->e_dn;
			}
		}
		send_ldap_result( op, rs );
		if ( matched != NULL ) {
			rs->sr_matched = NULL;
			monitor_cache_release( mi, matched );
		}
		return rs->sr_err;
	}

	if ( !acl_check_modlist( op, e, op->orm_modlist )) {
		rc = LDAP_INSUFFICIENT_ACCESS;

	} else {
		assert( !SLAP_SHADOW( op->o_bd ) );
		slap_mods_opattrs( op, &op->orm_modlist, 0 );

		rc = monitor_entry_modify( op, rs, e );
	}

	if ( rc != LDAP_SUCCESS ) {
		if ( !access_allowed_mask( op, e, slap_schema.si_ad_entry,
				NULL, ACL_DISCLOSE, NULL, NULL ) )
		{
			rc = LDAP_NO_SUCH_OBJECT;
		}
	}

	rs->sr_err = rc;
	send_ldap_result( op, rs );

	monitor_cache_release( mi, e );

	return rs->sr_err;
}
Пример #3
0
int
monitor_back_compare( Operation *op, SlapReply *rs )
{
	monitor_info_t	*mi = ( monitor_info_t * ) op->o_bd->be_private;
	Entry           *e, *matched = NULL;
	int		rc;

	/* get entry with reader lock */
	monitor_cache_dn2entry( op, rs, &op->o_req_ndn, &e, &matched );
	if ( e == NULL ) {
		rs->sr_err = LDAP_NO_SUCH_OBJECT;
		if ( matched ) {
			if ( !access_allowed_mask( op, matched,
					slap_schema.si_ad_entry,
					NULL, ACL_DISCLOSE, NULL, NULL ) )
			{
				/* do nothing */ ;
			} else {
				rs->sr_matched = matched->e_dn;
			}
		}
		send_ldap_result( op, rs );
		if ( matched ) {
			monitor_cache_release( mi, matched );
			rs->sr_matched = NULL;
		}

		return rs->sr_err;
	}

	monitor_entry_update( op, rs, e );
	rs->sr_err = slap_compare_entry( op, e, op->orc_ava );
	rc = rs->sr_err;
	switch ( rc ) {
	case LDAP_COMPARE_FALSE:
	case LDAP_COMPARE_TRUE:
		rc = LDAP_SUCCESS;
		break;
	}

	send_ldap_result( op, rs );
	rs->sr_err = rc;

	monitor_cache_release( mi, e );

	return rs->sr_err;
}
Пример #4
0
int
monitor_back_modify(
    Backend	*be,
    Connection	*conn,
    Operation	*op,
    struct berval	*dn,
    struct berval	*ndn,
    Modifications	*modlist
)
{
	int 		rc = 0;
	struct monitorinfo	*mi = (struct monitorinfo *) be->be_private;
	Entry		*matched;
	Entry		*e;

#ifdef NEW_LOGGING
	LDAP_LOG( BACK_MON, ENTRY,
		"monitor_back_modify: enter\n", 0, 0, 0 );
#else
	Debug(LDAP_DEBUG_ARGS, "monitor_back_modify:\n", 0, 0, 0);
#endif

	/* acquire and lock entry */
	monitor_cache_dn2entry( mi, ndn, &e, &matched );
	if ( e == NULL ) {
		send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
				matched ? matched->e_dn : NULL,
				NULL, NULL, NULL );
		if ( matched != NULL ) {
			monitor_cache_release( mi, matched );
			return( 0 );
		}
	}

	if ( !acl_check_modlist( be, conn, op, e, modlist )) {
		rc = LDAP_INSUFFICIENT_ACCESS;
	} else {
		rc = monitor_entry_modify( mi, e, modlist );
	}

	send_ldap_result( conn, op, rc, NULL, NULL, NULL, NULL );

	monitor_cache_release( mi, e );

	return( 0 );
}
Пример #5
0
int
monitor_back_search( Operation *op, SlapReply *rs )
{
	monitor_info_t	*mi = ( monitor_info_t * )op->o_bd->be_private;
	int		rc = LDAP_SUCCESS;
	Entry		*e = NULL, *matched = NULL;
	slap_mask_t	mask;

	Debug( LDAP_DEBUG_TRACE, "=> monitor_back_search\n", 0, 0, 0 );


	/* get entry with reader lock */
	monitor_cache_dn2entry( op, rs, &op->o_req_ndn, &e, &matched );
	if ( e == NULL ) {
		rs->sr_err = LDAP_NO_SUCH_OBJECT;
		if ( matched ) {
			if ( !access_allowed_mask( op, matched,
					slap_schema.si_ad_entry,
					NULL, ACL_DISCLOSE, NULL, NULL ) )
			{
				/* do nothing */ ;
			} else {
				rs->sr_matched = matched->e_dn;
			}
		}

		send_ldap_result( op, rs );
		if ( matched ) {
			monitor_cache_release( mi, matched );
			rs->sr_matched = NULL;
		}

		return rs->sr_err;
	}

	/* NOTE: __NEW__ "search" access is required
	 * on searchBase object */
	if ( !access_allowed_mask( op, e, slap_schema.si_ad_entry,
				NULL, ACL_SEARCH, NULL, &mask ) )
	{
		monitor_cache_release( mi, e );

		if ( !ACL_GRANT( mask, ACL_DISCLOSE ) ) {
			rs->sr_err = LDAP_NO_SUCH_OBJECT;
		} else {
			rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
		}

		send_ldap_result( op, rs );

		return rs->sr_err;
	}

	rs->sr_attrs = op->oq_search.rs_attrs;
	switch ( op->oq_search.rs_scope ) {
	case LDAP_SCOPE_BASE:
		monitor_entry_update( op, rs, e );
		rc = test_filter( op, e, op->oq_search.rs_filter );
 		if ( rc == LDAP_COMPARE_TRUE ) {
			rs->sr_entry = e;
			rs->sr_flags = 0;
			send_search_entry( op, rs );
			rs->sr_entry = NULL;
		}
		rc = LDAP_SUCCESS;
		monitor_cache_release( mi, e );
		break;

	case LDAP_SCOPE_ONELEVEL:
	case LDAP_SCOPE_SUBORDINATE:
		rc = monitor_send_children( op, rs, e,
			op->oq_search.rs_scope == LDAP_SCOPE_SUBORDINATE );
		break;

	case LDAP_SCOPE_SUBTREE:
		monitor_entry_update( op, rs, e );
		rc = test_filter( op, e, op->oq_search.rs_filter );
		if ( rc == LDAP_COMPARE_TRUE ) {
			rs->sr_entry = e;
			rs->sr_flags = 0;
			send_search_entry( op, rs );
			rs->sr_entry = NULL;
		}

		rc = monitor_send_children( op, rs, e, 1 );
		break;

	default:
		rc = LDAP_UNWILLING_TO_PERFORM;
		monitor_cache_release( mi, e );
	}

	rs->sr_attrs = NULL;
	rs->sr_err = rc;
	if ( rs->sr_err != SLAPD_ABANDON ) {
		send_ldap_result( op, rs );
	}

	return rs->sr_err;
}
Пример #6
0
int
monitor_back_compare( Operation *op, SlapReply *rs )
{
	monitor_info_t	*mi = ( monitor_info_t * ) op->o_bd->be_private;
	Entry           *e, *matched = NULL;
	Attribute	*a;
	int		rc;

	/* get entry with reader lock */
	monitor_cache_dn2entry( op, rs, &op->o_req_ndn, &e, &matched );
	if ( e == NULL ) {
		rs->sr_err = LDAP_NO_SUCH_OBJECT;
		if ( matched ) {
			if ( !access_allowed_mask( op, matched,
					slap_schema.si_ad_entry,
					NULL, ACL_DISCLOSE, NULL, NULL ) )
			{
				/* do nothing */ ;
			} else {
				rs->sr_matched = matched->e_dn;
			}
		}
		send_ldap_result( op, rs );
		if ( matched ) {
			monitor_cache_release( mi, matched );
			rs->sr_matched = NULL;
		}

		return rs->sr_err;
	}

	rs->sr_err = access_allowed( op, e, op->oq_compare.rs_ava->aa_desc,
			&op->oq_compare.rs_ava->aa_value, ACL_COMPARE, NULL );
	if ( !rs->sr_err ) {
		rs->sr_err = LDAP_INSUFFICIENT_ACCESS;
		goto return_results;
	}

	rs->sr_err = LDAP_NO_SUCH_ATTRIBUTE;

	for ( a = attrs_find( e->e_attrs, op->oq_compare.rs_ava->aa_desc );
			a != NULL;
			a = attrs_find( a->a_next, op->oq_compare.rs_ava->aa_desc )) {
		rs->sr_err = LDAP_COMPARE_FALSE;

		if ( attr_valfind( a,
			SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
				SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
			&op->oq_compare.rs_ava->aa_value, NULL,
			op->o_tmpmemctx ) == 0 )
		{
			rs->sr_err = LDAP_COMPARE_TRUE;
			break;
		}
	}

return_results:;
	rc = rs->sr_err;
	switch ( rc ) {
	case LDAP_COMPARE_FALSE:
	case LDAP_COMPARE_TRUE:
		rc = LDAP_SUCCESS;
		break;

	case LDAP_NO_SUCH_ATTRIBUTE:
		break;

	default:
		if ( !access_allowed_mask( op, e, slap_schema.si_ad_entry,
				NULL, ACL_DISCLOSE, NULL, NULL ) )
		{
			rs->sr_err = LDAP_NO_SUCH_OBJECT;
		}
		break;
	}
		
	send_ldap_result( op, rs );
	rs->sr_err = rc;

	monitor_cache_release( mi, e );

	return rs->sr_err;
}