]> git.sur5r.net Git - openldap/blobdiff - libraries/libldap/search.c
Merge remote-tracking branch 'origin/mdb.master'
[openldap] / libraries / libldap / search.c
index 2f27eddd6eff8fce4abd505cc02577e7198f082c..b90c1663edbe7b0c90fe454c8ade192196e82315 100644 (file)
@@ -1,7 +1,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2007 The OpenLDAP Foundation.
+ * Copyright 1998-2012 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -65,6 +65,25 @@ ldap_search_ext(
        struct timeval *timeout,
        int sizelimit,
        int *msgidp )
+{
+       return ldap_pvt_search( ld, base, scope, filter, attrs,
+               attrsonly, sctrls, cctrls, timeout, sizelimit, -1, msgidp );
+}
+
+int
+ldap_pvt_search(
+       LDAP *ld,
+       LDAP_CONST char *base,
+       int scope,
+       LDAP_CONST char *filter,
+       char **attrs,
+       int attrsonly,
+       LDAPControl **sctrls,
+       LDAPControl **cctrls,
+       struct timeval *timeout,
+       int sizelimit,
+       int deref,
+       int *msgidp )
 {
        int rc;
        BerElement      *ber;
@@ -98,7 +117,7 @@ ldap_search_ext(
        }
 
        ber = ldap_build_search_req( ld, base, scope, filter, attrs,
-           attrsonly, sctrls, cctrls, timelimit, sizelimit, &id ); 
+           attrsonly, sctrls, cctrls, timelimit, sizelimit, deref, &id ); 
 
        if ( ber == NULL ) {
                return ld->ld_errno;
@@ -127,12 +146,33 @@ ldap_search_ext_s(
        struct timeval *timeout,
        int sizelimit,
        LDAPMessage **res )
+{
+       return ldap_pvt_search_s( ld, base, scope, filter, attrs,
+               attrsonly, sctrls, cctrls, timeout, sizelimit, -1, res );
+}
+
+int
+ldap_pvt_search_s(
+       LDAP *ld,
+       LDAP_CONST char *base,
+       int scope,
+       LDAP_CONST char *filter,
+       char **attrs,
+       int attrsonly,
+       LDAPControl **sctrls,
+       LDAPControl **cctrls,
+       struct timeval *timeout,
+       int sizelimit,
+       int deref,
+       LDAPMessage **res )
 {
        int rc;
        int     msgid;
 
-       rc = ldap_search_ext( ld, base, scope, filter, attrs, attrsonly,
-               sctrls, cctrls, timeout, sizelimit, &msgid );
+    *res = NULL;
+
+       rc = ldap_pvt_search( ld, base, scope, filter, attrs, attrsonly,
+               sctrls, cctrls, timeout, sizelimit, deref, &msgid );
 
        if ( rc != LDAP_SUCCESS ) {
                return( rc );
@@ -142,6 +182,11 @@ ldap_search_ext_s(
 
        if( rc <= 0 ) {
                /* error(-1) or timeout(0) */
+               if ( ld->ld_errno == LDAP_TIMEOUT ) {
+                       /* cleanup request */
+                       (void) ldap_abandon( ld, msgid );
+                       ld->ld_errno = LDAP_TIMEOUT;
+               }
                return( ld->ld_errno );
        }
 
@@ -188,7 +233,7 @@ ldap_search(
        assert( LDAP_VALID( ld ) );
 
        ber = ldap_build_search_req( ld, base, scope, filter, attrs,
-           attrsonly, NULL, NULL, -1, -1, &id ); 
+           attrsonly, NULL, NULL, -1, -1, -1, &id ); 
 
        if ( ber == NULL ) {
                return( -1 );
@@ -212,6 +257,7 @@ ldap_build_search_req(
        LDAPControl **cctrls,
        ber_int_t timelimit,
        ber_int_t sizelimit,
+       ber_int_t deref,
        ber_int_t *idp)
 {
        BerElement      *ber;
@@ -261,13 +307,14 @@ ldap_build_search_req(
        if ( LDAP_IS_UDP(ld) ) {
                struct sockaddr sa = {0};
                /* dummy, filled with ldo_peer in request.c */
-           err = ber_write( ber, &sa, sizeof( sa ), 0 );
+           err = ber_write( ber, (char *) &sa, sizeof( sa ), 0 );
        }
        if ( LDAP_IS_UDP(ld) && ld->ld_options.ldo_version == LDAP_VERSION2) {
            char *dn = ld->ld_options.ldo_cldapdn;
            if (!dn) dn = "";
            err = ber_printf( ber, "{ist{seeiib", *idp, dn,
-               LDAP_REQ_SEARCH, base, (ber_int_t) scope, ld->ld_deref,
+               LDAP_REQ_SEARCH, base, (ber_int_t) scope,
+               (deref < 0) ? ld->ld_deref : deref,
                (sizelimit < 0) ? ld->ld_sizelimit : sizelimit,
                (timelimit < 0) ? ld->ld_timelimit : timelimit,
                attrsonly );
@@ -275,7 +322,8 @@ ldap_build_search_req(
 #endif
        {
            err = ber_printf( ber, "{it{seeiib", *idp,
-               LDAP_REQ_SEARCH, base, (ber_int_t) scope, ld->ld_deref,
+               LDAP_REQ_SEARCH, base, (ber_int_t) scope,
+               (deref < 0) ? ld->ld_deref : deref,
                (sizelimit < 0) ? ld->ld_sizelimit : sizelimit,
                (timelimit < 0) ? ld->ld_timelimit : timelimit,
                attrsonly );
@@ -301,27 +349,25 @@ ldap_build_search_req(
 
 #ifdef LDAP_DEBUG
        if ( ldap_debug & LDAP_DEBUG_ARGS ) {
-               char    buf[ BUFSIZ ] = { ' ', '*', '\0' };
+               char    buf[ BUFSIZ ], *ptr = " *";
 
                if ( attrs != NULL ) {
-                       char    *ptr;
-                       int     i;
-
-                       for ( ptr = buf, i = 0;
-                               attrs[ i ] != NULL && ptr < &buf[ sizeof( buf ) ];
-                               i++ )
-                       {
-                               ptr += snprintf( ptr, sizeof( buf ) - ( ptr - buf ),
-                                       " %s", attrs[ i ] );
+                       int     i, len, rest = sizeof( buf );
+
+                       for ( i = 0; attrs[ i ] != NULL && rest > 0; i++ ) {
+                               ptr = &buf[ sizeof( buf ) - rest ];
+                               len = snprintf( ptr, rest, " %s", attrs[ i ] );
+                               rest -= (len >= 0 ? len : (int) sizeof( buf ));
                        }
 
-                       if ( ptr >= &buf[ sizeof( buf ) ] ) {
+                       if ( rest <= 0 ) {
                                AC_MEMCPY( &buf[ sizeof( buf ) - STRLENOF( "...(truncated)" ) - 1 ],
                                        "...(truncated)", STRLENOF( "...(truncated)" ) + 1 );
                        } 
+                       ptr = buf;
                }
 
-               Debug( LDAP_DEBUG_ARGS, "ldap_build_search_req ATTRS:%s\n", buf, 0, 0 );
+               Debug( LDAP_DEBUG_ARGS, "ldap_build_search_req ATTRS:%s\n", ptr, 0,0 );
        }
 #endif /* LDAP_DEBUG */
 
@@ -354,11 +400,13 @@ ldap_search_st(
 {
        int     msgid;
 
+    *res = NULL;
+
        if ( (msgid = ldap_search( ld, base, scope, filter, attrs, attrsonly ))
            == -1 )
                return( ld->ld_errno );
 
-       if ( ldap_result( ld, msgid, LDAP_MSG_ALL, timeout, res ) == -1 )
+       if ( ldap_result( ld, msgid, LDAP_MSG_ALL, timeout, res ) == -1 || !*res )
                return( ld->ld_errno );
 
        if ( ld->ld_errno == LDAP_TIMEOUT ) {
@@ -382,11 +430,13 @@ ldap_search_s(
 {
        int     msgid;
 
+    *res = NULL;
+
        if ( (msgid = ldap_search( ld, base, scope, filter, attrs, attrsonly ))
            == -1 )
                return( ld->ld_errno );
 
-       if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, res ) == -1 || !res )
+       if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, res ) == -1 || !*res )
                return( ld->ld_errno );
 
        return( ldap_result2error( ld, *res, 0 ) );