Example #1
0
int ad_keystring(
	struct berval *bv )
{
	ber_len_t i;

	if( !AD_LEADCHAR( bv->bv_val[0] ) ) {
		return 1;
	}

	for( i=1; i<bv->bv_len; i++ ) {
		if( !AD_CHAR( bv->bv_val[i] )) {
			if ( msad_range_hack && bv->bv_val[i] == '=' )
				continue;
			return 1;
		}
	}
	return 0;
}
Example #2
0
int
slap_set_filter( SLAP_SET_GATHER gatherer,
	SetCookie *cp, struct berval *fbv,
	struct berval *user, struct berval *target, BerVarray *results )
{
#define STACK_SIZE	64
#define IS_SET(x)	( (unsigned long)(x) >= 256 )
#define IS_OP(x)	( (unsigned long)(x) < 256 )
#define SF_ERROR(x)	do { rc = -1; goto _error; } while ( 0 )
#define SF_TOP()	( (BerVarray)( ( stp < 0 ) ? 0 : stack[ stp ] ) )
#define SF_POP()	( (BerVarray)( ( stp < 0 ) ? 0 : stack[ stp-- ] ) )
#define SF_PUSH(x)	do { \
		if ( stp >= ( STACK_SIZE - 1 ) ) SF_ERROR( overflow ); \
		stack[ ++stp ] = (BerVarray)(long)(x); \
	} while ( 0 )

	BerVarray	set, lset;
	BerVarray	stack[ STACK_SIZE ] = { 0 };
	int		len, rc, stp;
	unsigned long	op;
	char		c, *filter = fbv->bv_val;

	if ( results ) {
		*results = NULL;
	}

	stp = -1;
	while ( ( c = *filter++ ) ) {
		set = NULL;
		switch ( c ) {
		case ' ':
		case '\t':
		case '\x0A':
		case '\x0D':
			break;

		case '(' /* ) */ :
			if ( IS_SET( SF_TOP() ) ) {
				SF_ERROR( syntax );
			}
			SF_PUSH( c );
			break;

		case /* ( */ ')':
			set = SF_POP();
			if ( IS_OP( set ) ) {
				SF_ERROR( syntax );
			}
			if ( SF_TOP() == (void *)'(' /* ) */ ) {
				SF_POP();
				SF_PUSH( set );
				set = NULL;

			} else if ( IS_OP( SF_TOP() ) ) {
				op = (unsigned long)SF_POP();
				lset = SF_POP();
				SF_POP();
				set = slap_set_join( cp, lset, op, set );
				if ( set == NULL ) {
					SF_ERROR( memory );
				}
				SF_PUSH( set );
				set = NULL;

			} else {
				SF_ERROR( syntax );
			}
			break;

		case '|':	/* union */
		case '&':	/* intersection */
		case '+':	/* string concatenation */
			set = SF_POP();
			if ( IS_OP( set ) ) {
				SF_ERROR( syntax );
			}
			if ( SF_TOP() == 0 || SF_TOP() == (void *)'(' /* ) */ ) {
				SF_PUSH( set );
				set = NULL;

			} else if ( IS_OP( SF_TOP() ) ) {
				op = (unsigned long)SF_POP();
				lset = SF_POP();
				set = slap_set_join( cp, lset, op, set );
				if ( set == NULL ) {
					SF_ERROR( memory );
				}
				SF_PUSH( set );
				set = NULL;
				
			} else {
				SF_ERROR( syntax );
			}
			SF_PUSH( c );
			break;

		case '[' /* ] */:
			if ( ( SF_TOP() == (void *)'/' ) || IS_SET( SF_TOP() ) ) {
				SF_ERROR( syntax );
			}
			for ( len = 0; ( c = *filter++ ) && ( c != /* [ */ ']' ); len++ )
				;
			if ( c == 0 ) {
				SF_ERROR( syntax );
			}
			
			set = cp->set_op->o_tmpcalloc( 2, sizeof( struct berval ),
					cp->set_op->o_tmpmemctx );
			if ( set == NULL ) {
				SF_ERROR( memory );
			}
			set->bv_val = cp->set_op->o_tmpcalloc( len + 1, sizeof( char ),
					cp->set_op->o_tmpmemctx );
			if ( BER_BVISNULL( set ) ) {
				SF_ERROR( memory );
			}
			AC_MEMCPY( set->bv_val, &filter[ - len - 1 ], len );
			set->bv_len = len;
			SF_PUSH( set );
			set = NULL;
			break;

		case '-':
			if ( ( SF_TOP() == (void *)'/' )
				&& ( *filter == '*' || ASCII_DIGIT( *filter ) ) )
			{
				SF_POP();

				if ( *filter == '*' ) {
					set = set_parents( cp, SF_POP() );
					filter++;

				} else {
					char *next = NULL;
					long parent = strtol( filter, &next, 10 );

					if ( next == filter ) {
						SF_ERROR( syntax );
					}

					set = SF_POP();
					if ( parent != 0 ) {
						set = set_parent( cp, set, parent );
					}
					filter = next;
				}

				if ( set == NULL ) {
					SF_ERROR( memory );
				}

				SF_PUSH( set );
				set = NULL;
				break;
			} else {
				c = *filter++;
				if ( c != '>' ) {
					SF_ERROR( syntax );
				}
				/* fall through to next case */
			}

		case '/':
			if ( IS_OP( SF_TOP() ) ) {
				SF_ERROR( syntax );
			}
			SF_PUSH( '/' );
			break;

		default:
			if ( !AD_LEADCHAR( c ) ) {
				SF_ERROR( syntax );
			}
			filter--;
			for ( len = 1;
				( c = filter[ len ] ) && AD_CHAR( c );
				len++ )
			{
				/* count */
				if ( c == '-' && !AD_CHAR( filter[ len + 1 ] ) ) {
					break;
				}
			}
			if ( len == 4
				&& memcmp( "this", filter, len ) == 0 )
			{
				assert( !BER_BVISNULL( target ) );
				if ( ( SF_TOP() == (void *)'/' ) || IS_SET( SF_TOP() ) ) {
					SF_ERROR( syntax );
				}
				set = cp->set_op->o_tmpcalloc( 2, sizeof( struct berval ),
						cp->set_op->o_tmpmemctx );
				if ( set == NULL ) {
					SF_ERROR( memory );
				}
				ber_dupbv_x( set, target, cp->set_op->o_tmpmemctx );
				if ( BER_BVISNULL( set ) ) {
					SF_ERROR( memory );
				}
				BER_BVZERO( &set[ 1 ] );
				
			} else if ( len == 4
				&& memcmp( "user", filter, len ) == 0 ) 
			{
				if ( ( SF_TOP() == (void *)'/' ) || IS_SET( SF_TOP() ) ) {
					SF_ERROR( syntax );
				}
				if ( BER_BVISNULL( user ) ) {
					SF_ERROR( memory );
				}
				set = cp->set_op->o_tmpcalloc( 2, sizeof( struct berval ),
						cp->set_op->o_tmpmemctx );
				if ( set == NULL ) {
					SF_ERROR( memory );
				}
				ber_dupbv_x( set, user, cp->set_op->o_tmpmemctx );
				BER_BVZERO( &set[ 1 ] );
				
			} else if ( SF_TOP() != (void *)'/' ) {
				SF_ERROR( syntax );

			} else {
				struct berval		fb2;
				AttributeDescription	*ad = NULL;
				const char		*text = NULL;

				SF_POP();
				fb2.bv_val = filter;
				fb2.bv_len = len;

				if ( slap_bv2ad( &fb2, &ad, &text ) != LDAP_SUCCESS ) {
					SF_ERROR( syntax );
				}

				/* NOTE: ad must have distinguishedName syntax
				 * or expand in an LDAP URI if c == '*'
				 */
				
				set = set_chase( gatherer,
					cp, SF_POP(), ad, c == '*' );
				if ( set == NULL ) {
					SF_ERROR( memory );
				}
				if ( c == '*' ) {
					len++;
				}
			}
			filter += len;
			SF_PUSH( set );
			set = NULL;
			break;
		}
	}

	set = SF_POP();
	if ( IS_OP( set ) ) {
		SF_ERROR( syntax );
	}
	if ( SF_TOP() == 0 ) {
		/* FIXME: ok ? */ ;

	} else if ( IS_OP( SF_TOP() ) ) {
		op = (unsigned long)SF_POP();
		lset = SF_POP();
		set = slap_set_join( cp, lset, op, set );
		if ( set == NULL ) {
			SF_ERROR( memory );
		}
		
	} else {
		SF_ERROR( syntax );
	}

	rc = slap_set_isempty( set ) ? 0 : 1;
	if ( results ) {
		*results = set;
		set = NULL;
	}

_error:
	if ( IS_SET( set ) ) {
		ber_bvarray_free_x( set, cp->set_op->o_tmpmemctx );
	}
	while ( ( set = SF_POP() ) ) {
		if ( IS_SET( set ) ) {
			ber_bvarray_free_x( set, cp->set_op->o_tmpmemctx );
		}
	}
	return rc;
}