3 * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
4 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
7 * Copyright (c) 1993 Regents of the University of Michigan.
10 * getfilter.c -- optional add-on to libldap
17 #include <ac/stdlib.h>
21 #include <ac/string.h>
23 #include <ac/unistd.h>
25 #ifdef HAVE_SYS_FILE_H
31 static int break_into_words LDAP_P((
32 /* LDAP_CONST */ char *str,
33 LDAP_CONST char *delims,
36 #define FILT_MAX_LINE_LEN 1024
39 ldap_init_getfilter_buf( char *buf, ber_len_t buflen )
42 LDAPFiltList *flp, *nextflp;
43 LDAPFiltInfo *fip, *nextfip;
49 if (( lfdp = (LDAPFiltDesc *)LDAP_CALLOC( 1, sizeof( LDAPFiltDesc))) == NULL ) {
57 while ( buflen > 0 && ( tokcnt = ldap_int_next_line_tokens( &buf, &buflen, &tok ))
61 case 1: /* tag line */
69 case 5: /* start of filter info. list */
70 if (( nextflp = (LDAPFiltList *)LDAP_CALLOC( 1, sizeof( LDAPFiltList )))
72 ldap_getfilter_free( lfdp );
75 nextflp->lfl_tag = LDAP_STRDUP( tag );
76 nextflp->lfl_pattern = tok[ 0 ];
77 if ( (rc = regcomp( &re, nextflp->lfl_pattern, 0 )) != 0 ) {
79 regerror(rc, &re, error, sizeof(error));
80 ldap_getfilter_free( lfdp );
82 LDAP_LOG ( FILTER, ERR,
83 "ldap_init_get_filter_buf: bad regular expression %s, %s\n",
84 nextflp->lfl_pattern, error, 0 );
86 Debug( LDAP_DEBUG_ANY, "ldap_init_get_filter_buf: "
87 "bad regular expression %s, %s\n",
88 nextflp->lfl_pattern, error, 0 );
96 nextflp->lfl_delims = tok[ 1 ];
97 nextflp->lfl_ilist = NULL;
98 nextflp->lfl_next = NULL;
99 if ( flp == NULL ) { /* first one */
100 lfdp->lfd_filtlist = nextflp;
102 flp->lfl_next = nextflp;
106 for ( i = 2; i < 5; ++i ) {
107 tok[ i - 2 ] = tok[ i ];
112 case 3: /* filter, desc, and optional search scope */
113 if ( nextflp != NULL ) { /* add to info list */
114 if (( nextfip = (LDAPFiltInfo *)LDAP_CALLOC( 1,
115 sizeof( LDAPFiltInfo ))) == NULL ) {
116 ldap_getfilter_free( lfdp );
120 if ( fip == NULL ) { /* first one */
121 nextflp->lfl_ilist = nextfip;
123 fip->lfi_next = nextfip;
126 nextfip->lfi_next = NULL;
127 nextfip->lfi_filter = tok[ 0 ];
128 nextfip->lfi_desc = tok[ 1 ];
129 if ( tok[ 2 ] != NULL ) {
130 if ( strcasecmp( tok[ 2 ], "subtree" ) == 0 ) {
131 nextfip->lfi_scope = LDAP_SCOPE_SUBTREE;
132 } else if ( strcasecmp( tok[ 2 ], "onelevel" ) == 0 ) {
133 nextfip->lfi_scope = LDAP_SCOPE_ONELEVEL;
134 } else if ( strcasecmp( tok[ 2 ], "base" ) == 0 ) {
135 nextfip->lfi_scope = LDAP_SCOPE_BASE;
138 ldap_getfilter_free( lfdp );
142 LDAP_FREE( tok[ 2 ] );
145 nextfip->lfi_scope = LDAP_SCOPE_SUBTREE; /* default */
147 nextfip->lfi_isexact = ( strchr( tok[ 0 ], '*' ) == NULL &&
148 strchr( tok[ 0 ], '~' ) == NULL );
155 ldap_getfilter_free( lfdp );
169 ldap_init_getfilter( LDAP_CONST char *fname )
177 if (( fp = fopen( fname, "r" )) == NULL ) {
181 if ( fseek( fp, 0L, SEEK_END ) != 0 ) { /* move to end to get len */
188 if ( fseek( fp, 0L, SEEK_SET ) != 0 ) { /* back to start of file */
193 if (( buf = LDAP_MALLOC( (size_t)len )) == NULL ) {
198 rlen = fread( buf, 1, (size_t)len, fp );
202 if ( rlen != len && !eof ) { /* error: didn't get the whole file */
208 lfdp = ldap_init_getfilter_buf( buf, rlen );
217 /* LDAP_CONST */ char *tagpat,
218 /* LDAP_CONST */ char *value )
224 if ( lfdp->lfd_curvalcopy != NULL ) {
225 LDAP_FREE( lfdp->lfd_curvalcopy );
226 LDAP_FREE( lfdp->lfd_curvalwords );
229 lfdp->lfd_curval = value;
230 lfdp->lfd_curfip = NULL;
232 for ( flp = lfdp->lfd_filtlist; flp != NULL; flp = flp->lfl_next ) {
233 /* compile tagpat, continue if we fail */
234 if (regcomp(&re, tagpat, REG_EXTENDED|REG_NOSUB) != 0)
237 /* match tagpattern and tag, continue if we fail */
238 rc = regexec(&re, flp->lfl_tag, 0, NULL, 0);
243 /* compile flp->ifl_pattern, continue if we fail */
244 if (regcomp(&re, flp->lfl_pattern, REG_EXTENDED|REG_NOSUB) != 0)
247 /* match ifl_pattern and lfd_curval, continue if we fail */
248 rc = regexec(&re, lfdp->lfd_curval, 0, NULL, 0);
253 /* we successfully compiled both patterns and matched both values */
254 lfdp->lfd_curfip = flp->lfl_ilist;
258 if ( lfdp->lfd_curfip == NULL ) {
262 if (( lfdp->lfd_curvalcopy = LDAP_STRDUP( value )) == NULL ) {
266 if ( break_into_words( lfdp->lfd_curvalcopy, flp->lfl_delims,
267 &lfdp->lfd_curvalwords ) < 0 ) {
268 LDAP_FREE( lfdp->lfd_curvalcopy );
269 lfdp->lfd_curvalcopy = NULL;
273 return( ldap_getnextfilter( lfdp ));
280 LDAP_CONST char *pattern,
281 LDAP_CONST char *prefix,
282 LDAP_CONST char *suffix,
283 LDAP_CONST char *attr,
284 LDAP_CONST char *value,
288 ldap_getnextfilter( LDAPFiltDesc *lfdp )
292 fip = lfdp->lfd_curfip;
298 lfdp->lfd_curfip = fip->lfi_next;
300 ldap_build_filter( lfdp->lfd_filter, LDAP_FILT_MAXSIZ, fip->lfi_filter,
301 lfdp->lfd_filtprefix, lfdp->lfd_filtsuffix, NULL,
302 lfdp->lfd_curval, lfdp->lfd_curvalwords );
303 lfdp->lfd_retfi.lfi_filter = lfdp->lfd_filter;
304 lfdp->lfd_retfi.lfi_desc = fip->lfi_desc;
305 lfdp->lfd_retfi.lfi_scope = fip->lfi_scope;
306 lfdp->lfd_retfi.lfi_isexact = fip->lfi_isexact;
308 return( &lfdp->lfd_retfi );
315 LDAP_CONST char *pattern,
316 LDAP_CONST char *prefix,
317 LDAP_CONST char *suffix,
318 LDAP_CONST char *attr,
319 LDAP_CONST char *value,
325 int i, wordcount, wordnum, endwordnum;
327 if ( valwords == NULL ) {
330 for ( wordcount = 0; valwords[ wordcount ] != NULL; ++wordcount ) {
337 if ( prefix != NULL ) {
339 f += strlen( prefix );
342 for ( p = pattern; *p != '\0'; ++p ) {
346 if ( LDAP_DIGIT( (unsigned char) p[1] )) {
349 if ( *(p+1) == '-' ) {
351 if ( LDAP_DIGIT( (unsigned char) p[1] )) {
353 endwordnum = *p - '1'; /* e.g., "%v2-4" */
354 if ( endwordnum > wordcount - 1 ) {
355 endwordnum = wordcount - 1;
358 endwordnum = wordcount - 1; /* e.g., "%v2-" */
361 endwordnum = wordnum; /* e.g., "%v2" */
364 if ( wordcount > 0 ) {
365 for ( i = wordnum; i <= endwordnum; ++i ) {
366 if ( i > wordnum ) { /* add blank btw words */
369 slen = strlen( valwords[ i ] );
370 AC_MEMCPY( f, valwords[ i ], slen );
374 } else if ( *(p+1) == '$' ) {
376 if ( wordcount > 0 ) {
377 wordnum = wordcount - 1;
378 slen = strlen( valwords[ wordnum ] );
379 AC_MEMCPY( f, valwords[ wordnum ], slen );
382 } else if ( value != NULL ) {
383 slen = strlen( value );
384 AC_MEMCPY( f, value, slen );
387 } else if ( *p == 'a' && attr != NULL ) {
388 slen = strlen( attr );
389 AC_MEMCPY( f, attr, slen );
398 if ( (size_t) (f - filtbuf) > buflen ) {
405 if ( suffix != NULL && ( (size_t) (f - filtbuf) < buflen ) )
414 break_into_words( /* LDAP_CONST */ char *str, LDAP_CONST char *delims, char ***wordsp )
420 if (( words = (char **)LDAP_CALLOC( 1, sizeof( char * ))) == NULL ) {
424 words[ count ] = NULL;
426 word = ldap_pvt_strtok( str, delims, &tok_r );
427 while ( word != NULL ) {
428 if (( words = (char **)LDAP_REALLOC( words,
429 ( count + 2 ) * sizeof( char * ))) == NULL ) {
433 words[ count ] = word;
434 words[ ++count ] = NULL;
435 word = ldap_pvt_strtok( NULL, delims, &tok_r );