]> git.sur5r.net Git - openldap/commitdiff
Sync with HEAD
authorKurt Zeilenga <kurt@openldap.org>
Fri, 30 Aug 2002 03:06:17 +0000 (03:06 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Fri, 30 Aug 2002 03:06:17 +0000 (03:06 +0000)
30 files changed:
build/main.dsw
doc/devel/todo
libraries/liblber/sockbuf.c
libraries/libldap/abandon.c
libraries/libldap/cyrus.c
libraries/libldap/filter.c
libraries/libldap/ldap-int.h
libraries/libldap/request.c
libraries/libldap/result.c
libraries/liblutil/liblutil.dsp
libraries/librewrite/rewrite-int.h
libraries/librewrite/session.c
servers/slapd/back-bdb/group.c
servers/slapd/back-bdb/operational.c
servers/slapd/back-bdb/proto-bdb.h
servers/slapd/back-bdb/search.c
servers/slapd/back-ldbm/search.c
servers/slapd/backend.c
servers/slapd/dn.c
servers/slapd/filter.c
servers/slapd/filterentry.c
servers/slapd/init.c
servers/slapd/matchedValues.c
servers/slapd/mra.c
servers/slapd/operational.c
servers/slapd/proto-slap.h
servers/slapd/result.c
servers/slapd/schema.c
servers/slapd/search.c
servers/slapd/slap.h

index f198bf3c05e979c4aae55079885084db4c7e5538..b5d01bfcb82859ffc0720adcaba8c75d9d9faf97 100644 (file)
@@ -123,9 +123,6 @@ Package=<4>
     Project_Dep_Name testavl
     End Project Dependency
     Begin Project Dependency
-    Project_Dep_Name ud
-    End Project Dependency
-    Begin Project Dependency
     Project_Dep_Name slapcat
     End Project Dependency
     Begin Project Dependency
@@ -155,6 +152,9 @@ Package=<4>
     Begin Project Dependency
     Project_Dep_Name ftest
     End Project Dependency
+    Begin Project Dependency
+    Project_Dep_Name ldapwhoami
+    End Project Dependency
 }}}
 
 ###############################################################################
@@ -354,6 +354,27 @@ Package=<4>
 
 ###############################################################################
 
+Project: "ldapwhoami"=..\clients\tools\ldapwhoami.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+    Begin Project Dependency
+    Project_Dep_Name liblber
+    End Project Dependency
+    Begin Project Dependency
+    Project_Dep_Name libldap
+    End Project Dependency
+    Begin Project Dependency
+    Project_Dep_Name liblutil
+    End Project Dependency
+}}}
+
+###############################################################################
+
 Project: "libavl"=..\libraries\libavl\libavl.dsp - Package Owner=<4>
 
 Package=<5>
@@ -777,27 +798,6 @@ Package=<4>
 
 ###############################################################################
 
-Project: "ud"=..\clients\ud\ud.dsp - Package Owner=<4>
-
-Package=<5>
-{{{
-}}}
-
-Package=<4>
-{{{
-    Begin Project Dependency
-    Project_Dep_Name libldap
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name liblber
-    End Project Dependency
-    Begin Project Dependency
-    Project_Dep_Name liblutil
-    End Project Dependency
-}}}
-
-###############################################################################
-
 Global:
 
 Package=<5>
index 5a4d74df65c0f729ca6443e526c4b81c1fef30ec..a2cd3978dd5b1966b5c480dae12c7e0bbc3c1de6 100644 (file)
@@ -31,7 +31,7 @@ OpenLDAP 2.x Projects
 Large projects
 --------------
 Redesign slapd memory allocation fault handling
-Perform a security audit (and fix any hole found)
+Update to latest autoconf and friends
 Implement localization
 
 
@@ -41,16 +41,14 @@ Implement LDAP Transactions extension
 Implement Proxy Authorization Control extension
 Implement LDAP Cancel extension
 Implement authPassword (RFC 3112)
-Update to latest autoconf and friends
+Populate matchingRuleUse attribute in the subschema
 
 
 Small projects
 --------------
 Add dumpasn1 logging support
 Add LDIFv1 control support
-Populate matchingRuleUse attribute in the subschema
 Implement -V version options
-Add No-Op Control support to client tools (e.g. ldapsearch(1))
 Add tests to test suite (ACI, moddn, manageDSAit, etc.)
 Recode linked-list structs to use <ldap_queue.h> macros
 Create ldapbind(1) to support bind operations
index ae5c07c8c1e4c28e1fba4bf370de5b3a203b185f..7fa6e85321340b19feb8a4601328e050dc1c52b7 100644 (file)
@@ -313,11 +313,6 @@ ber_pvt_sb_do_write( Sockbuf_IO_Desc *sbiod, Sockbuf_Buf *buf_out )
                buf_out->buf_end = buf_out->buf_ptr = 0;
        }
 
-       if ( (ber_len_t)ret < to_go ) {
-               /* not enough data, so pretend no data was sent. */
-               return -1;
-       }
-
        return ret;
 }
 
index a88a5865b5a89ab8813b2c49ababf82bd4954ee3..04397a275edb9f28d8e04a68c288ca75adfc5024 100644 (file)
@@ -224,7 +224,7 @@ do_abandon(
        }
 
        if ( lr != NULL ) {
-               if ( sendabandon ) {
+               if ( sendabandon || lr->lr_status == LDAP_REQST_WRITING ) {
                        ldap_free_connection( ld, lr->lr_conn, 0, 1 );
                }
                if ( origid == msgid ) {
index 1e6e9f42cf31f5d322753bd82766dc7f09b196d9..85b248de6715f102a7260043180e6186881bca82 100644 (file)
@@ -331,8 +331,13 @@ sb_sasl_write( Sockbuf_IO_Desc *sbiod, void *buf, ber_len_t len)
        /* Are there anything left in the buffer? */
        if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) {
                ret = ber_pvt_sb_do_write( sbiod, &p->buf_out );
-               if ( ret <= 0 )
+               if ( ret < 0 )
                        return ret;
+               /* Still have something left?? */
+               if ( p->buf_out.buf_ptr != p->buf_out.buf_end ) {
+                       errno = EWOULDBLOCK;
+                       return 0;
+               }
        }
 
        /* now encode the next packet. */
@@ -1088,6 +1093,7 @@ ldap_int_sasl_set_option( LDAP *ld, int option, void *arg )
 }
 
 #ifdef LDAP_R_COMPILE
+#define LDAP_DEBUG_R_SASL
 void *ldap_pvt_sasl_mutex_new(void)
 {
        ldap_pvt_thread_mutex_t *mutex;
@@ -1098,23 +1104,47 @@ void *ldap_pvt_sasl_mutex_new(void)
        if ( ldap_pvt_thread_mutex_init( mutex ) == 0 ) {
                return mutex;
        }
+#ifndef LDAP_DEBUG_R_SASL
+       assert( 0 );
+#endif /* !LDAP_DEBUG_R_SASL */
        return NULL;
 }
 
 int ldap_pvt_sasl_mutex_lock(void *mutex)
 {
+#ifdef LDAP_DEBUG_R_SASL
+       if ( mutex == NULL ) {
+               return SASL_OK;
+       }
+#else /* !LDAP_DEBUG_R_SASL */
+       assert( mutex );
+#endif /* !LDAP_DEBUG_R_SASL */
        return ldap_pvt_thread_mutex_lock( (ldap_pvt_thread_mutex_t *)mutex )
                ? SASL_FAIL : SASL_OK;
 }
 
 int ldap_pvt_sasl_mutex_unlock(void *mutex)
 {
+#ifdef LDAP_DEBUG_R_SASL
+       if ( mutex == NULL ) {
+               return SASL_OK;
+       }
+#else /* !LDAP_DEBUG_R_SASL */
+       assert( mutex );
+#endif /* !LDAP_DEBUG_R_SASL */
        return ldap_pvt_thread_mutex_unlock( (ldap_pvt_thread_mutex_t *)mutex )
                ? SASL_FAIL : SASL_OK;
 }
 
 void ldap_pvt_sasl_mutex_dispose(void *mutex)
 {
+#ifdef LDAP_DEBUG_R_SASL
+       if ( mutex == NULL ) {
+               return;
+       }
+#else /* !LDAP_DEBUG_R_SASL */
+       assert( mutex );
+#endif /* !LDAP_DEBUG_R_SASL */
        (void) ldap_pvt_thread_mutex_destroy( (ldap_pvt_thread_mutex_t *)mutex );
        LDAP_FREE( mutex );
 }
index 259c9a459089dba1a482147aa463f1c82ea06ab7..2ff345dd6d2c75fe87b0bd160348d3c3c23ec588 100644 (file)
@@ -837,8 +837,7 @@ put_vrFilter( BerElement *ber, const char *str_in )
         */
 
 #ifdef NEW_LOGGING
-       LDAP_LOG ( FILTER, ARGS, "ldap_pvt_put_vrFilter: \"%s\"\n", 
-               str_in, 0, 0 );
+       LDAP_LOG ( FILTER, ARGS, "put_vrFilter: \"%s\"\n", str_in, 0, 0 );
 #else
        Debug( LDAP_DEBUG_TRACE, "put_vrFilter: \"%s\"\n", str_in, 0, 0 );
 #endif
@@ -933,9 +932,9 @@ put_vrFilter( BerElement *ber, const char *str_in )
 
                case /*'('*/ ')':
 #ifdef NEW_LOGGING
-                       LDAP_LOG ( FILTER, DETAIL1, "ldap_pvt_put_filter: end\n", 0, 0, 0 );
+                       LDAP_LOG ( FILTER, DETAIL1, "put_vrFilter: end\n", 0, 0, 0 );
 #else
-                       Debug( LDAP_DEBUG_TRACE, "put_filter: end\n",
+                       Debug( LDAP_DEBUG_TRACE, "put_vrFilter: end\n",
                                0, 0, 0 );
 #endif
                        if ( ber_printf( ber, /*"["*/ "]" ) == -1 ) {
@@ -952,10 +951,10 @@ put_vrFilter( BerElement *ber, const char *str_in )
 
                default:        /* assume it's a simple type=value filter */
 #ifdef NEW_LOGGING
-                       LDAP_LOG ( FILTER, DETAIL1, "ldap_pvt_put_filter: default\n", 
+                       LDAP_LOG ( FILTER, DETAIL1, "put_vrFilter: default\n", 
                                0, 0, 0 );
 #else
-                       Debug( LDAP_DEBUG_TRACE, "put_filter: default\n",
+                       Debug( LDAP_DEBUG_TRACE, "put_vrFilter: default\n",
                                0, 0, 0 );
 #endif
                        next = strchr( str, '\0' );
index 4ad20dd9f4c813a6172fbc9e940e42b441803d9d..5e44c3287dd399130b723ddcab8b0cd1edd0995a 100644 (file)
@@ -467,6 +467,7 @@ LDAP_F (int) ldap_chase_referrals( LDAP *ld, LDAPRequest *lr,
 LDAP_F (int) ldap_chase_v3referrals( LDAP *ld, LDAPRequest *lr,
        char **refs, int sref, char **referralsp, int *hadrefp );
 LDAP_F (int) ldap_append_referral( LDAP *ld, char **referralsp, char *s );
+LDAP_F (int) ldap_int_flush_request( LDAP *ld, LDAPRequest *lr );
 
 /*
  * in result.c:
index b9ecd9b3bd3a8ca7b50962b4fabfc288b1518e95..0ffd592b2187ecf700a2459bb079a813db059793 100644 (file)
@@ -137,6 +137,39 @@ ldap_send_initial_request(
 }
 
 
+int
+ldap_int_flush_request(
+       LDAP *ld,
+       LDAPRequest *lr
+)
+{
+       LDAPConn *lc = lr->lr_conn;
+
+       if ( ber_flush( lc->lconn_sb, lr->lr_ber, 0 ) != 0 ) {
+               if ( errno == EWOULDBLOCK ) {
+                       /* need to continue write later */
+                       lr->lr_status = LDAP_REQST_WRITING;
+                       ldap_mark_select_write( ld, lc->lconn_sb );
+                       ld->ld_errno = LDAP_BUSY;
+                       return -2;
+               } else {
+                       ld->ld_errno = LDAP_SERVER_DOWN;
+                       ldap_free_request( ld, lr );
+                       ldap_free_connection( ld, lc, 0, 0 );
+                       return( -1 );
+               }
+       } else {
+               if ( lr->lr_parent == NULL ) {
+                       lr->lr_ber->ber_end = lr->lr_ber->ber_ptr;
+                       lr->lr_ber->ber_ptr = lr->lr_ber->ber_buf;
+               }
+               lr->lr_status = LDAP_REQST_INPROGRESS;
+
+               /* sent -- waiting for a response */
+               ldap_mark_select_read( ld, lc->lconn_sb );
+       }
+       return 0;
+}
 
 int
 ldap_send_server_request(
@@ -189,6 +222,18 @@ ldap_send_server_request(
        }
 
        use_connection( ld, lc );
+
+       /* If we still have an incomplete write, try to finish it before
+        * dealing with the new request. If we don't finish here, return
+        * LDAP_BUSY and let the caller retry later. We only allow a single
+        * request to be in WRITING state.
+        */
+       if ( ld->ld_requests &&
+               ld->ld_requests->lr_status == LDAP_REQST_WRITING &&
+               ldap_int_flush_request( ld, ld->ld_requests ) < 0 ) {
+               return -1;
+       }
+
        if (( lr = (LDAPRequest *)LDAP_CALLOC( 1, sizeof( LDAPRequest ))) ==
            NULL ) {
                ld->ld_errno = LDAP_NO_MEMORY;
@@ -225,30 +270,8 @@ ldap_send_server_request(
        ld->ld_requests = lr;
        lr->lr_prev = NULL;
 
-       if ( ber_flush( lc->lconn_sb, ber, 0 ) != 0 ) {
-#ifdef notyet
-               if ( errno == EWOULDBLOCK ) {
-                       /* need to continue write later */
-                       lr->lr_status = LDAP_REQST_WRITING;
-                       ldap_mark_select_write( ld, lc->lconn_sb );
-               } else {
-#else /* notyet */
-                       ld->ld_errno = LDAP_SERVER_DOWN;
-                       ldap_free_request( ld, lr );
-                       ldap_free_connection( ld, lc, 0, 0 );
-                       return( -1 );
-#endif /* notyet */
-#ifdef notyet
-               }
-#endif /* notyet */
-       } else {
-               if ( parentreq == NULL ) {
-                       ber->ber_end = ber->ber_ptr;
-                       ber->ber_ptr = ber->ber_buf;
-               }
-
-               /* sent -- waiting for a response */
-               ldap_mark_select_read( ld, lc->lconn_sb );
+       if ( ldap_int_flush_request( ld, lr ) == -1 ) {
+               return -1;
        }
 
        ld->ld_errno = LDAP_SUCCESS;
index 1a7bcec9efff41fa9bd692f91cab037538a24cea..2f82aa94227ed6a061b3ace32330464be765d5bb 100644 (file)
@@ -334,6 +334,12 @@ wait4msg(
                                    rc = -2;    /* select interrupted: loop */
                            } else {
                                    rc = -2;
+                                   if ( ld->ld_requests &&
+                                               ld->ld_requests->lr_status == LDAP_REQST_WRITING &&
+                                               ldap_is_write_ready( ld,
+                                                       ld->ld_requests->lr_conn->lconn_sb ) ) {
+                                               ldap_int_flush_request( ld, ld->ld_requests );
+                                       }
                                    for ( lc = ld->ld_conns; rc == -2 && lc != NULL;
                                        lc = nextlc ) {
                                            nextlc = lc->lconn_next;
index 436a6981bf7aeef502b0301375bfec07d163a915..013a800c12031bd34f407fa32bcbc4cfb2ace6d4 100644 (file)
@@ -204,6 +204,10 @@ SOURCE=.\ntservice.c
 # End Source File
 # Begin Source File
 
+SOURCE=.\passfile.c
+# End Source File
+# Begin Source File
+
 SOURCE=.\passwd.c
 # End Source File
 # Begin Source File
index 28e47e46c64832fbcc44273f87235df6071c2112..b8bc161a54d34cec1f727baad1c72fc43f7b1253 100644 (file)
@@ -243,7 +243,9 @@ struct rewrite_session {
        Avlnode                        *ls_vars;
 #ifdef USE_REWRITE_LDAP_PVT_THREADS
        ldap_pvt_thread_rdwr_t          ls_vars_mutex;
+       ldap_pvt_thread_mutex_t         ls_mutex;
 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
+       int                             ls_count;
 };
 
 /*
index fa5c78354a682211ca80e85084c50c3ed3e2d5cf..1e93ecd777fa8c4527c95caa3fd3c4cb2986008a 100644 (file)
@@ -44,7 +44,7 @@ rewrite_cookie_cmp(
        assert( s2 != NULL );
        assert( s1->ls_cookie != NULL );
        assert( s2->ls_cookie != NULL );
-       
+
         return ( ( s1->ls_cookie < s2->ls_cookie ) ? -1 :
                        ( ( s1->ls_cookie > s2->ls_cookie ) ? 1 : 0 ) );
 }
@@ -68,6 +68,8 @@ rewrite_cookie_dup(
        assert( s1->ls_cookie != NULL );
        assert( s2->ls_cookie != NULL );
        
+       assert( s1->ls_cookie != s2->ls_cookie );
+       
         return ( ( s1->ls_cookie == s2->ls_cookie ) ? -1 : 0 );
 }
 
@@ -80,24 +82,44 @@ rewrite_session_init(
                const void *cookie
 )
 {
-       struct rewrite_session *session;
-       int rc;
+       struct rewrite_session  *session, tmp;
+       int                     rc;
 
        assert( info != NULL );
        assert( cookie != NULL );
-       
+
+#ifdef USE_REWRITE_LDAP_PVT_THREADS
+       ldap_pvt_thread_rdwr_wlock( &info->li_cookies_mutex );
+#endif /* USE_REWRITE_LDAP_PVT_THREADS */
+
+       tmp.ls_cookie = ( void * )cookie;
+       session = ( struct rewrite_session * )avl_find( info->li_cookies, 
+                       ( caddr_t )&tmp, rewrite_cookie_cmp );
+       if ( session ) {
+               session->ls_count++;
+#ifdef USE_REWRITE_LDAP_PVT_THREADS
+               ldap_pvt_thread_rdwr_wunlock( &info->li_cookies_mutex );
+#endif /* USE_REWRITE_LDAP_PVT_THREADS */
+               return session;
+       }
+               
        session = calloc( sizeof( struct rewrite_session ), 1 );
        if ( session == NULL ) {
                return NULL;
        }
        session->ls_cookie = ( void * )cookie;
+       session->ls_count = 1;
        
 #ifdef USE_REWRITE_LDAP_PVT_THREADS
+       if ( ldap_pvt_thread_mutex_init( &session->ls_mutex ) ) {
+               free( session );
+               return NULL;
+       }
        if ( ldap_pvt_thread_rdwr_init( &session->ls_vars_mutex ) ) {
+               ldap_pvt_thread_mutex_destroy( &session->ls_mutex );
                free( session );
                return NULL;
        }
-       ldap_pvt_thread_rdwr_wlock( &info->li_cookies_mutex );
 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
 
        rc = avl_insert( &info->li_cookies, ( caddr_t )session,
@@ -109,6 +131,11 @@ rewrite_session_init(
 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
        
        if ( rc != 0 ) {
+#ifdef USE_REWRITE_LDAP_PVT_THREADS
+               ldap_pvt_thread_rdwr_destroy( &session->ls_vars_mutex );
+               ldap_pvt_thread_mutex_destroy( &session->ls_mutex );
+#endif /* USE_REWRITE_LDAP_PVT_THREADS */
+
                free( session );
                return NULL;
        }
@@ -137,11 +164,26 @@ rewrite_session_find(
        session = ( struct rewrite_session * )avl_find( info->li_cookies,
                        ( caddr_t )&tmp, rewrite_cookie_cmp );
 #ifdef USE_REWRITE_LDAP_PVT_THREADS
+       if ( session ) {
+               ldap_pvt_thread_mutex_lock( &session->ls_mutex );
+       }
        ldap_pvt_thread_rdwr_runlock( &info->li_cookies_mutex );
 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
 
        return session;
-               
+}
+
+/*
+ * Returns a session
+ */
+void
+rewrite_session_return(
+               struct rewrite_info *info,
+               struct rewrite_session *session
+)
+{
+       assert( session );
+       ldap_pvt_thread_mutex_unlock( &session->ls_mutex );
 }
 
 /*
@@ -184,6 +226,7 @@ rewrite_session_var_set(
 #ifdef USE_REWRITE_LDAP_PVT_THREADS
                        ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex );
 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
+                       rewrite_session_return( info, session );
                        return REWRITE_ERR;
                }
        }       
@@ -192,6 +235,8 @@ rewrite_session_var_set(
        ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex );
 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
 
+       rewrite_session_return( info, session );
+
        return REWRITE_SUCCESS;
 }
 
@@ -236,7 +281,9 @@ rewrite_session_var_get(
 #ifdef USE_REWRITE_LDAP_PVT_THREADS
                ldap_pvt_thread_rdwr_runlock( &session->ls_vars_mutex );
 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
-               
+
+               rewrite_session_return( info, session );
+
                return REWRITE_ERR;
        } else {
                value->bv_val = strdup( var->lv_value.bv_val );
@@ -246,6 +293,8 @@ rewrite_session_var_get(
 #ifdef USE_REWRITE_LDAP_PVT_THREADS
         ldap_pvt_thread_rdwr_runlock( &session->ls_vars_mutex );
 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
+
+       rewrite_session_return( info, session );
        
        return REWRITE_SUCCESS;
 }
@@ -269,12 +318,20 @@ rewrite_session_delete(
        session = rewrite_session_find( info, cookie );
 
        if ( session != NULL ) {
+               if ( --session->ls_count > 0 ) {
+                       rewrite_session_return( info, session );
+                       return REWRITE_SUCCESS;
+               }
+
 #ifdef USE_REWRITE_LDAP_PVT_THREADS
                ldap_pvt_thread_rdwr_wlock( &session->ls_vars_mutex );
 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
+
                rewrite_var_delete( session->ls_vars );
+
 #ifdef USE_REWRITE_LDAP_PVT_THREADS
-               ldap_pvt_thread_rdwr_wunlock( &session->ls_vars_mutex );
+               ldap_pvt_thread_rdwr_destroy( &session->ls_vars_mutex );
+               ldap_pvt_thread_mutex_destroy( &session->ls_mutex );
 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
        }
 
@@ -289,6 +346,8 @@ rewrite_session_delete(
         * There is nothing to delete in the return value
         */
        avl_delete( &info->li_cookies, ( caddr_t )&tmp, rewrite_cookie_cmp );
+       free( session );
+
 #ifdef USE_REWRITE_LDAP_PVT_THREADS
        ldap_pvt_thread_rdwr_wunlock( &info->li_cookies_mutex );
 #endif /* USE_REWRITE_LDAP_PVT_THREADS */
@@ -318,6 +377,10 @@ rewrite_session_destroy(
        
        count = avl_free( info->li_cookies, NULL );
        info->li_cookies = NULL;
+
+       fprintf( stderr, "count = %d; num_cookies = %d\n", 
+                       count, info->li_num_cookies );
+       
        assert( count == info->li_num_cookies );
        info->li_num_cookies = 0;
 
index d4fb4de09e0bdc23912ab7de3faaf56a2e21600c..f774bb18310533ae6943c780b95844c3c312ef86 100644 (file)
@@ -40,7 +40,6 @@ bdb_group(
        int     rc = 1;
        Attribute *attr;
 
-       AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass;
        const char *group_oc_name = NULL;
        const char *group_at_name = group_at->ad_cname.bv_val;
 
index cfcf17cdb3d02ec46f62cdd2c1354923b7ffca93..1c5d4b14d6580bbc60bde18d608d0bd79e7c81c0 100644 (file)
  */
 
 int
-bdb_operational(
+bdb_hasSubordinates(
        BackendDB       *be,
        Connection      *conn, 
        Operation       *op,
        Entry           *e,
-       AttributeName           *attrs,
-       int             opattrs,
-       Attribute       **a )
+       int             *hasSubordinates )
 {
        struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-       Attribute       **aa = a;
        int             rc;
        DB_TXN          *ltid = NULL;
-    struct bdb_op_info opinfo;
+       struct bdb_op_info opinfo;
        
        assert( e );
-
-       if ( !opattrs && !ad_inlist( slap_schema.si_ad_hasSubordinates, attrs ) ) {
-               return 0;
-       }
-
+       assert( hasSubordinates );
 
        if( 0 ) {
 retry: /* transaction retry */
@@ -51,9 +44,9 @@ retry:        /* transaction retry */
 #endif
 #ifdef NEW_LOGGING
                LDAP_LOG ( OPERATION, DETAIL1, 
-                       "=> bdb_operational: retrying...\n", 0, 0, 0 );
+                       "=> bdb_hasSubordinates: retrying...\n", 0, 0, 0 );
 #else
-               Debug( LDAP_DEBUG_TRACE, "==> bdb_operational: retrying...\n", 
+               Debug( LDAP_DEBUG_TRACE, "==> bdb_hasSubordinates: retrying...\n", 
                                0, 0, 0 );
 #endif
                rc = TXN_ABORT( ltid );
@@ -71,11 +64,11 @@ retry:      /* transaction retry */
        if ( rc != 0 ) {
 #ifdef NEW_LOGGING
                LDAP_LOG ( OPERATION, ERR, 
-                       "=> bdb_operational: txn_begin failed: %s (%d)\n",
+                       "=> bdb_hasSubordinates: txn_begin failed: %s (%d)\n",
                        db_strerror(rc), rc, 0 );
 #else
                Debug( LDAP_DEBUG_TRACE,
-                       "bdb_operational: txn_begin failed: %s (%d)\n",
+                       "bdb_hasSubordinates: txn_begin failed: %s (%d)\n",
                        db_strerror( rc ), rc, 0 );
 #endif
                rc = LDAP_OTHER;
@@ -95,21 +88,22 @@ retry:      /* transaction retry */
                goto retry;
 
        case 0:
+               *hasSubordinates = LDAP_COMPARE_TRUE;
+               break;
+
        case DB_NOTFOUND:
-               *aa = slap_operational_hasSubordinate( rc == 0 );
-               if ( *aa != NULL ) {
-                       aa = &(*aa)->a_next;
-               }
+               *hasSubordinates = LDAP_COMPARE_FALSE;
+               rc = LDAP_SUCCESS;
                break;
 
        default:
 #ifdef NEW_LOGGING
                LDAP_LOG ( OPERATION, ERR, 
-                       "=> bdb_operational: has_children failed: %s (%d)\n",
+                       "=> bdb_hasSubordinates: has_children failed: %s (%d)\n",
                        db_strerror(rc), rc, 0 );
 #else
                Debug(LDAP_DEBUG_ARGS, 
-                       "<=- bdb_operational: has_children failed: %s (%d)\n", 
+                       "<=- bdb_hasSubordinates: has_children failed: %s (%d)\n", 
                        db_strerror(rc), rc, 0 );
 #endif
                rc = LDAP_OTHER;
@@ -130,3 +124,33 @@ return_results:
        return rc;
 }
 
+int
+bdb_operational(
+       BackendDB       *be,
+       Connection      *conn, 
+       Operation       *op,
+       Entry           *e,
+       AttributeName           *attrs,
+       int             opattrs,
+       Attribute       **a )
+{
+       Attribute       **aa = a;
+       int             rc = 0;
+       
+       assert( e );
+
+       if ( opattrs || ad_inlist( slap_schema.si_ad_hasSubordinates, attrs ) ) {
+               int     hasSubordinates;
+
+               rc = bdb_hasSubordinates( be, conn, op, e, &hasSubordinates );
+               if ( rc == LDAP_SUCCESS ) {
+                       *aa = slap_operational_hasSubordinate( hasSubordinates == LDAP_COMPARE_TRUE );
+                       if ( *aa != NULL ) {
+                               aa = &(*aa)->a_next;
+                       }
+               }
+       }
+
+       return rc;
+}
+
index 8fa8b55181e2792923d3319321d00550808ce8e9..6c7dfeb5863175293a4808a692a946e8324634ab 100644 (file)
@@ -300,6 +300,17 @@ int bdb_modify_internal(
        char *textbuf,
        size_t textlen );
 
+/*
+ * operational.c
+ */
+int
+bdb_hasSubordinates(
+       BackendDB       *be,
+       Connection      *conn, 
+       Operation       *op,
+       Entry           *e,
+       int             *hasSubordinates );
+
 /*
  * passwd.c
  */
index 462d8ec02745e742373cc6dd7649488df4667a07..30abec8b259f04faa3b171eb9271b65427b42879 100644 (file)
@@ -59,6 +59,10 @@ bdb_search(
        struct slap_limits_set *limit = NULL;
        int isroot = 0;
 
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+       int             filter_hasSubordinates = 0;
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
        u_int32_t       locker;
        DB_LOCK         lock;
 
@@ -322,11 +326,22 @@ dn2entry_retry:
                }
        }
 
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+       /*
+        * is hasSubordinates used in the filter ?
+        * FIXME: we may compute this directly when parsing the filter
+        */
+       filter_hasSubordinates = filter_has_subordinates( filter );
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
        for ( id = bdb_idl_first( candidates, &cursor );
                id != NOID;
                id = bdb_idl_next( candidates, &cursor ) )
        {
                int             scopeok = 0;
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+               Attribute       *hasSubordinates = NULL;
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
 
                /* check for abandon */
                if ( op->o_abandon ) {
@@ -490,8 +505,47 @@ id2entry_retry:
                        goto loop_continue;
                }
 
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+               /*
+                * if hasSubordinates is used in the filter,
+                * append it to the entry's attributes
+                */
+               if ( filter_hasSubordinates ) {
+                       int     hs;
+
+                       rc = bdb_hasSubordinates( be, conn, op, e, &hs);
+                       if ( rc != LDAP_SUCCESS ) {
+                               goto loop_continue;
+                       }
+
+                       hasSubordinates = slap_operational_hasSubordinate( hs == LDAP_COMPARE_TRUE );
+                       if ( hasSubordinates == NULL ) {
+                               goto loop_continue;
+                       }
+
+                       hasSubordinates->a_next = e->e_attrs;
+                       e->e_attrs = hasSubordinates;
+               }
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
                /* if it matches the filter and scope, send it */
                rc = test_filter( be, conn, op, e, filter );
+
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+               if ( hasSubordinates ) {
+                       /*
+                        * FIXME: this is fairly inefficient, because 
+                        * if hasSubordinates is among the required
+                        * attrs, it will be added again later;
+                        * maybe we should leave it and check
+                        * check later if it's already present,
+                        * if required
+                        */
+                       e->e_attrs = e->e_attrs->a_next;
+                       attr_free( hasSubordinates );
+               }
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
                if ( rc == LDAP_COMPARE_TRUE ) {
                        struct berval   dn;
 
@@ -525,12 +579,16 @@ id2entry_retry:
                                if (e) {
                                        int result;
                                        
+#if 0  /* noop is masked SLAP_CTRL_UPDATE */
                                        if( op->o_noop ) {
                                                result = 0;
                                        } else {
+#endif
                                                result = send_search_entry( be, conn, op,
                                                        e, attrs, attrsonly, NULL);
+#if 0
                                        }
+#endif
 
                                        switch (result) {
                                        case 0:         /* entry sent ok */
@@ -557,8 +615,8 @@ id2entry_retry:
                        }
                } else {
 #ifdef NEW_LOGGING
-                               LDAP_LOG ( OPERATION, RESULTS,
-                                       "bdb_search: %ld does match filter\n", (long) id, 0, 0);
+                       LDAP_LOG ( OPERATION, RESULTS,
+                               "bdb_search: %ld does match filter\n", (long) id, 0, 0);
 #else
                        Debug( LDAP_DEBUG_TRACE,
                                "bdb_search: %ld does match filter\n",
@@ -774,3 +832,4 @@ static int search_candidates(
 
        return rc;
 }
+
index 87f4b9278b1676360089b3b42d5fd18445464e53..eac5f831e9cc125a7bba4b4bb83afe27462ce404 100644 (file)
@@ -57,6 +57,10 @@ ldbm_back_search(
        struct slap_limits_set *limit = NULL;
        int isroot = 0;
                
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+       int             filter_hasSubordinates = 0;
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
 #ifdef NEW_LOGGING
        LDAP_LOG( BACK_LDBM, ENTRY, "ldbm_back_search: enter\n", 0, 0, 0 );
 #else
@@ -288,10 +292,22 @@ searchit:
        /* compute it anyway; root does not use it */
        stoptime = op->o_time + tlimit;
 
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+       /*
+        * is hasSubordinates used in the filter ?
+        * FIXME: we may compute this directly when parsing the filter
+        */
+       filter_hasSubordinates = filter_has_subordinates( filter );
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
        for ( id = idl_firstid( candidates, &cursor ); id != NOID;
            id = idl_nextid( candidates, &cursor ) )
        {
                int scopeok = 0;
+               int result = 0;
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+               Attribute       *hasSubordinates = NULL;
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
 
                /* check for abandon */
                if ( op->o_abandon ) {
@@ -420,8 +436,44 @@ searchit:
                        goto loop_continue;
                }
 
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+               /*
+                * if hasSubordinates is used in the filter,
+                * append it to the entry's attributes
+                */
+               if ( filter_hasSubordinates ) {
+                       int     hs;
+
+                       hs = has_children( be, e );
+                       hasSubordinates = slap_operational_hasSubordinate( hs );
+                       if ( hasSubordinates == NULL ) {
+                               goto loop_continue;
+                       }
+
+                       hasSubordinates->a_next = e->e_attrs;
+                       e->e_attrs = hasSubordinates;
+               }
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
                /* if it matches the filter and scope, send it */
-               if ( test_filter( be, conn, op, e, filter ) == LDAP_COMPARE_TRUE ) {
+               result = test_filter( be, conn, op, e, filter );
+
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+               if ( hasSubordinates ) {
+                       /*
+                        * FIXME: this is fairly inefficient, because 
+                        * if hasSubordinates is among the required
+                        * attrs, it will be added again later;
+                        * maybe we should leave it and check
+                        * check later if it's already present,
+                        * if required
+                        */
+                       e->e_attrs = e->e_attrs->a_next;
+                       attr_free( hasSubordinates );
+               }
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
+               if ( result == LDAP_COMPARE_TRUE ) {
                        struct berval   dn;
 
                        /* check scope */
@@ -452,7 +504,7 @@ searchit:
                                }
 
                                if (e) {
-                                       int result = send_search_entry(be, conn, op,
+                                       result = send_search_entry(be, conn, op,
                                                e, attrs, attrsonly, NULL);
 
                                        switch (result) {
index 461fc7a9f5af79c7a20cf4936215356fc948680f..b5f3fe0440bcf93671dd8308240a152f94aaddd0 100644 (file)
@@ -254,34 +254,32 @@ int backend_startup(Backend *be)
 
                if ( be->bd_info->bi_open ) {
                        rc = be->bd_info->bi_open( be->bd_info );
-               }
-
-               if(rc != 0) {
+                       if ( rc != 0 ) {
 #ifdef NEW_LOGGING
-                       LDAP_LOG( BACKEND, CRIT, "backend_startup: bi_open failed!\n", 0, 0, 0 );
+                               LDAP_LOG( BACKEND, CRIT, "backend_startup: bi_open failed!\n", 0, 0, 0 );
 #else
-                       Debug( LDAP_DEBUG_ANY,
-                               "backend_startup: bi_open failed!\n",
-                               0, 0, 0 );
+                               Debug( LDAP_DEBUG_ANY,
+                                       "backend_startup: bi_open failed!\n",
+                                       0, 0, 0 );
 #endif
 
-                       return rc;
+                               return rc;
+                       }
                }
 
                if ( be->bd_info->bi_db_open ) {
                        rc = be->bd_info->bi_db_open( be );
-               }
-
-               if(rc != 0) {
+                       if ( rc != 0 ) {
 #ifdef NEW_LOGGING
-                       LDAP_LOG( BACKEND, CRIT, 
-                               "backend_startup: bi_db_open failed! (%d)\n", rc, 0, 0 );
+                               LDAP_LOG( BACKEND, CRIT, 
+                                       "backend_startup: bi_db_open failed! (%d)\n", rc, 0, 0 );
 #else
-                       Debug( LDAP_DEBUG_ANY,
-                               "backend_startup: bi_db_open failed! (%d)\n",
-                               rc, 0, 0 );
+                               Debug( LDAP_DEBUG_ANY,
+                                       "backend_startup: bi_db_open failed! (%d)\n",
+                                       rc, 0, 0 );
 #endif
-                       return rc;
+                               return rc;
+                       }
                }
 
                return rc;
@@ -297,18 +295,17 @@ int backend_startup(Backend *be)
                if( backendInfo[i].bi_open ) {
                        rc = backendInfo[i].bi_open(
                                &backendInfo[i] );
-               }
-
-               if(rc != 0) {
+                       if ( rc != 0 ) {
 #ifdef NEW_LOGGING
-                       LDAP_LOG( BACKEND, CRIT, 
-                               "backend_startup: bi_open %d failed!\n", i, 0, 0 );
+                               LDAP_LOG( BACKEND, CRIT, 
+                                       "backend_startup: bi_open %d failed!\n", i, 0, 0 );
 #else
-                       Debug( LDAP_DEBUG_ANY,
-                               "backend_startup: bi_open %d failed!\n",
-                               i, 0, 0 );
+                               Debug( LDAP_DEBUG_ANY,
+                                       "backend_startup: bi_open %d failed!\n",
+                                       i, 0, 0 );
 #endif
-                       return rc;
+                               return rc;
+                       }
                }
        }
 
@@ -320,18 +317,17 @@ int backend_startup(Backend *be)
                if ( backendDB[i].bd_info->bi_db_open ) {
                        rc = backendDB[i].bd_info->bi_db_open(
                                &backendDB[i] );
-               }
-
-               if(rc != 0) {
+                       if ( rc != 0 ) {
 #ifdef NEW_LOGGING
-                       LDAP_LOG( BACKEND, CRIT, 
-                               "backend_startup: bi_db_open(%d) failed! (%d)\n", i, rc, 0 );
+                               LDAP_LOG( BACKEND, CRIT, 
+                                       "backend_startup: bi_db_open(%d) failed! (%d)\n", i, rc, 0 );
 #else
-                       Debug( LDAP_DEBUG_ANY,
-                               "backend_startup: bi_db_open(%d) failed! (%d)\n",
-                               i, rc, 0 );
+                               Debug( LDAP_DEBUG_ANY,
+                                       "backend_startup: bi_db_open(%d) failed! (%d)\n",
+                                       i, rc, 0 );
 #endif
-                       return rc;
+                               return rc;
+                       }
                }
        }
 
@@ -746,6 +742,11 @@ backend_check_controls(
                return LDAP_SUCCESS;
        }
 
+       if ( be->be_controls == NULL ) {
+               *text = "control unavailable in context";
+               return LDAP_UNAVAILABLE_CRITICAL_EXTENSION;
+       }
+
        for( ; *ctrls != NULL ; ctrls++ ) {
                if( (*ctrls)->ldctl_iscritical &&
                        !ldap_charray_inlist( be->be_controls, (*ctrls)->ldctl_oid ) )
index 9194a9cb536847b75b6430c535321b77cd075072..0084a7c80a22776a1e22295055ac06dea866f300 100644 (file)
 
 const struct berval slap_empty_bv = { 0, "" };
 
-#define SLAP_LDAPDN_PRETTY 0x1
-
-#define SLAP_LDAPDN_MAXLEN 8192
-
 /*
  * The DN syntax-related functions take advantage of the dn representation
  * handling functions ldap_str2dn/ldap_dn2str.  The latter are not schema-
@@ -493,6 +489,60 @@ dnPretty2(
        return LDAP_SUCCESS;
 }
 
+int
+dnPrettyNormalDN(
+       Syntax *syntax,
+       struct berval *val,
+       LDAPDN **dn,
+       int flags )
+{
+       assert( val );
+       assert( dn );
+
+#ifdef NEW_LOGGING
+       LDAP_LOG( OPERATION, ARGS, ">>> dn%sDN: <%s>\n", 
+                       flags == SLAP_LDAPDN_PRETTY ? "Pretty" : "Normal", 
+                       val->bv_val, 0 );
+#else
+       Debug( LDAP_DEBUG_TRACE, ">>> dn%sDN: <%s>\n", 
+                       flags == SLAP_LDAPDN_PRETTY ? "Pretty" : "Normal", 
+                       val->bv_val, 0 );
+#endif
+
+       if ( val->bv_len == 0 ) {
+               return LDAP_SUCCESS;
+
+       } else if ( val->bv_len > SLAP_LDAPDN_MAXLEN ) {
+               return LDAP_INVALID_SYNTAX;
+
+       } else {
+               int             rc;
+
+               /* FIXME: should be liberal in what we accept */
+               rc = ldap_bv2dn( val, dn, LDAP_DN_FORMAT_LDAP );
+               if ( rc != LDAP_SUCCESS ) {
+                       return LDAP_INVALID_SYNTAX;
+               }
+
+               assert( strlen( val->bv_val ) == val->bv_len );
+
+               /*
+                * Schema-aware rewrite
+                */
+               if ( LDAPDN_rewrite( *dn, flags ) != LDAP_SUCCESS ) {
+                       ldap_dnfree( *dn );
+                       *dn = NULL;
+                       return LDAP_INVALID_SYNTAX;
+               }
+       }
+
+       Debug( LDAP_DEBUG_TRACE, "<<< dn%sDN\n", 
+                       flags == SLAP_LDAPDN_PRETTY ? "Pretty" : "Normal",
+                       0, 0 );
+
+       return LDAP_SUCCESS;
+}
+
 /*
  * Combination of both dnPretty and dnNormalize
  */
index 69a26bf34bd30a3fe0fed81e8f50b53c701b903a..608b732c847c4c1cf26d4a5404b7dce1dccbd9b6 100644 (file)
@@ -744,7 +744,7 @@ filter2bv( Filter *f, struct berval *fstr )
 
        case LDAP_FILTER_EXT:
                filter_escape_value( &f->f_mr_value, &tmp );
-
+#ifndef SLAP_X_MRA_MATCH_DNATTRS
                fstr->bv_len = f->f_mr_desc->ad_cname.bv_len +
                        ( f->f_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
                        ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) +
@@ -757,6 +757,31 @@ filter2bv( Filter *f, struct berval *fstr )
                        f->f_mr_rule_text.bv_len ? ":" : "",
                        f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
                        tmp.bv_val );
+#else /* SLAP_X_MRA_MATCH_DNATTRS */
+               {
+               struct berval ad;
+
+               if ( f->f_mr_desc ) {
+                       ad = f->f_mr_desc->ad_cname;
+               } else {
+                       ad.bv_len = 0;
+                       ad.bv_val = "";
+               }
+                       
+               fstr->bv_len = ad.bv_len +
+                       ( f->f_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
+                       ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) +
+                       tmp.bv_len + ( sizeof("(:=)") - 1 );
+               fstr->bv_val = malloc( fstr->bv_len + 1 );
+
+               snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
+                       ad.bv_val,
+                       f->f_mr_dnattrs ? ":dn" : "",
+                       f->f_mr_rule_text.bv_len ? ":" : "",
+                       f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
+                       tmp.bv_val );
+               }
+#endif /* SLAP_X_MRA_MATCH_DNATTRS */
                ber_memfree( tmp.bv_val );
                break;
 
@@ -1286,6 +1311,7 @@ simple_vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr )
        case LDAP_FILTER_EXT:
                filter_escape_value( &f->f_mr_value, &tmp );
 
+#ifndef SLAP_X_MRA_MATCH_DNATTRS
                fstr->bv_len = f->f_mr_desc->ad_cname.bv_len +
                        ( f->f_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
                        ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) +
@@ -1298,6 +1324,32 @@ simple_vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr )
                        f->f_mr_rule_text.bv_len ? ":" : "",
                        f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
                        tmp.bv_val );
+#else /* SLAP_X_MRA_MATCH_DNATTRS */
+               {
+               struct berval ad;
+
+               if ( f->f_mr_desc ) {
+                       ad = f->f_mr_desc->ad_cname;
+               } else {
+                       ad.bv_len = 0;
+                       ad.bv_val = "";
+               }
+                       
+               fstr->bv_len = ad.bv_len +
+                       ( f->f_mr_dnattrs ? sizeof(":dn")-1 : 0 ) +
+                       ( f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_len+1 : 0 ) +
+                       tmp.bv_len + ( sizeof("(:=)") - 1 );
+               fstr->bv_val = malloc( fstr->bv_len + 1 );
+
+               snprintf( fstr->bv_val, fstr->bv_len + 1, "(%s%s%s%s:=%s)",
+                       ad.bv_val,
+                       f->f_mr_dnattrs ? ":dn" : "",
+                       f->f_mr_rule_text.bv_len ? ":" : "",
+                       f->f_mr_rule_text.bv_len ? f->f_mr_rule_text.bv_val : "",
+                       tmp.bv_val );
+               }
+#endif /* SLAP_X_MRA_MATCH_DNATTRS */
+
                ber_memfree( tmp.bv_val );
                break;
 
@@ -1514,3 +1566,92 @@ return_error:
        return( LDAP_SUCCESS );
 }
 
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+static int filter_has_subordinates_list(
+       Filter          *filter );
+
+/*
+ * FIXME: we could detect the need to filter
+ * for hasSubordinates when parsing the filter ...
+ */
+
+static int
+filter_has_subordinates_list(
+       Filter          *fl )
+{
+       Filter                  *f;
+
+       for ( f = fl; f != NULL; f = f->f_next ) {
+               int     rc;
+
+               rc = filter_has_subordinates( f );
+
+               if ( rc ) {
+                       return rc;
+               }
+       }
+
+       return 0;
+}
+
+int
+filter_has_subordinates(
+       Filter          *f )
+{
+       AttributeDescription    *ad = NULL;
+
+       switch ( f->f_choice ) {
+       case LDAP_FILTER_PRESENT:
+               ad = f->f_desc;
+               break;
+
+       case LDAP_FILTER_EQUALITY:
+       case LDAP_FILTER_APPROX:
+       case LDAP_FILTER_GE:
+       case LDAP_FILTER_LE:
+               ad = f->f_ava->aa_desc;
+               break;
+
+       case LDAP_FILTER_SUBSTRINGS:
+               ad = f->f_sub_desc;
+               break;
+
+       case LDAP_FILTER_EXT:
+               /* could be null; however here it is harmless */
+               ad = f->f_mra->ma_desc;
+               break;
+
+       case LDAP_FILTER_NOT:
+               return filter_has_subordinates( f->f_not );
+
+       case LDAP_FILTER_AND:
+               return filter_has_subordinates_list( f->f_and );
+
+       case LDAP_FILTER_OR:
+               return filter_has_subordinates_list( f->f_or );
+
+       case SLAPD_FILTER_COMPUTED:
+               /*
+                * something wrong?
+                */
+               return 0;
+
+       default:
+               /*
+                * this means a new type of filter has been implemented,
+                * which is not handled yet in this function; we should
+                * issue a developer's warning, e.g. an assertion
+                */
+               assert( 0 );
+               return -1;
+       }
+
+       if ( ad == slap_schema.si_ad_hasSubordinates ) {
+               return 1;
+       }
+
+       return 0;
+}
+
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
+
index 672915cb8cde4a6ff3db6717e74d401c4d1592bb..111e258e61554acf70b6f6a9b0cc7ef880da75a1 100644 (file)
@@ -215,36 +215,174 @@ static int test_mra_filter(
 {
        Attribute       *a;
 
+#ifndef SLAP_X_MRA_MATCH_DNATTRS
        if( !access_allowed( be, conn, op, e,
                mra->ma_desc, &mra->ma_value, ACL_SEARCH, NULL ) )
        {
                return LDAP_INSUFFICIENT_ACCESS;
        }
+#else /* SLAP_X_MRA_MATCH_DNATTRS */
+       if ( mra->ma_desc ) {
+               /*
+                * if ma_desc is available, then we're filtering for
+                * one attribute, and SEARCH permissions can be checked
+                * directly.
+                */
+               if( !access_allowed( be, conn, op, e,
+                       mra->ma_desc, &mra->ma_value, ACL_SEARCH, NULL ) )
+               {
+                       return LDAP_INSUFFICIENT_ACCESS;
+               }
+#endif /* SLAP_X_MRA_MATCH_DNATTRS */
+
+               for(a = attrs_find( e->e_attrs, mra->ma_desc );
+                       a != NULL;
+                       a = attrs_find( a->a_next, mra->ma_desc ) )
+               {
+                       struct berval *bv;
+                       for ( bv = a->a_vals; bv->bv_val != NULL; bv++ ) {
+                               int ret;
+                               int rc;
+                               const char *text;
+       
+                               rc = value_match( &ret, a->a_desc, mra->ma_rule,
+                                       SLAP_MR_ASSERTION_SYNTAX_MATCH,
+                                       bv, &mra->ma_value, &text );
+       
+                               if( rc != LDAP_SUCCESS ) {
+                                       return rc;
+                               }
+       
+                               if ( ret == 0 ) {
+                                       return LDAP_COMPARE_TRUE;
+                               }
+                       }
+               }
+#ifdef SLAP_X_MRA_MATCH_DNATTRS
+       } else {
 
-       for(a = attrs_find( e->e_attrs, mra->ma_desc );
-               a != NULL;
-               a = attrs_find( a->a_next, mra->ma_desc ) )
-       {
-               struct berval *bv;
-               for ( bv = a->a_vals; bv->bv_val != NULL; bv++ ) {
-                       int ret;
-                       int rc;
-                       const char *text;
+               /*
+                * No attribute description: test all
+                */
+               for ( a = e->e_attrs; a != NULL; a = a->a_next ) {
+                       struct berval   *bv, value;
+                       const char      *text = NULL;
+                       int             rc;
+
+                       /* check if matching is appropriate */
+                       if ( strcmp( mra->ma_rule->smr_syntax->ssyn_oid,
+                               a->a_desc->ad_type->sat_syntax->ssyn_oid ) != 0 ) {
+                               continue;
+                       }
 
-                       rc = value_match( &ret, a->a_desc, mra->ma_rule,
-                               SLAP_MR_ASSERTION_SYNTAX_MATCH,
-                               bv, &mra->ma_value,
-                               &text );
+                       /* normalize for equality */
+                       rc = value_validate_normalize( a->a_desc, 
+                               SLAP_MR_EQUALITY,
+                               &mra->ma_value, &value, &text );
+                       if ( rc != LDAP_SUCCESS ) {
+                               continue;
+                       }
 
-                       if( rc != LDAP_SUCCESS ) {
-                               return rc;
+                       /* check search access */
+                       if ( !access_allowed( be, conn, op, e,
+                               a->a_desc, &value, ACL_SEARCH, NULL ) ) {
+                               continue;
                        }
 
-                       if ( ret == 0 ) {
-                               return LDAP_COMPARE_TRUE;
+                       /* check match */
+                       for ( bv = a->a_vals; bv->bv_val != NULL; bv++ ) {
+                               int ret;
+                               int rc;
+       
+                               rc = value_match( &ret, a->a_desc, mra->ma_rule,
+                                       SLAP_MR_ASSERTION_SYNTAX_MATCH,
+                                       bv, &value, &text );
+       
+                               if( rc != LDAP_SUCCESS ) {
+                                       return rc;
+                               }
+       
+                               if ( ret == 0 ) {
+                                       return LDAP_COMPARE_TRUE;
+                               }
+                       }
+               }
+       }
+
+       /* check attrs in DN AVAs if required */
+       if ( mra->ma_dnattrs ) {
+               LDAPDN          *dn = NULL;
+               int             iRDN, iAVA;
+               int             rc;
+
+               /* parse and pretty the dn */
+               rc = dnPrettyDN( NULL, &e->e_name, &dn );
+               if ( rc != LDAP_SUCCESS ) {
+                       return LDAP_INVALID_SYNTAX;
+               }
+
+               /* for each AVA of each RDN ... */
+               for ( iRDN = 0; dn[ 0 ][ iRDN ]; iRDN++ ) {
+                       LDAPRDN         *rdn = dn[ 0 ][ iRDN ];
+
+                       for ( iAVA = 0; rdn[ 0 ][ iAVA ]; iAVA++ ) {
+                               LDAPAVA         *ava = rdn[ 0 ][ iAVA ];
+                               struct berval   *bv = &ava->la_value, value;
+                               AttributeDescription *ad = (AttributeDescription *)ava->la_private;
+                               int ret;
+                               int rc;
+                               const char *text;
+
+                               assert( ad );
+
+                               if ( mra->ma_desc ) {
+                                       /* have a mra type? check for subtype */
+                                       if ( !is_ad_subtype( ad, mra->ma_desc ) ) {
+                                               continue;
+                                       }
+                                       value = mra->ma_value;
+
+                               } else {
+                                       const char      *text = NULL;
+
+                                       /* check if matching is appropriate */
+                                       if ( strcmp( mra->ma_rule->smr_syntax->ssyn_oid,
+                                               ad->ad_type->sat_syntax->ssyn_oid ) != 0 ) {
+                                               continue;
+                                       }
+
+                                       /* normalize for equality */
+                                       rc = value_validate_normalize( ad, SLAP_MR_EQUALITY,
+                                               &mra->ma_value, &value, &text );
+                                       if ( rc != LDAP_SUCCESS ) {
+                                               continue;
+                                       }
+
+                                       /* check search access */
+                                       if ( !access_allowed( be, conn, op, e,
+                                               ad, &value, ACL_SEARCH, NULL ) ) {
+                                               continue;
+                                       }
+                               }
+
+                               /* check match */
+                               rc = value_match( &ret, ad, mra->ma_rule,
+                                       SLAP_MR_ASSERTION_SYNTAX_MATCH,
+                                       bv, &value, &text );
+
+                               if( rc != LDAP_SUCCESS ) {
+                                       ldap_dnfree( dn );
+                                       return rc;
+                               }
+
+                               if ( ret == 0 ) {
+                                       ldap_dnfree( dn );
+                                       return LDAP_COMPARE_TRUE;
+                               }
                        }
                }
        }
+#endif /* SLAP_X_MRA_MATCH_DNATTRS */
 
        return LDAP_COMPARE_FALSE;
 }
index d091c4fe07a25feb96b0761398b31bfa23549a98..90f66152ea85758efc344eaf96c4d0394d7d3259 100644 (file)
@@ -71,6 +71,65 @@ ldap_pvt_thread_mutex_t      replog_mutex;
 static const char* slap_name = NULL;
 int slapMode = SLAP_UNDEFINED_MODE;
 
+/*
+ * all known control OIDs should be added to this list
+ */
+char *slap_known_controls[] = {
+#ifdef LDAP_CONTROL_REFERRALS
+       LDAP_CONTROL_REFERRALS,
+#endif /* LDAP_CONTROL_REFERRALS */
+
+#ifdef LDAP_CONTROL_MANAGEDSAIT
+       LDAP_CONTROL_MANAGEDSAIT,
+#endif /* LDAP_CONTROL_MANAGEDSAIT */
+
+#ifdef LDAP_CONTROL_SUBENTRIES
+       LDAP_CONTROL_SUBENTRIES,
+#endif /* LDAP_CONTROL_SUBENTRIES */
+
+#ifdef LDAP_CONTROL_NOOP
+       LDAP_CONTROL_NOOP,
+#endif /* LDAP_CONTROL_NOOP */
+
+#ifdef LDAP_CONTROL_DUPENT_REQUEST
+       LDAP_CONTROL_DUPENT_REQUEST,
+#endif /* LDAP_CONTROL_DUPENT_REQUEST */
+
+#ifdef LDAP_CONTROL_DUPENT_RESPONSE
+       LDAP_CONTROL_DUPENT_RESPONSE,
+#endif /* LDAP_CONTROL_DUPENT_RESPONSE */
+
+#ifdef LDAP_CONTROL_DUPENT_ENTRY
+       LDAP_CONTROL_DUPENT_ENTRY,
+#endif /* LDAP_CONTROL_DUPENT_ENTRY */
+
+#ifdef LDAP_CONTROL_PAGEDRESULTS
+       LDAP_CONTROL_PAGEDRESULTS,
+#endif /* LDAP_CONTROL_PAGEDRESULTS */
+
+#ifdef LDAP_CONTROL_SORTREQUEST
+       LDAP_CONTROL_SORTREQUEST,
+#endif /* LDAP_CONTROL_SORTREQUEST */
+
+#ifdef LDAP_CONTROL_SORTRESPONSE
+       LDAP_CONTROL_SORTRESPONSE,
+#endif /* LDAP_CONTROL_SORTRESPONSE */
+
+#ifdef LDAP_CONTROL_VLVREQUEST
+       LDAP_CONTROL_VLVREQUEST,
+#endif /* LDAP_CONTROL_VLVREQUEST */
+
+#ifdef LDAP_CONTROL_VLVRESPONSE
+       LDAP_CONTROL_VLVRESPONSE,
+#endif /* LDAP_CONTROL_VLVRESPONSE */
+
+#ifdef LDAP_CONTROL_VALUESRETURNFILTER
+       LDAP_CONTROL_VALUESRETURNFILTER,
+#endif /* LDAP_CONTROL_VALUESRETURNFILTER */
+
+       NULL
+};
+
 int
 slap_init( int mode, const char *name )
 {
index 483a14956d225e1f988caa2bf4636202ff340a42..51c223e97d0ad71787f20f803395313361af352e 100644 (file)
@@ -19,7 +19,8 @@
 
 #include "../../libraries/liblber/lber-int.h"
 
-static int test_mra_vrFilter(
+static int
+test_mra_vrFilter(
        Backend         *be,
        Connection      *conn,
        Operation       *op,
@@ -342,7 +343,8 @@ test_substrings_vrFilter(
        return LDAP_SUCCESS;
 }
 
-static int test_mra_vrFilter(
+static int
+test_mra_vrFilter(
        Backend         *be,
        Connection      *conn,
        Operation       *op,
@@ -354,11 +356,40 @@ static int test_mra_vrFilter(
        int i, j;
 
        for ( i=0; a != NULL; a = a->a_next, i++ ) {
-               struct berval *bv;
-       
+               struct berval *bv, value;
+
+#ifndef SLAP_X_MRA_MATCH_DNATTRS
                if ( !is_ad_subtype( a->a_desc, mra->ma_desc ) ) {
                        return( LDAP_SUCCESS );
                }
+               value = mra->ma_value;
+
+#else /* SLAP_X_MRA_MATCH_DNATTRS */
+               if ( mra->ma_desc ) {
+                       if ( !is_ad_subtype( a->a_desc, mra->ma_desc ) ) {
+                               return( LDAP_SUCCESS );
+                       }
+                       value = mra->ma_value;
+
+               } else {
+                       const char      *text = NULL;
+
+                       /* check if matching is appropriate */
+                       if ( strcmp( mra->ma_rule->smr_syntax->ssyn_oid,
+                               a->a_desc->ad_type->sat_syntax->ssyn_oid ) != 0 ) {
+                               continue;
+                       }
+
+                       /* normalize for equality */
+                       if ( value_validate_normalize( a->a_desc, 
+                               SLAP_MR_EQUALITY,
+                               &mra->ma_value, &value,
+                               &text ) != LDAP_SUCCESS ) {
+                               continue;
+                       }
+
+               }
+#endif /* SLAP_X_MRA_MATCH_DNATTRS */
 
                for ( bv = a->a_vals, j = 0; bv->bv_val != NULL; bv++, j++ ) {
                        int ret;
@@ -367,14 +398,14 @@ static int test_mra_vrFilter(
 
                        rc = value_match( &ret, a->a_desc, mra->ma_rule,
                                SLAP_MR_ASSERTION_SYNTAX_MATCH,
-                               bv, &mra->ma_value,
+                               bv, &value,
                                &text );
 
                        if( rc != LDAP_SUCCESS ) {
                                return rc;
                        }
 
-                       if ( ret ) {
+                       if ( ret == 0 ) {
                                (*e_flags)[i][j] = 1;
                        }
                }
index eca939b02674fd8b17def10f75c736b76a158c53..d4e331f194ad36fce2c3bc049dad5a1ce1e54b59 100644 (file)
@@ -170,10 +170,15 @@ get_mra(
                return SLAPD_DISCONNECT;
        }
 
+#ifndef SLAP_X_MRA_MATCH_DNATTRS
+       /*
+        * Let's try to implement it
+        */
        if( ma->ma_dnattrs ) {
                *text = "matching with \":dn\" not supported";
                return LDAP_INAPPROPRIATE_MATCHING;
        }
+#endif /* !SLAP_X_MRA_MATCH_DNATTRS */
 
        if( type.bv_val != NULL ) {
                rc = slap_bv2ad( &type, &ma->ma_desc, text );
@@ -182,9 +187,11 @@ get_mra(
                        return rc;
                }
 
+#ifndef SLAP_X_MRA_MATCH_DNATTRS
        } else {
                *text = "matching without attribute description rule not supported";
                return LDAP_INAPPROPRIATE_MATCHING;
+#endif /* !SLAP_X_MRA_MATCH_DNATTRS */
        }
 
        if( ma->ma_rule_text.bv_val != NULL ) {
@@ -196,6 +203,40 @@ get_mra(
                }
        }
 
+       /*
+        * FIXME: is it correct that ma->ma_rule_text, if present,
+        * is looked-up, checked, and then replaced by the sat_equality
+        * of the given attribute?  I'd rather do smtg like use
+        * the attribute's equality rule only if no matching rule
+        * was given, otherwise I don't see any extension ...
+        */
+
+#if 1
+       if ( ma->ma_rule == NULL ) {
+#ifdef SLAP_X_MRA_MATCH_DNATTRS
+               /*
+                * Need either type or rule ...
+                */
+               if ( ma->ma_desc == NULL ) {
+                       mra_free( ma, 1 );
+                       *text = "matching rule not recognized";
+                       return LDAP_INAPPROPRIATE_MATCHING;
+               }
+#endif /* !SLAP_X_MRA_MATCH_DNATTRS */
+
+               if ( ma->ma_desc->ad_type->sat_equality != NULL &&
+                       ma->ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT )
+               {
+                       /* no matching rule was provided, use the attribute's
+                          equality rule if it supports extensible matching. */
+                       ma->ma_rule = ma->ma_desc->ad_type->sat_equality;
+
+               } else {
+                       mra_free( ma, 1 );
+                       return LDAP_INAPPROPRIATE_MATCHING;
+               }
+       }
+#else
        if( ma->ma_desc != NULL &&
                ma->ma_desc->ad_type->sat_equality != NULL &&
                ma->ma_desc->ad_type->sat_equality->smr_usage & SLAP_MR_EXT )
@@ -208,24 +249,38 @@ get_mra(
                mra_free( ma, 1 );
                return LDAP_INAPPROPRIATE_MATCHING;
        }
+#endif
 
-       /* check to see if the matching rule is appropriate for
-          the syntax of the attribute.  This check will need
-          to be extended to support other kinds of extensible
-          matching rules */
-       if( strcmp( ma->ma_rule->smr_syntax->ssyn_oid,
-               ma->ma_desc->ad_type->sat_syntax->ssyn_oid ) != 0 )
-       {
-               mra_free( ma, 1 );
-               return LDAP_INAPPROPRIATE_MATCHING;
-       }
+#ifdef SLAP_X_MRA_MATCH_DNATTRS
+       if ( ma->ma_desc != NULL ) {
+#endif /* SLAP_X_MRA_MATCH_DNATTRS */
+               /* check to see if the matching rule is appropriate for
+                 the syntax of the attribute.  This check will need
+                  to be extended to support other kinds of extensible
+                  matching rules */
+               if( strcmp( ma->ma_rule->smr_syntax->ssyn_oid,
+                       ma->ma_desc->ad_type->sat_syntax->ssyn_oid ) != 0 )
+               {
+                       mra_free( ma, 1 );
+                       return LDAP_INAPPROPRIATE_MATCHING;
+               }
 
-       /*
-        * OK, if no matching rule, normalize for equality, otherwise
-        * normalize for the matching rule.
-        */
-       rc = value_validate_normalize( ma->ma_desc, SLAP_MR_EQUALITY,
-               &value, &ma->ma_value, text );
+               /*
+                * OK, if no matching rule, normalize for equality, otherwise
+                * normalize for the matching rule.
+                */
+               rc = value_validate_normalize( ma->ma_desc, SLAP_MR_EQUALITY,
+                       &value, &ma->ma_value, text );
+#ifdef SLAP_X_MRA_MATCH_DNATTRS
+       } else {
+               /*
+                * Need to normalize, but how?
+                */
+               ma->ma_value = value;
+               rc = value_validate( ma->ma_rule, &ma->ma_value, text );
+
+       }
+#endif /* SLAP_X_MRA_MATCH_DNATTRS */
 
        if( rc != LDAP_SUCCESS ) {
                mra_free( ma, 1 );
index b9396b2473fd194affd1174765a1349981bedb1e..f6b45221f8e889bb4aaf1df6469752877122b818 100644 (file)
@@ -40,14 +40,24 @@ Attribute *
 slap_operational_hasSubordinate( int hs )
 {
        Attribute       *a;
-       
+       char            *val;
+       ber_len_t       len;
+
+       if ( hs ) {
+               val = "TRUE";
+               len = sizeof( "TRUE" ) - 1;
+
+       } else {
+               val = "FALSE";
+               len = sizeof( "FALSE" ) - 1;
+
+       }
+
        a = ch_malloc( sizeof( Attribute ) );
        a->a_desc = slap_schema.si_ad_hasSubordinates;
-
        a->a_vals = ch_malloc( 2 * sizeof( struct berval ) );
-       ber_str2bv( hs ? "TRUE" : "FALSE",
-               hs ? sizeof("TRUE")-1 : sizeof("FALSE")-1,
-               1, a->a_vals );
+
+       ber_str2bv( val, len, 1, a->a_vals );
        a->a_vals[1].bv_val = NULL;
 
        a->a_next = NULL;
index 95720738d06d439a1ecb2cad4fa6906c52148f96..f51f24a18bad32b0c92e8c2f2bdad10d832ba5af 100644 (file)
@@ -395,6 +395,13 @@ LDAP_SLAPD_F (int) dnX509normalize LDAP_P(( void *x509_name, struct berval *out
 
 LDAP_SLAPD_F (int) dnX509peerNormalize LDAP_P(( void *ssl, struct berval *dn ));
 
+LDAP_SLAPD_F (int) dnPrettyNormalDN LDAP_P(( Syntax *syntax, struct berval *val, LDAPDN **dn, int flags ));
+#define dnPrettyDN(syntax, val, dn) \
+       dnPrettyNormalDN((syntax),(val),(dn), SLAP_LDAPDN_PRETTY)
+#define dnNormalDN(syntax, val, dn) \
+       dnPrettyNormalDN((syntax),(val),(dn), 0)
+
+
 /*
  * entry.c
  */
@@ -451,17 +458,31 @@ LDAP_SLAPD_F (int) get_filter LDAP_P((
 LDAP_SLAPD_F (void) filter_free LDAP_P(( Filter *f ));
 LDAP_SLAPD_F (void) filter2bv LDAP_P(( Filter *f, struct berval *bv ));
 
-LDAP_SLAPD_F (int) get_vrFilter( Connection *conn, BerElement *ber,
+LDAP_SLAPD_F (int) get_vrFilter LDAP_P(( Connection *conn, BerElement *ber,
        ValuesReturnFilter **f,
-       const char **text );
+       const char **text ));
+
+LDAP_SLAPD_F (void) vrFilter_free LDAP_P(( ValuesReturnFilter *f ));
+LDAP_SLAPD_F (void) vrFilter2bv LDAP_P(( ValuesReturnFilter *f, struct berval *fstr ));
 
-LDAP_SLAPD_F (void) vrFilter_free( ValuesReturnFilter *f );
-LDAP_SLAPD_F (void) vrFilter2bv( ValuesReturnFilter *f, struct berval *fstr );
+/*
+ * define to honor hasSubordinates operational attribute in search filters
+ */
+#define SLAP_X_FILTER_HASSUBORDINATES
 
+#ifdef SLAP_X_FILTER_HASSUBORDINATES
+LDAP_SLAPD_F (int) filter_has_subordinates LDAP_P(( Filter *filter ));
+#endif /* SLAP_X_FILTER_HASSUBORDINATES */
 
 /*
  * filterentry.c
  */
+
+/*
+ * define to enable dn components match in extended filter matching
+ */
+#define SLAP_X_MRA_MATCH_DNATTRS
+
 LDAP_SLAPD_F (int) test_filter LDAP_P((
        Backend *be, Connection *conn, Operation *op,
        Entry *e, Filter *f ));
@@ -479,6 +500,8 @@ LDAP_SLAPD_F (int)  slap_startup LDAP_P(( Backend *be ));
 LDAP_SLAPD_F (int)     slap_shutdown LDAP_P(( Backend *be ));
 LDAP_SLAPD_F (int)     slap_destroy LDAP_P((void));
 
+LDAP_SLAPD_V (char *)  slap_known_controls[];
+
 /*
  * kerberos.c
  */
index ccc1de308336c816201a3ada61da4c65b11bc830..ed5f85f7824a8fd5ca88cc1092e8f5f02b3fe515 100644 (file)
@@ -762,36 +762,42 @@ send_search_entry(
         * to ValuesReturnFilter or 0 if not
         */     
        if ( op->vrFilter != NULL ) {
-               int k = 0;
-               char *a_flags;
+               int     k = 0;
+               size_t  size;
 
                for ( a = e->e_attrs, i=0; a != NULL; a = a->a_next, i++ ) {
                        for ( j = 0; a->a_vals[j].bv_val != NULL; j++ ) k++;
                }
-               e_flags = ch_calloc ( 1, i * sizeof(char *) + k );
-               a_flags = (char *)(e_flags + i);
-               for ( a = e->e_attrs, i=0; a != NULL; a = a->a_next, i++ ) {
-                       for ( j = 0; a->a_vals[j].bv_val != NULL; j++ );
-                       e_flags[i] = a_flags;
-                       a_flags += j;
-               }
 
-               rc = filter_matched_values(be, conn, op, e->e_attrs, &e_flags) ; 
-               if ( rc == -1 ) {
+               size = i * sizeof(char *) + k;
+               if ( size > 0 ) {
+                       char    *a_flags;
+                       e_flags = ch_calloc ( 1, i * sizeof(char *) + k );
+                       a_flags = (char *)(e_flags + i);
+                       memset( a_flags, 0, k );
+                       for ( a = e->e_attrs, i=0; a != NULL; a = a->a_next, i++ ) {
+                               for ( j = 0; a->a_vals[j].bv_val != NULL; j++ );
+                               e_flags[i] = a_flags;
+                               a_flags += j;
+                       }
+       
+                       rc = filter_matched_values(be, conn, op, e->e_attrs, &e_flags) ; 
+                       if ( rc == -1 ) {
 #ifdef NEW_LOGGING
-                       LDAP_LOG( OPERATION, ERR, 
-                               "send_search_entry: conn %lu matched values filtering failed\n",
-                               conn ? conn->c_connid : 0, 0, 0 );
+                               LDAP_LOG( OPERATION, ERR, 
+                                       "send_search_entry: conn %lu matched values filtering failed\n",
+                                       conn ? conn->c_connid : 0, 0, 0 );
 #else
-               Debug( LDAP_DEBUG_ANY,
-                               "matched values filtering failed\n", 0, 0, 0 );
+                       Debug( LDAP_DEBUG_ANY,
+                                       "matched values filtering failed\n", 0, 0, 0 );
 #endif
-                       ber_free( ber, 1 );
-
-                       send_ldap_result( conn, op, LDAP_OTHER,
-                               NULL, "matched values filtering error", 
-                               NULL, NULL );
-                       goto error_return;
+                               ber_free( ber, 1 );
+       
+                               send_ldap_result( conn, op, LDAP_OTHER,
+                                       NULL, "matched values filtering error", 
+                                       NULL, NULL );
+                               goto error_return;
+                       }
                }
        }
 
@@ -909,48 +915,74 @@ send_search_entry(
                }
        }
 
-       /* free e_flags */
-       if ( e_flags ) {
-               free( e_flags );
-               e_flags = NULL;
-       }
-
        /* eventually will loop through generated operational attributes */
        /* only have subschemaSubentry implemented */
        aa = backend_operational( be, conn, op, e, attrs, opattrs );
 
        if ( aa != NULL && op->vrFilter != NULL ) {
-               int k = 0;
-               char *a_flags;
+               int     k = 0;
+               size_t  size;
 
                for ( a = aa, i=0; a != NULL; a = a->a_next, i++ ) {
                        for ( j = 0; a->a_vals[j].bv_val != NULL; j++ ) k++;
                }
-               e_flags = ch_calloc ( 1, i * sizeof(char *) + k );
-               a_flags = (char *)(e_flags + i);
-               for ( a = e->e_attrs, i=0; a != NULL; a = a->a_next, i++ ) {
-                       for ( j = 0; a->a_vals[j].bv_val != NULL; j++ );
-                       e_flags[i] = a_flags;
-                       a_flags += j;
-               }
-               rc = filter_matched_values(be, conn, op, aa, &e_flags) ; 
-           
-               if ( rc == -1 ) {
+
+               size = i * sizeof(char *) + k;
+               if ( size > 0 ) {
+                       char    *a_flags, **tmp;
+               
+                       /*
+                        * Reuse previous memory - we likely need less space
+                        * for operational attributes
+                        */
+                       tmp = ch_realloc ( e_flags, i * sizeof(char *) + k );
+                       if ( tmp == NULL ) {
 #ifdef NEW_LOGGING
-                       LDAP_LOG( OPERATION, ERR, 
-                               "send_search_entry: conn %lu "
-                               "matched values filtering failed\n", 
-                               conn ? conn->c_connid : 0, 0, 0);
+                               LDAP_LOG( OPERATION, ERR, 
+                                       "send_search_entry: conn %lu "
+                                       "not enough memory "
+                                       "for matched values filtering\n", 
+                                       conn ? conn->c_connid : 0, 0, 0);
 #else
-               Debug( LDAP_DEBUG_ANY,
-                               "matched values filtering failed\n", 0, 0, 0 );
+                               Debug( LDAP_DEBUG_ANY,
+                                       "send_search_entry: conn %lu "
+                                       "not enough memory "
+                                       "for matched values filtering\n",
+                                       conn ? conn->c_connid : 0, 0, 0 );
 #endif
-                       ber_free( ber, 1 );
-
-                       send_ldap_result( conn, op, LDAP_OTHER,
-                               NULL, "matched values filtering error", 
-                               NULL, NULL );
-                       goto error_return;
+                               ber_free( ber, 1 );
+       
+                               send_ldap_result( conn, op, LDAP_NO_MEMORY,
+                                       NULL, NULL, NULL, NULL );
+                               goto error_return;
+                       }
+                       e_flags = tmp;
+                       a_flags = (char *)(e_flags + i);
+                       memset( a_flags, 0, k );
+                       for ( a = aa, i=0; a != NULL; a = a->a_next, i++ ) {
+                               for ( j = 0; a->a_vals[j].bv_val != NULL; j++ );
+                               e_flags[i] = a_flags;
+                               a_flags += j;
+                       }
+                       rc = filter_matched_values(be, conn, op, aa, &e_flags) ; 
+                   
+                       if ( rc == -1 ) {
+#ifdef NEW_LOGGING
+                               LDAP_LOG( OPERATION, ERR, 
+                                       "send_search_entry: conn %lu "
+                                       "matched values filtering failed\n", 
+                                       conn ? conn->c_connid : 0, 0, 0);
+#else
+                               Debug( LDAP_DEBUG_ANY,
+                                       "matched values filtering failed\n", 0, 0, 0 );
+#endif
+                               ber_free( ber, 1 );
+       
+                               send_ldap_result( conn, op, LDAP_OTHER,
+                                       NULL, "matched values filtering error", 
+                                       NULL, NULL );
+                               goto error_return;
+                       }
                }
        }
 
index 725995150fe03669113f729be32e78165ce83579..874ace374c5981a7a022cc510fedb25e29626807 100644 (file)
@@ -28,9 +28,7 @@ schema_info( Entry **entry, const char **text )
                = slap_schema.si_ad_objectClass;
 
        Entry           *e;
-       struct berval   vals[2];
-
-       vals[1].bv_val = NULL;
+       struct berval   vals[5];
 
        e = (Entry *) ch_calloc( 1, sizeof(Entry) );
 
@@ -44,22 +42,17 @@ schema_info( Entry **entry, const char **text )
 
        vals[0].bv_val = "subentry";
        vals[0].bv_len = sizeof("subentry")-1;
-       attr_merge( e, ad_structuralObjectClass, vals );
+       attr_merge_one( e, ad_structuralObjectClass, vals );
 
        vals[0].bv_val = "top";
        vals[0].bv_len = sizeof("top")-1;
-       attr_merge( e, ad_objectClass, vals );
-
-       vals[0].bv_val = "subentry";
-       vals[0].bv_len = sizeof("subentry")-1;
-       attr_merge( e, ad_objectClass, vals );
-
-       vals[0].bv_val = "subschema";
-       vals[0].bv_len = sizeof("subschema")-1;
-       attr_merge( e, ad_objectClass, vals );
-
-       vals[0].bv_val = "extensibleObject";
-       vals[0].bv_len = sizeof("extensibleObject")-1;
+       vals[1].bv_val = "subentry";
+       vals[1].bv_len = sizeof("subentry")-1;
+       vals[2].bv_val = "subschema";
+       vals[2].bv_len = sizeof("subschema")-1;
+       vals[3].bv_val = "extensibleObject";
+       vals[3].bv_len = sizeof("extensibleObject")-1;
+       vals[4].bv_val = NULL;
        attr_merge( e, ad_objectClass, vals );
 
        {
@@ -85,7 +78,7 @@ schema_info( Entry **entry, const char **text )
                        return LDAP_OTHER;
                }
 
-               attr_merge( e, desc, vals );
+               attr_merge_one( e, desc, vals );
        }
 
        if ( syn_schema_info( e ) 
index 90cb1927cc3d3ea70415b239c52405a99ae08c1f..fada8cb8cdec9f3bebfc1fe3831aade9efb4693a 100644 (file)
@@ -142,14 +142,12 @@ do_search(
                        send_ldap_disconnect( conn, op,
                                LDAP_PROTOCOL_ERROR, text );
                } else {
-                       send_ldap_result( conn, op, rc,
-                               NULL, text, NULL, NULL );
+                       send_ldap_result( conn, op, rc, 
+                                       NULL, text, NULL, NULL );
                }
                goto return_results;
-
-       } else {
-               filter2bv( filter, &fstr );
        }
+       filter2bv( filter, &fstr );
 
 #ifdef NEW_LOGGING
        LDAP_LOG( OPERATION, ARGS, 
@@ -319,7 +317,7 @@ do_search(
        if ( be->be_search ) {
                (*be->be_search)( be, conn, op, &pbase, &nbase,
                        scope, deref, sizelimit,
-                   timelimit, filter, &fstr, an, attrsonly );
+                       timelimit, filter, &fstr, an, attrsonly );
        } else {
                send_ldap_result( conn, op, rc = LDAP_UNWILLING_TO_PERFORM,
                        NULL, "operation not supported within namingContext",
index 86a324d7361988a733bebbbe78c4fe76b3445c98..e64d7e87b9d7b169848a7bc17e81e6de5d71ffea 100644 (file)
@@ -1675,6 +1675,12 @@ enum {
 };
 #endif /* SLAPD_MONITOR */
 
+/*
+ * Better know these all around slapd
+ */
+#define SLAP_LDAPDN_PRETTY 0x1
+#define SLAP_LDAPDN_MAXLEN 8192
+
 LDAP_END_DECL
 
 #include "proto-slap.h"