Back to index

lightning-sunbird  0.9+nobinonly
Functions
search.c File Reference
#include "ldap-int.h"

Go to the source code of this file.

Functions

static int nsldapi_timeval2ldaplimit (struct timeval *timeoutp, int defaultvalue)
static int nsldapi_search (LDAP *ld, const char *base, int scope, const char *filter, char **attrs, int attrsonly, LDAPControl **serverctrls, LDAPControl **clientctrls, int timelimit, int sizelimit, int *msgidp)
static char * find_right_paren (char *s)
static char * put_complex_filter (BerElement *ber, char *str, unsigned long tag, int not)
static int put_filter (BerElement *ber, char *str)
static int unescape_filterval (char *str)
static int hexchar2int (char c)
static int is_valid_attr (char *a)
static int put_simple_filter (BerElement *ber, char *str)
static int put_substring_filter (BerElement *ber, char *type, char *str)
static int put_filter_list (BerElement *ber, char *str)
static int nsldapi_search_s (LDAP *ld, const char *base, int scope, const char *filter, char **attrs, int attrsonly, LDAPControl **serverctrls, LDAPControl **clientctrls, struct timeval *localtimeoutp, int timelimit, int sizelimit, LDAPMessage **res)
int LDAP_CALL ldap_search (LDAP *ld, const char *base, int scope, const char *filter, char **attrs, int attrsonly)
int LDAP_CALL ldap_search_ext (LDAP *ld, const char *base, int scope, const char *filter, char **attrs, int attrsonly, LDAPControl **serverctrls, LDAPControl **clientctrls, struct timeval *timeoutp, int sizelimit, int *msgidp)
int nsldapi_build_search_req (LDAP *ld, const char *base, int scope, const char *filter, char **attrs, int attrsonly, LDAPControl **serverctrls, LDAPControl **clientctrls, int timelimit, int sizelimit, int msgid, BerElement **berp)
static char * find_star (char *s)
int LDAP_CALL ldap_search_st (LDAP *ld, const char *base, int scope, const char *filter, char **attrs, int attrsonly, struct timeval *timeout, LDAPMessage **res)
int LDAP_CALL ldap_search_s (LDAP *ld, const char *base, int scope, const char *filter, char **attrs, int attrsonly, LDAPMessage **res)
int LDAP_CALL ldap_search_ext_s (LDAP *ld, const char *base, int scope, const char *filter, char **attrs, int attrsonly, LDAPControl **serverctrls, LDAPControl **clientctrls, struct timeval *timeoutp, int sizelimit, LDAPMessage **res)

Function Documentation

static char * find_right_paren ( char *  s) [static]

Definition at line 385 of file search.c.

{
       int    balance, escape;

       balance = 1;
       escape = 0;
       while ( *s && balance ) {
              if ( escape == 0 ) {
                     if ( *s == '(' )
                            balance++;
                     else if ( *s == ')' )
                            balance--;
              }
              if ( *s == '\\' && ! escape )
                     escape = 1;
              else
                     escape = 0;
              if ( balance )
                     s++;
       }

       return( *s ? s : NULL );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static char* find_star ( char *  s) [static]

Definition at line 655 of file search.c.

{
    for ( ; *s; ++s ) {
       switch ( *s ) {
         case '*': return s;
         case '\\':
           ++s;
           if ( hexchar2int(s[0]) >= 0 && hexchar2int(s[1]) >= 0 ) ++s;
         default: break;
       }
    }
    return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int hexchar2int ( char  c) [static]

Definition at line 852 of file search.c.

{
    if ( c >= '0' && c <= '9' ) {
       return( c - '0' );
    }
    if ( c >= 'A' && c <= 'F' ) {
       return( c - 'A' + 10 );
    }
    if ( c >= 'a' && c <= 'f' ) {
       return( c - 'a' + 10 );
    }
    return( -1 );
}

Here is the caller graph for this function:

static int is_valid_attr ( char *  a) [static]

Definition at line 632 of file search.c.

{
       for ( ; *a; a++ ) {
           if ( !isascii( *a ) ) {
              return( 0 );
           } else if ( !isalnum( *a ) ) {
              switch ( *a ) {
                case '-':
                case '.':
                case ';':
                case ':':
                case '_':
                  break; /* valid */
                default:
                  return( 0 );
              }
           }
       }

       return( 1 );
}

Here is the caller graph for this function:

int LDAP_CALL ldap_search ( LDAP *  ld,
const char *  base,
int  scope,
const char *  filter,
char **  attrs,
int  attrsonly 
)

Definition at line 95 of file search.c.

{
       int           msgid;

       LDAPDebug( LDAP_DEBUG_TRACE, "ldap_search\n", 0, 0, 0 );

       if ( ldap_search_ext( ld, base, scope, filter, attrs, attrsonly, NULL,
           NULL, NULL, -1, &msgid ) == LDAP_SUCCESS ) {
              return( msgid );
       } else {
              return( -1 ); /* error is in ld handle */
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

int LDAP_CALL ldap_search_ext ( LDAP *  ld,
const char *  base,
int  scope,
const char *  filter,
char **  attrs,
int  attrsonly,
LDAPControl **  serverctrls,
LDAPControl **  clientctrls,
struct timeval timeoutp,
int  sizelimit,
int msgidp 
)

Definition at line 123 of file search.c.

{
       /*
        * It is an error to pass in a zero'd timeval.
        */
       if ( timeoutp != NULL && timeoutp->tv_sec == 0 &&
           timeoutp->tv_usec == 0 ) {
              if ( ld != NULL ) {
                     LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
              }
                return( LDAP_PARAM_ERROR );
        }

       return( nsldapi_search( ld, base, scope, filter, attrs, attrsonly,
           serverctrls, clientctrls,
           nsldapi_timeval2ldaplimit( timeoutp, -1 ), sizelimit, msgidp ));
}

Here is the call graph for this function:

Here is the caller graph for this function:

int LDAP_CALL ldap_search_ext_s ( LDAP *  ld,
const char *  base,
int  scope,
const char *  filter,
char **  attrs,
int  attrsonly,
LDAPControl **  serverctrls,
LDAPControl **  clientctrls,
struct timeval timeoutp,
int  sizelimit,
LDAPMessage **  res 
)

Definition at line 943 of file search.c.

{
       return( nsldapi_search_s( ld, base, scope, filter, attrs, attrsonly,
           serverctrls, clientctrls, timeoutp,
           nsldapi_timeval2ldaplimit( timeoutp, -1 ), sizelimit, res ));
}

Here is the call graph for this function:

Here is the caller graph for this function:

int LDAP_CALL ldap_search_s ( LDAP *  ld,
const char *  base,
int  scope,
const char *  filter,
char **  attrs,
int  attrsonly,
LDAPMessage **  res 
)

Definition at line 928 of file search.c.

{
       return( nsldapi_search_s( ld, base, scope, filter, attrs, attrsonly,
           NULL, NULL, NULL, -1, -1, res ));
}

Here is the call graph for this function:

Here is the caller graph for this function:

int LDAP_CALL ldap_search_st ( LDAP *  ld,
const char *  base,
int  scope,
const char *  filter,
char **  attrs,
int  attrsonly,
struct timeval timeout,
LDAPMessage **  res 
)

Definition at line 911 of file search.c.

{
       return( nsldapi_search_s( ld, base, scope, filter, attrs, attrsonly,
           NULL, NULL, timeout, -1, -1, res ));
}

Here is the call graph for this function:

Here is the caller graph for this function:

int nsldapi_build_search_req ( LDAP *  ld,
const char *  base,
int  scope,
const char *  filter,
char **  attrs,
int  attrsonly,
LDAPControl **  serverctrls,
LDAPControl **  clientctrls,
int  timelimit,
int  sizelimit,
int  msgid,
BerElement **  berp 
)

Definition at line 277 of file search.c.

{
       BerElement    *ber;
       int           err;
       char          *fdup;

       /*
        * Create the search request.  It looks like this:
        *     SearchRequest := [APPLICATION 3] SEQUENCE {
        *            baseObject    DistinguishedName,
        *            scope         ENUMERATED {
        *                   baseObject    (0),
        *                   singleLevel   (1),
        *                   wholeSubtree  (2)
        *            },
        *            derefAliases  ENUMERATED {
        *                   neverDerefaliases    (0),
        *                   derefInSearching     (1),
        *                   derefFindingBaseObj  (2),
        *                   alwaysDerefAliases   (3)
        *            },
        *            sizelimit     INTEGER (0 .. 65535),
        *            timelimit     INTEGER (0 .. 65535),
        *            attrsOnly     BOOLEAN,
        *            filter        Filter,
        *            attributes    SEQUENCE OF AttributeType
        *     }
        * wrapped in an ldap message.
        */

       /* create a message to send */
       if (( err = nsldapi_alloc_ber_with_options( ld, &ber ))
           != LDAP_SUCCESS ) {
              return( err );
       }

       if ( base == NULL ) {
           base = "";
       }

       if ( sizelimit == -1 ) {
           sizelimit = ld->ld_sizelimit;
       }

       if ( timelimit == -1 ) {
           timelimit = ld->ld_timelimit;
       }

#ifdef CLDAP
       if ( ld->ld_sbp->sb_naddr > 0 ) {
           err = ber_printf( ber, "{ist{seeiib", msgid,
              ld->ld_cldapdn, LDAP_REQ_SEARCH, base, scope, ld->ld_deref,
              sizelimit, timelimit, attrsonly );
       } else {
#endif /* CLDAP */
              err = ber_printf( ber, "{it{seeiib", msgid,
                  LDAP_REQ_SEARCH, base, scope, ld->ld_deref,
                  sizelimit, timelimit, attrsonly );
#ifdef CLDAP
       }
#endif /* CLDAP */

       if ( err == -1 ) {
              LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
              ber_free( ber, 1 );
              return( LDAP_ENCODING_ERROR );
       }

       fdup = nsldapi_strdup( filter );
       err = put_filter( ber, fdup );
       NSLDAPI_FREE( fdup );

       if ( err == -1 ) {
              LDAP_SET_LDERRNO( ld, LDAP_FILTER_ERROR, NULL, NULL );
              ber_free( ber, 1 );
              return( LDAP_FILTER_ERROR );
       }

       if ( ber_printf( ber, "{v}}", attrs ) == -1 ) {
              LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
              ber_free( ber, 1 );
              return( LDAP_ENCODING_ERROR );
       }

       if ( (err = nsldapi_put_controls( ld, serverctrls, 1, ber ))
           != LDAP_SUCCESS ) {
              ber_free( ber, 1 );
              return( err );
       }

       *berp = ber;
       return( LDAP_SUCCESS );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int nsldapi_search ( LDAP *  ld,
const char *  base,
int  scope,
const char *  filter,
char **  attrs,
int  attrsonly,
LDAPControl **  serverctrls,
LDAPControl **  clientctrls,
int  timelimit,
int  sizelimit,
int msgidp 
) [static]

Definition at line 159 of file search.c.

{
       BerElement    *ber;
       int           rc, rc_key;
       unsigned long key;   /* XXXmcs: memcache */

       LDAPDebug( LDAP_DEBUG_TRACE, "ldap_search_ext\n", 0, 0, 0 );

       if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
              return( LDAP_PARAM_ERROR );
       }

       if ( base == NULL ) {
           base = "";
       }

       if ( filter == NULL ) {
           filter = "(objectclass=*)";
       }

       if ( msgidp == NULL || ( scope != LDAP_SCOPE_BASE
           && scope != LDAP_SCOPE_ONELEVEL && scope != LDAP_SCOPE_SUBTREE )
              || ( sizelimit < -1 )) {
              LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
                return( LDAP_PARAM_ERROR );
        }
       LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
       *msgidp = ++ld->ld_msgid;
       LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );

       /*
        * XXXmcs: should use cache function pointers to hook in memcache
        */
       if ( ld->ld_memcache == NULL ) {
              rc_key = LDAP_NOT_SUPPORTED;
       } else if (( rc_key = ldap_memcache_createkey( ld, base, scope, filter,
           attrs, attrsonly, serverctrls, clientctrls, &key)) == LDAP_SUCCESS
           && ldap_memcache_result( ld, *msgidp, key ) == LDAP_SUCCESS ) {
              return LDAP_SUCCESS;
       }

       /* check the cache */
       if ( ld->ld_cache_on && ld->ld_cache_search != NULL ) {
              LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
              if ( (rc = (ld->ld_cache_search)( ld, *msgidp, LDAP_REQ_SEARCH,
                  base, scope, filter, attrs, attrsonly )) != 0 ) {
                     *msgidp = rc;
                     LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
                     return( LDAP_SUCCESS );
              }
              LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
       }

       /* caching off or did not find it in the cache - check the net */
       if (( rc = nsldapi_build_search_req( ld, base, scope, filter, attrs,
           attrsonly, serverctrls, clientctrls, timelimit, sizelimit,
           *msgidp, &ber )) != LDAP_SUCCESS ) {
              return( rc );
       }

       /* send the message */
       rc = nsldapi_send_initial_request( ld, *msgidp, LDAP_REQ_SEARCH,
              (char *) base, ber );

       /*
        * XXXmcs: should use cache function pointers to hook in memcache
        */
       if ( (rc_key == LDAP_SUCCESS) && (rc >= 0) ) {
              ldap_memcache_new( ld, rc, key, base );
       }

       *msgidp = rc;
       return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int nsldapi_search_s ( LDAP *  ld,
const char *  base,
int  scope,
const char *  filter,
char **  attrs,
int  attrsonly,
LDAPControl **  serverctrls,
LDAPControl **  clientctrls,
struct timeval localtimeoutp,
int  timelimit,
int  sizelimit,
LDAPMessage **  res 
) [static]

Definition at line 964 of file search.c.

{
       int    err, msgid;

       /*
        * It is an error to pass in a zero'd timeval.
        */
       if ( localtimeoutp != NULL && localtimeoutp->tv_sec == 0 &&
           localtimeoutp->tv_usec == 0 ) {
              if ( ld != NULL ) {
                     LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
              }
              if ( res != NULL ) {
                     *res = NULL;
              }
                return( LDAP_PARAM_ERROR );
        }

       if (( err = nsldapi_search( ld, base, scope, filter, attrs, attrsonly,
           serverctrls, clientctrls, timelimit, sizelimit, &msgid ))
           != LDAP_SUCCESS ) {
              if ( res != NULL ) {
                     *res = NULL;
              }
              return( err );
       }

       if ( ldap_result( ld, msgid, 1, localtimeoutp, res ) == -1 ) {
              /*
               * Error.  ldap_result() sets *res to NULL for us.
               */
              return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
       }

       if ( LDAP_GET_LDERRNO( ld, NULL, NULL ) == LDAP_TIMEOUT ) {
              (void) ldap_abandon( ld, msgid );
              err = LDAP_TIMEOUT;
              LDAP_SET_LDERRNO( ld, err, NULL, NULL );
              if ( res != NULL ) {
                     *res = NULL;
              }
              return( err );
       }

       return( ldap_result2error( ld, *res, 0 ) );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int nsldapi_timeval2ldaplimit ( struct timeval timeoutp,
int  defaultvalue 
) [static]

Definition at line 252 of file search.c.

{
       int           timelimit;

       if ( NULL == timeoutp ) {
              timelimit = defaultvalue;
       } else if ( timeoutp->tv_sec > 0 ) {
              timelimit = timeoutp->tv_sec;
       } else if ( timeoutp->tv_usec > 0 ) {
              timelimit = 1;       /* minimum we can express in LDAP */
       } else {
              /*
               * both tv_sec and tv_usec are less than one (zero?) so
               * to maintain compatiblity with our "zero means no limit"
               * convention we pass no limit to the server.
               */
              timelimit = 0;       /* no limit */
       }

       return( timelimit );
}

Here is the caller graph for this function:

static char * put_complex_filter ( BerElement *  ber,
char *  str,
unsigned long  tag,
int  not 
) [static]

Definition at line 410 of file search.c.

{
       char   *next;

       /*
        * We have (x(filter)...) with str sitting on
        * the x.  We have to find the paren matching
        * the one before the x and put the intervening
        * filters by calling put_filter_list().
        */

       /* put explicit tag */
       if ( ber_printf( ber, "t{", tag ) == -1 )
              return( NULL );

       str++;
       if ( (next = find_right_paren( str )) == NULL )
              return( NULL );

       *next = '\0';
       if ( put_filter_list( ber, str ) == -1 )
              return( NULL );
       *next++ = ')';

       /* flush explicit tagged thang */
       if ( ber_printf( ber, "}" ) == -1 )
              return( NULL );

       return( next );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int put_filter ( BerElement *  ber,
char *  str 
) [static]

Definition at line 447 of file search.c.

{
       char   *next;
       int    parens, balance, escape;

       /*
        * A Filter looks like this:
        *      Filter ::= CHOICE {
        *              and             [0]     SET OF Filter,
        *              or              [1]     SET OF Filter,
        *              not             [2]     Filter,
        *              equalityMatch   [3]     AttributeValueAssertion,
        *              substrings      [4]     SubstringFilter,
        *              greaterOrEqual  [5]     AttributeValueAssertion,
        *              lessOrEqual     [6]     AttributeValueAssertion,
        *              present         [7]     AttributeType,,
        *              approxMatch     [8]     AttributeValueAssertion
        *      }
        *
        *      SubstringFilter ::= SEQUENCE {
        *              type               AttributeType,
        *              SEQUENCE OF CHOICE {
        *                      initial          [0] IA5String,
        *                      any              [1] IA5String,
        *                      final            [2] IA5String
        *              }
        *      }
        * Note: tags in a choice are always explicit
        */

       LDAPDebug( LDAP_DEBUG_TRACE, "put_filter \"%s\"\n", str, 0, 0 );

       parens = 0;
       while ( *str ) {
              switch ( *str ) {
              case '(':
                     str++;
                     parens++;
                     switch ( *str ) {
                     case '&':
                            LDAPDebug( LDAP_DEBUG_TRACE, "put_filter: AND\n",
                                0, 0, 0 );

                            if ( (str = put_complex_filter( ber, str,
                                LDAP_FILTER_AND, 0 )) == NULL )
                                   return( -1 );

                            parens--;
                            break;

                     case '|':
                            LDAPDebug( LDAP_DEBUG_TRACE, "put_filter: OR\n",
                                0, 0, 0 );

                            if ( (str = put_complex_filter( ber, str,
                                LDAP_FILTER_OR, 0 )) == NULL )
                                   return( -1 );

                            parens--;
                            break;

                     case '!':
                            LDAPDebug( LDAP_DEBUG_TRACE, "put_filter: NOT\n",
                                0, 0, 0 );

                            if ( (str = put_complex_filter( ber, str,
                                LDAP_FILTER_NOT, 1 )) == NULL )
                                   return( -1 );

                            parens--;
                            break;

                     default:
                            LDAPDebug( LDAP_DEBUG_TRACE,
                                "put_filter: simple\n", 0, 0, 0 );

                            balance = 1;
                            escape = 0;
                            next = str;
                            while ( *next && balance ) {
                                   if ( escape == 0 ) {
                                          if ( *next == '(' )
                                                 balance++;
                                          else if ( *next == ')' )
                                                 balance--;
                                   }
                                   if ( *next == '\\' && ! escape )
                                          escape = 1;
                                   else
                                          escape = 0;
                                   if ( balance )
                                          next++;
                            }
                            if ( balance != 0 )
                                   return( -1 );

                            *next = '\0';
                            if ( put_simple_filter( ber, str ) == -1 ) {
                                   return( -1 );
                            }
                            *next++ = ')';
                            str = next;
                            parens--;
                            break;
                     }
                     break;

              case ')':
                     LDAPDebug( LDAP_DEBUG_TRACE, "put_filter: end\n", 0, 0,
                         0 );
                     if ( ber_printf( ber, "]" ) == -1 )
                            return( -1 );
                     str++;
                     parens--;
                     break;

              case ' ':
                     str++;
                     break;

              default:      /* assume it's a simple type=value filter */
                     LDAPDebug( LDAP_DEBUG_TRACE, "put_filter: default\n", 0, 0,
                         0 );
                     next = strchr( str, '\0' );
                     if ( put_simple_filter( ber, str ) == -1 ) {
                            return( -1 );
                     }
                     str = next;
                     break;
              }
       }

       return( parens ? -1 : 0 );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int put_filter_list ( BerElement *  ber,
char *  str 
) [static]

Definition at line 588 of file search.c.

{
       char   *next;
       char   save;

       LDAPDebug( LDAP_DEBUG_TRACE, "put_filter_list \"%s\"\n", str, 0, 0 );

       while ( *str ) {
              while ( *str && isspace( *str ) )
                     str++;
              if ( *str == '\0' )
                     break;

              if ( (next = find_right_paren( str + 1 )) == NULL )
                     return( -1 );
              save = *++next;

              /* now we have "(filter)" with str pointing to it */
              *next = '\0';
              if ( put_filter( ber, str ) == -1 )
                     return( -1 );
              *next = save;

              str = next;
       }

       return( 0 );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int put_simple_filter ( BerElement *  ber,
char *  str 
) [static]

Definition at line 670 of file search.c.

{
       char          *s, *s2, *s3, filterop;
       char          *value;
       unsigned long ftype;
       int           rc, len;
       char          *oid;  /* for v3 extended filter */
       int           dnattr;       /* for v3 extended filter */

       LDAPDebug( LDAP_DEBUG_TRACE, "put_simple_filter \"%s\"\n", str, 0, 0 );

       rc = -1;      /* pessimistic */

       if (( str = nsldapi_strdup( str )) == NULL ) {
              return( rc );
       }

       if ( (s = strchr( str, '=' )) == NULL ) {
              goto free_and_return;
       }
       value = s + 1;
       *s-- = '\0';
       filterop = *s;
       if ( filterop == '<' || filterop == '>' || filterop == '~' ||
           filterop == ':' ) {
              *s = '\0';
       }

       if ( ! is_valid_attr( str ) ) {
              goto free_and_return;
       }

       switch ( filterop ) {
       case '<':
              ftype = LDAP_FILTER_LE;
              break;
       case '>':
              ftype = LDAP_FILTER_GE;
              break;
       case '~':
              ftype = LDAP_FILTER_APPROX;
              break;
       case ':':     /* extended filter - v3 only */
              /*
               * extended filter looks like this:
               *
               *     [type][':dn'][':'oid]':='value
               *
               * where one of type or :oid is required.
               *
               */
              ftype = LDAP_FILTER_EXTENDED;
              s2 = s3 = NULL;
              if ( (s2 = strrchr( str, ':' )) == NULL ) {
                     goto free_and_return;
              }
              if ( strcasecmp( s2, ":dn" ) == 0 ) {
                     oid = NULL;
                     dnattr = 1;
                     *s2 = '\0';
              } else {
                     oid = s2 + 1;
                     dnattr = 0;
                     *s2 = '\0';
                     if ( (s3 = strrchr( str, ':' )) != NULL ) {
                            if ( strcasecmp( s3, ":dn" ) == 0 ) {
                                   dnattr = 1;
                            } else {
                                   goto free_and_return;
                            }
                            *s3 = '\0';
                     }
              }
              if ( (rc = ber_printf( ber, "t{", ftype )) == -1 ) {
                     goto free_and_return;
              }
              if ( oid != NULL ) {
                     if ( (rc = ber_printf( ber, "ts", LDAP_TAG_MRA_OID,
                         oid )) == -1 ) {
                            goto free_and_return;
                     }
              }
              if ( *str != '\0' ) {
                     if ( (rc = ber_printf( ber, "ts",
                         LDAP_TAG_MRA_TYPE, str )) == -1 ) {
                            goto free_and_return;
                     }
              }
              if (( len = unescape_filterval( value )) < 0 ||
                  ( rc = ber_printf( ber, "totb}", LDAP_TAG_MRA_VALUE,
                  value, len, LDAP_TAG_MRA_DNATTRS, dnattr )) == -1 ) {
                     goto free_and_return;
              }
              rc = 0;
              goto free_and_return;
              break;
       default:
              if ( find_star( value ) == NULL ) {
                     ftype = LDAP_FILTER_EQUALITY;
              } else if ( strcmp( value, "*" ) == 0 ) {
                     ftype = LDAP_FILTER_PRESENT;
              } else {
                     rc = put_substring_filter( ber, str, value );
                     goto free_and_return;
              }
              break;
       }

       if ( ftype == LDAP_FILTER_PRESENT ) {
              rc = ber_printf( ber, "ts", ftype, str );
       } else if (( len = unescape_filterval( value )) >= 0 ) {
              rc = ber_printf( ber, "t{so}", ftype, str, value, len );
       }
       if ( rc != -1 ) {
              rc = 0;
       }

free_and_return:
       NSLDAPI_FREE( str );
       return( rc );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int put_substring_filter ( BerElement *  ber,
char *  type,
char *  str 
) [static]

Definition at line 867 of file search.c.

{
       char          *nextstar, gotstar = 0;
       unsigned long ftype;
       int           len;

       LDAPDebug( LDAP_DEBUG_TRACE, "put_substring_filter \"%s=%s\"\n", type,
           val, 0 );

       if ( ber_printf( ber, "t{s{", LDAP_FILTER_SUBSTRINGS, type ) == -1 ) {
              return( -1 );
       }

       for ( ; val != NULL; val = nextstar ) {
              if ( (nextstar = find_star( val )) != NULL ) {
                     *nextstar++ = '\0';
              }

              if ( gotstar == 0 ) {
                     ftype = LDAP_SUBSTRING_INITIAL;
              } else if ( nextstar == NULL ) {
                     ftype = LDAP_SUBSTRING_FINAL;
              } else {
                     ftype = LDAP_SUBSTRING_ANY;
              }
              if ( *val != '\0' ) {
                     if (( len = unescape_filterval( val )) < 0 ||
                         ber_printf( ber, "to", ftype, val, len ) == -1 ) {
                            return( -1 );
                     }
              }

              gotstar = 1;
       }

       if ( ber_printf( ber, "}}" ) == -1 ) {
              return( -1 );
       }

       return( 0 );
}

Here is the call graph for this function:

Here is the caller graph for this function:

static int unescape_filterval ( char *  str) [static]

Definition at line 802 of file search.c.

{
       int    escape, firstdigit, ival; 
       char   *s, *d;

       escape = 0;
       for ( s = d = val; *s; s++ ) {
              if ( escape ) {
                     /*
                      * first try LDAPv3 escape (hexadecimal) sequence
                      */
                     if (( ival = hexchar2int( *s )) < 0 ) {
                            if ( firstdigit ) {
                                   /*
                                    * LDAPv2 (RFC1960) escape sequence
                                    */
                                   *d++ = *s;
                                   escape = 0;
                            } else {
                                   return(-1);
                            }
                     }
                     if ( firstdigit ) {
                         *d = ( ival<<4 );
                         firstdigit = 0;
                     } else {
                         *d++ |= ival;
                         escape = 0;
                     }

              } else if ( *s != '\\' ) {
                     *d++ = *s;
                     escape = 0;

              } else {
                     escape = 1;
                     firstdigit = 1;
              }
       }

       return( d - val );
}

Here is the call graph for this function:

Here is the caller graph for this function: