2 * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
3 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6 * Copyright (c) 1993 Regents of the University of Michigan.
9 * getfilter.c -- optional add-on to libldap
20 #include <ac/string.h>
22 #include <ac/unistd.h>
24 #ifdef HAVE_SYS_FILE_H
30 static int break_into_words LDAP_P(( char *str, char *delims, char ***wordsp ));
32 #define FILT_MAX_LINE_LEN 1024
35 ldap_init_getfilter( char *fname )
43 if (( fp = fopen( fname, "r" )) == NULL ) {
47 if ( fseek( fp, 0L, SEEK_END ) != 0 ) { /* move to end to get len */
54 if ( fseek( fp, 0L, SEEK_SET ) != 0 ) { /* back to start of file */
59 if (( buf = malloc( (size_t)len )) == NULL ) {
64 rlen = fread( buf, 1, (size_t)len, fp );
68 if ( rlen != len && !eof ) { /* error: didn't get the whole file */
74 lfdp = ldap_init_getfilter_buf( buf, rlen );
82 ldap_init_getfilter_buf( char *buf, long buflen )
85 LDAPFiltList *flp, *nextflp;
86 LDAPFiltInfo *fip, *nextfip;
92 if (( lfdp = (LDAPFiltDesc *)calloc( 1, sizeof( LDAPFiltDesc))) == NULL ) {
100 while ( buflen > 0 && ( tokcnt = next_line_tokens( &buf, &buflen, &tok ))
104 case 1: /* tag line */
112 case 5: /* start of filter info. list */
113 if (( nextflp = (LDAPFiltList *)calloc( 1, sizeof( LDAPFiltList )))
115 ldap_getfilter_free( lfdp );
118 nextflp->lfl_tag = strdup( tag );
119 nextflp->lfl_pattern = tok[ 0 ];
120 if ( (rc = regcomp( &re, nextflp->lfl_pattern, 0 )) != 0 ) {
123 regerror(rc, &re, error, sizeof(error));
124 ldap_getfilter_free( lfdp );
125 fprintf( stderr, "bad regular expression %s, %s\n",
126 nextflp->lfl_pattern, error );
128 #endif /* LDAP_LIBUI */
129 free_strarray( tok );
134 nextflp->lfl_delims = tok[ 1 ];
135 nextflp->lfl_ilist = NULL;
136 nextflp->lfl_next = NULL;
137 if ( flp == NULL ) { /* first one */
138 lfdp->lfd_filtlist = nextflp;
140 flp->lfl_next = nextflp;
144 for ( i = 2; i < 5; ++i ) {
145 tok[ i - 2 ] = tok[ i ];
150 case 3: /* filter, desc, and optional search scope */
151 if ( nextflp != NULL ) { /* add to info list */
152 if (( nextfip = (LDAPFiltInfo *)calloc( 1,
153 sizeof( LDAPFiltInfo ))) == NULL ) {
154 ldap_getfilter_free( lfdp );
155 free_strarray( tok );
158 if ( fip == NULL ) { /* first one */
159 nextflp->lfl_ilist = nextfip;
161 fip->lfi_next = nextfip;
164 nextfip->lfi_next = NULL;
165 nextfip->lfi_filter = tok[ 0 ];
166 nextfip->lfi_desc = tok[ 1 ];
167 if ( tok[ 2 ] != NULL ) {
168 if ( strcasecmp( tok[ 2 ], "subtree" ) == 0 ) {
169 nextfip->lfi_scope = LDAP_SCOPE_SUBTREE;
170 } else if ( strcasecmp( tok[ 2 ], "onelevel" ) == 0 ) {
171 nextfip->lfi_scope = LDAP_SCOPE_ONELEVEL;
172 } else if ( strcasecmp( tok[ 2 ], "base" ) == 0 ) {
173 nextfip->lfi_scope = LDAP_SCOPE_BASE;
175 free_strarray( tok );
176 ldap_getfilter_free( lfdp );
183 nextfip->lfi_scope = LDAP_SCOPE_SUBTREE; /* default */
185 nextfip->lfi_isexact = ( strchr( tok[ 0 ], '*' ) == NULL &&
186 strchr( tok[ 0 ], '~' ) == NULL );
192 free_strarray( tok );
193 ldap_getfilter_free( lfdp );
208 ldap_setfilteraffixes( LDAPFiltDesc *lfdp, char *prefix, char *suffix )
210 if ( lfdp->lfd_filtprefix != NULL ) {
211 free( lfdp->lfd_filtprefix );
213 lfdp->lfd_filtprefix = ( prefix == NULL ) ? NULL : strdup( prefix );
215 if ( lfdp->lfd_filtsuffix != NULL ) {
216 free( lfdp->lfd_filtsuffix );
218 lfdp->lfd_filtsuffix = ( suffix == NULL ) ? NULL : strdup( suffix );
223 ldap_getfirstfilter( LDAPFiltDesc *lfdp, char *tagpat, char *value )
229 if ( lfdp->lfd_curvalcopy != NULL ) {
230 free( lfdp->lfd_curvalcopy );
231 free( lfdp->lfd_curvalwords );
234 lfdp->lfd_curval = value;
235 lfdp->lfd_curfip = NULL;
237 for ( flp = lfdp->lfd_filtlist; flp != NULL; flp = flp->lfl_next ) {
238 /* compile tagpat, continue if we fail */
239 if (regcomp(&re, tagpat, 0) != 0)
242 /* match tagpatern and tag, continue if we fail */
243 rc = regexec(&re, flp->lfl_tag, 0, NULL, 0);
248 /* compile flp->ifl_pattern, continue if we fail */
249 if (regcomp(&re, flp->lfl_pattern, 0) != 0)
252 /* match ifl_pattern and lfd_curval, continue if we fail */
253 rc = regexec(&re, lfdp->lfd_curval, 0, NULL, 0);
258 /* we successfully compiled both patterns and matched both values */
259 lfdp->lfd_curfip = flp->lfl_ilist;
263 if ( lfdp->lfd_curfip == NULL ) {
267 if (( lfdp->lfd_curvalcopy = strdup( value )) == NULL ) {
271 if ( break_into_words( lfdp->lfd_curvalcopy, flp->lfl_delims,
272 &lfdp->lfd_curvalwords ) < 0 ) {
273 free( lfdp->lfd_curvalcopy );
274 lfdp->lfd_curvalcopy = NULL;
278 return( ldap_getnextfilter( lfdp ));
283 ldap_getnextfilter( LDAPFiltDesc *lfdp )
287 fip = lfdp->lfd_curfip;
293 lfdp->lfd_curfip = fip->lfi_next;
295 ldap_build_filter( lfdp->lfd_filter, LDAP_FILT_MAXSIZ, fip->lfi_filter,
296 lfdp->lfd_filtprefix, lfdp->lfd_filtsuffix, NULL,
297 lfdp->lfd_curval, lfdp->lfd_curvalwords );
298 lfdp->lfd_retfi.lfi_filter = lfdp->lfd_filter;
299 lfdp->lfd_retfi.lfi_desc = fip->lfi_desc;
300 lfdp->lfd_retfi.lfi_scope = fip->lfi_scope;
301 lfdp->lfd_retfi.lfi_isexact = fip->lfi_isexact;
303 return( &lfdp->lfd_retfi );
308 ldap_build_filter( char *filtbuf, unsigned long buflen, char *pattern,
309 char *prefix, char *suffix, char *attr, char *value, char **valwords )
313 int i, wordcount, wordnum, endwordnum;
315 if ( valwords == NULL ) {
318 for ( wordcount = 0; valwords[ wordcount ] != NULL; ++wordcount ) {
325 if ( prefix != NULL ) {
327 f += strlen( prefix );
330 for ( p = pattern; *p != '\0'; ++p ) {
334 if ( isdigit( (unsigned char) p[1] )) {
337 if ( *(p+1) == '-' ) {
339 if ( isdigit( (unsigned char) p[1] )) {
341 endwordnum = *p - '1'; /* e.g., "%v2-4" */
342 if ( endwordnum > wordcount - 1 ) {
343 endwordnum = wordcount - 1;
346 endwordnum = wordcount - 1; /* e.g., "%v2-" */
349 endwordnum = wordnum; /* e.g., "%v2" */
352 if ( wordcount > 0 ) {
353 for ( i = wordnum; i <= endwordnum; ++i ) {
354 if ( i > wordnum ) { /* add blank btw words */
357 slen = strlen( valwords[ i ] );
358 SAFEMEMCPY( f, valwords[ i ], slen );
362 } else if ( *(p+1) == '$' ) {
364 if ( wordcount > 0 ) {
365 wordnum = wordcount - 1;
366 slen = strlen( valwords[ wordnum ] );
367 SAFEMEMCPY( f, valwords[ wordnum ], slen );
370 } else if ( value != NULL ) {
371 slen = strlen( value );
372 SAFEMEMCPY( f, value, slen );
375 } else if ( *p == 'a' && attr != NULL ) {
376 slen = strlen( attr );
377 SAFEMEMCPY( f, attr, slen );
386 if ( (unsigned long) (f - filtbuf) > buflen ) {
393 if ( suffix != NULL && (
394 (unsigned long) ( f - filtbuf ) < buflen ) )
404 break_into_words( char *str, char *delims, char ***wordsp )
410 if (( words = (char **)calloc( 1, sizeof( char * ))) == NULL ) {
414 words[ count ] = NULL;
416 word = ldap_pvt_strtok( str, delims, &tok_r );
417 while ( word != NULL ) {
418 if (( words = (char **)realloc( words,
419 ( count + 2 ) * sizeof( char * ))) == NULL ) {
423 words[ count ] = word;
424 words[ ++count ] = NULL;
425 word = ldap_pvt_strtok( NULL, delims, &tok_r );