]> git.ipfire.org Git - thirdparty/openldap.git/commitdiff
support a separate cached connection for binds when using (liberal) idassert flagged...
authorPierangelo Masarati <ando@openldap.org>
Sun, 17 Dec 2006 22:11:40 +0000 (22:11 +0000)
committerPierangelo Masarati <ando@openldap.org>
Sun, 17 Dec 2006 22:11:40 +0000 (22:11 +0000)
servers/slapd/back-ldap/back-ldap.h
servers/slapd/back-ldap/bind.c
servers/slapd/back-ldap/config.c

index 3490e4a0eff77b19b909f170604c52dcf0210eeb..6fbabaec5e2ace1ee58ea104a61f4a194893b1a1 100644 (file)
@@ -46,15 +46,19 @@ typedef struct ldap_monitor_info_t {
 
 typedef struct ldapconn_t {
        Connection              *lc_conn;
-#define        LDAP_BACK_PCONN         ((void *)0x0)
-#define        LDAP_BACK_PCONN_TLS     ((void *)0x1)
-#define LDAP_BACK_PCONN_PRIV   (-1)
-#define LDAP_BACK_PCONN_ISPRIV(lc)     ((void *)(lc)->lc_conn <= LDAP_BACK_PCONN_TLS)
-#define        LDAP_BACK_PCONN_ID(lc)  (LDAP_BACK_PCONN_ISPRIV((lc)) ? LDAP_BACK_PCONN_PRIV : (lc)->lc_conn->c_connid )
+#define        LDAP_BACK_PCONN                 ((void *)0x0)
+#define        LDAP_BACK_PCONN_TLS             ((void *)0x1)
+#define        LDAP_BACK_PCONN_BIND            ((void *)0x2)
+#define        LDAP_BACK_PCONN_BIND_TLS        ((void *)0x3)
+#define        LDAP_BACK_PCONN_LAST            ((void *)0x4)
+#define LDAP_BACK_PCONN_ISPRIV(lc)     ((void *)(lc)->lc_conn < LDAP_BACK_PCONN_LAST)
+#define        LDAP_BACK_PCONN_ID(lc)          (LDAP_BACK_PCONN_ISPRIV((lc)) ? ( -1 - (long)(lc)->lc_conn ): (lc)->lc_conn->c_connid )
 #ifdef HAVE_TLS
-#define        LDAP_BACK_PCONN_SET(op) ((op)->o_conn->c_is_tls ? LDAP_BACK_PCONN_TLS : LDAP_BACK_PCONN)
+#define        LDAP_BACK_PCONN_SET(op)         ((op)->o_conn->c_is_tls ? LDAP_BACK_PCONN_TLS : LDAP_BACK_PCONN)
+#define        LDAP_BACK_PCONN_BIND_SET(op)    ((op)->o_conn->c_is_tls ? LDAP_BACK_PCONN_BIND_TLS : LDAP_BACK_PCONN_BIND)
 #else /* ! HAVE_TLS */
-#define        LDAP_BACK_PCONN_SET(op) (LDAP_BACK_PCONN)
+#define        LDAP_BACK_PCONN_SET(op)         (LDAP_BACK_PCONN)
+#define        LDAP_BACK_PCONN_BIND_SET(op)    (LDAP_BACK_PCONN_BIND)
 #endif /* ! HAVE_TLS */
 
        LDAP                    *lc_ld;
@@ -79,6 +83,8 @@ typedef struct ldapconn_t {
 #define        LDAP_BACK_CONN_CLEAR(lc,f)      LDAP_BACK_CONN_CLEAR_F(&(lc)->lc_lcflags, (f))
 #define        LDAP_BACK_CONN_CPY(lc,f,mlc)    LDAP_BACK_CONN_CPY_F(&(lc)->lc_lcflags, (f), &(mlc)->lc_lcflags)
 
+/* 0xFFF00000U are reserved for back-meta */
+
 #define        LDAP_BACK_FCONN_ISBOUND (0x00000001U)
 #define        LDAP_BACK_FCONN_ISANON  (0x00000002U)
 #define        LDAP_BACK_FCONN_ISBMASK (LDAP_BACK_FCONN_ISBOUND|LDAP_BACK_FCONN_ISANON)
@@ -88,8 +94,6 @@ typedef struct ldapconn_t {
 #define        LDAP_BACK_FCONN_TAINTED (0x00000020U)
 #define        LDAP_BACK_FCONN_ISIDASR (0x00000040U)
 
-/* 0x00FF0000 are reserved for back-meta */
-
 #define        LDAP_BACK_CONN_ISBOUND(lc)              LDAP_BACK_CONN_ISSET((lc), LDAP_BACK_FCONN_ISBOUND)
 #define        LDAP_BACK_CONN_ISBOUND_SET(lc)          LDAP_BACK_CONN_SET((lc), LDAP_BACK_FCONN_ISBOUND)
 #define        LDAP_BACK_CONN_ISBOUND_CLEAR(lc)        LDAP_BACK_CONN_CLEAR((lc), LDAP_BACK_FCONN_ISBMASK)
@@ -171,12 +175,13 @@ typedef struct slap_idassert_t {
 #define        li_idassert_tls         li_idassert.si_bc.sb_tls
 
        unsigned        si_flags;
-#define LDAP_BACK_AUTH_NONE                            0x00U
-#define        LDAP_BACK_AUTH_NATIVE_AUTHZ                     0x01U
-#define        LDAP_BACK_AUTH_OVERRIDE                         0x02U
-#define        LDAP_BACK_AUTH_PRESCRIPTIVE                     0x04U
-#define        LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ             0x08U
-#define        LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND     0x10U
+#define LDAP_BACK_AUTH_NONE                            (0x00U)
+#define        LDAP_BACK_AUTH_NATIVE_AUTHZ                     (0x01U)
+#define        LDAP_BACK_AUTH_OVERRIDE                         (0x02U)
+#define        LDAP_BACK_AUTH_PRESCRIPTIVE                     (0x04U)
+#define        LDAP_BACK_AUTH_OBSOLETE_PROXY_AUTHZ             (0x08U)
+#define        LDAP_BACK_AUTH_OBSOLETE_ENCODING_WORKAROUND     (0x10U)
+#define        LDAP_BACK_AUTH_AUTHZ_ALL                        (0x20U)
 #define        li_idassert_flags       li_idassert.si_flags
 
        BerVarray       si_authz;
@@ -222,31 +227,35 @@ typedef struct ldapinfo_t {
 #define LDAP_BACK_RETRY_DEFAULT                (3)
 
        unsigned        li_flags;
-#define LDAP_BACK_F_NONE               (0x0000U)
-#define LDAP_BACK_F_SAVECRED           (0x0001U)
-#define LDAP_BACK_F_USE_TLS            (0x0002U)
-#define LDAP_BACK_F_PROPAGATE_TLS      (0x0004U)
-#define LDAP_BACK_F_TLS_CRITICAL       (0x0008U)
+
+/* 0xFFF00000U are reserved for back-meta */
+
+#define LDAP_BACK_F_NONE               (0x00000000U)
+#define LDAP_BACK_F_SAVECRED           (0x00000001U)
+#define LDAP_BACK_F_USE_TLS            (0x00000002U)
+#define LDAP_BACK_F_PROPAGATE_TLS      (0x00000004U)
+#define LDAP_BACK_F_TLS_CRITICAL       (0x00000008U)
 #define LDAP_BACK_F_TLS_USE_MASK       (LDAP_BACK_F_USE_TLS|LDAP_BACK_F_TLS_CRITICAL)
 #define LDAP_BACK_F_TLS_PROPAGATE_MASK (LDAP_BACK_F_PROPAGATE_TLS|LDAP_BACK_F_TLS_CRITICAL)
 #define LDAP_BACK_F_TLS_MASK           (LDAP_BACK_F_TLS_USE_MASK|LDAP_BACK_F_TLS_PROPAGATE_MASK)
-#define LDAP_BACK_F_CHASE_REFERRALS    (0x0010U)
-#define LDAP_BACK_F_PROXY_WHOAMI       (0x0020U)
+#define LDAP_BACK_F_CHASE_REFERRALS    (0x00000010U)
+#define LDAP_BACK_F_PROXY_WHOAMI       (0x00000020U)
 
-#define        LDAP_BACK_F_T_F                 (0x0040U)
-#define        LDAP_BACK_F_T_F_DISCOVER        (0x0080U)
+#define        LDAP_BACK_F_T_F                 (0x00000040U)
+#define        LDAP_BACK_F_T_F_DISCOVER        (0x00000080U)
 #define        LDAP_BACK_F_T_F_MASK            (LDAP_BACK_F_T_F)
 #define        LDAP_BACK_F_T_F_MASK2           (LDAP_BACK_F_T_F_MASK|LDAP_BACK_F_T_F_DISCOVER)
 
-#define LDAP_BACK_F_MONITOR            (0x0100U)
-#define        LDAP_BACK_F_SINGLECONN          (0x0200U)
+#define LDAP_BACK_F_MONITOR            (0x00000100U)
+#define        LDAP_BACK_F_SINGLECONN          (0x00000200U)
+#define LDAP_BACK_F_USE_TEMPORARIES    (0x00000400U)
 
-#define        LDAP_BACK_F_ISOPEN              (0x0400U)
+#define        LDAP_BACK_F_ISOPEN              (0x00000800U)
 
-#define        LDAP_BACK_F_CANCEL_ABANDON      (0x0000U)
-#define        LDAP_BACK_F_CANCEL_IGNORE       (0x1000U)
-#define        LDAP_BACK_F_CANCEL_EXOP         (0x2000U)
-#define        LDAP_BACK_F_CANCEL_EXOP_DISCOVER        (0x4000U)
+#define        LDAP_BACK_F_CANCEL_ABANDON      (0x00000000U)
+#define        LDAP_BACK_F_CANCEL_IGNORE       (0x00001000U)
+#define        LDAP_BACK_F_CANCEL_EXOP         (0x00002000U)
+#define        LDAP_BACK_F_CANCEL_EXOP_DISCOVER        (0x00004000U)
 #define        LDAP_BACK_F_CANCEL_MASK         (LDAP_BACK_F_CANCEL_IGNORE|LDAP_BACK_F_CANCEL_EXOP)
 #define        LDAP_BACK_F_CANCEL_MASK2        (LDAP_BACK_F_CANCEL_MASK|LDAP_BACK_F_CANCEL_EXOP_DISCOVER)
 
@@ -265,6 +274,7 @@ typedef struct ldapinfo_t {
 
 #define LDAP_BACK_MONITOR(li)          LDAP_BACK_ISSET( (li), LDAP_BACK_F_MONITOR )
 #define        LDAP_BACK_SINGLECONN(li)        LDAP_BACK_ISSET( (li), LDAP_BACK_F_SINGLECONN )
+#define        LDAP_BACK_USE_TEMPORARIES(li)   LDAP_BACK_ISSET( (li), LDAP_BACK_F_USE_TEMPORARIES)
 
 #define        LDAP_BACK_ISOPEN(li)            LDAP_BACK_ISSET( (li), LDAP_BACK_F_ISOPEN )
 
index 55151b8be8e47b5d1a95ef1644cb0f26041c8435..4036106abda572016298b0c192de6f756b640c4b 100644 (file)
@@ -104,11 +104,12 @@ ldap_back_conndnlc_cmp( const void *c1, const void *c2 );
 int
 ldap_back_bind( Operation *op, SlapReply *rs )
 {
-       ldapinfo_t      *li = (ldapinfo_t *) op->o_bd->be_private;
-       ldapconn_t      *lc;
+       ldapinfo_t              *li = (ldapinfo_t *) op->o_bd->be_private;
+       ldapconn_t              *lc;
 
-       int rc = 0;
-       ber_int_t msgid;
+       int                     rc = 0;
+       ber_int_t               msgid;
+       ldap_back_send_t        retrying = LDAP_BACK_RETRYING;
 
        lc = ldap_back_getconn( op, rs, LDAP_BACK_BIND_SERR, NULL, NULL );
        if ( !lc ) {
@@ -121,24 +122,35 @@ ldap_back_bind( Operation *op, SlapReply *rs )
        }
        LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
 
+retry:;
        /* method is always LDAP_AUTH_SIMPLE if we got here */
        rs->sr_err = ldap_sasl_bind( lc->lc_ld, op->o_req_dn.bv_val,
                        LDAP_SASL_SIMPLE,
                        &op->orb_cred, op->o_ctrls, NULL, &msgid );
+       /* FIXME: should we always retry, or only when piping the bind
+        * in the "override" connection pool? */
        rc = ldap_back_op_result( lc, op, rs, msgid,
                li->li_timeout[ SLAP_OP_BIND ],
-               LDAP_BACK_BIND_SERR );
+               LDAP_BACK_BIND_SERR | retrying );
+       if ( rc == LDAP_UNAVAILABLE && retrying ) {
+               retrying &= ~LDAP_BACK_RETRYING;
+               if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_BIND_SERR ) ) {
+                       goto retry;
+               }
+       }
+
        if ( rc == LDAP_SUCCESS ) {
                /* If defined, proxyAuthz will be used also when
                 * back-ldap is the authorizing backend; for this
                 * purpose, after a successful bind the connection
-                * is trashed and further operations will use
-                * a default connections with identity assertion */
+                * is left for further binds, and further operations 
+                * on this client connection will use a default
+                * connection with identity assertion */
                /* NOTE: use with care */
                if ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) {
-                       LDAP_BACK_CONN_TAINTED_SET( lc );
+                       assert( lc->lc_binding == 1 );
+                       lc->lc_binding = 0;
                        ldap_back_release_conn( op, rs, lc );
-
                        return( rc );
                }
 
@@ -632,7 +644,8 @@ ldap_back_getconn(
        ldapconn_t      *lc = NULL,
                        lc_curr = { 0 };
        int             refcnt = 1,
-                       binding = 1;
+                       binding = 1,
+                       lookupconn = !( sendok & LDAP_BACK_BINDING );
 
        /* if the server is quarantined, and
         * - the current interval did not expire yet, or
@@ -672,19 +685,50 @@ ldap_back_getconn(
                lc_curr.lc_conn = LDAP_BACK_PCONN_SET( op );
 
        } else {
-               lc_curr.lc_local_ndn = op->o_ndn;
-               /* Explicit binds must not be shared */
+               struct berval   tmpbinddn,
+                               tmpbindcred,
+                               save_o_dn,
+                               save_o_ndn;
+               int             isproxyauthz;
+
+               /* need cleanup */
+               if ( binddn == NULL ) {
+                       binddn = &tmpbinddn;
+               }       
+               if ( bindcred == NULL ) {
+                       bindcred = &tmpbindcred;
+               }
                if ( op->o_tag == LDAP_REQ_BIND ) {
+                       save_o_dn = op->o_dn;
+                       save_o_ndn = op->o_ndn;
+                       op->o_dn = op->o_req_dn;
+                       op->o_ndn = op->o_req_ndn;
+               }
+               isproxyauthz = ldap_back_is_proxy_authz( op, rs, sendok, binddn, bindcred );
+               if ( op->o_tag == LDAP_REQ_BIND ) {
+                       op->o_dn = save_o_dn;
+                       op->o_ndn = save_o_ndn;
+               }
+
+               lc_curr.lc_local_ndn = op->o_ndn;
+               /* Explicit binds must not be shared;
+                * however, explicit binds are piped in a special connection
+                * when idassert is to occur with "override" set */
+               if ( op->o_tag == LDAP_REQ_BIND && !isproxyauthz ) {
                        lc_curr.lc_conn = op->o_conn;
 
                } else {
-                       if ( !( sendok & LDAP_BACK_BINDING ) && 
-                               ldap_back_is_proxy_authz( op, rs, sendok, binddn, bindcred ) )
-                       {
+                       if ( isproxyauthz && !( sendok & LDAP_BACK_BINDING ) ) {
                                lc_curr.lc_local_ndn = *binddn;
                                lc_curr.lc_conn = LDAP_BACK_PCONN_SET( op );
                                LDAP_BACK_CONN_ISIDASSERT_SET( &lc_curr );
 
+                       } else if ( isproxyauthz && ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) {
+                               lc_curr.lc_local_ndn = slap_empty_bv;
+                               lc_curr.lc_conn = LDAP_BACK_PCONN_BIND_SET( op );
+                               LDAP_BACK_CONN_ISIDASSERT_SET( &lc_curr );
+                               lookupconn = 1;
+
                        } else if ( SLAP_IS_AUTHZ_BACKEND( op ) ) {
                                lc_curr.lc_conn = op->o_conn;
 
@@ -695,7 +739,7 @@ ldap_back_getconn(
        }
 
        /* Explicit Bind requests always get their own conn */
-       if ( !( sendok & LDAP_BACK_BINDING ) ) {
+       if ( lookupconn ) {
                /* Searches for a ldapconn in the avl tree */
 retry_lock:
                ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
@@ -705,13 +749,26 @@ retry_lock:
                if ( lc != NULL ) {
                        /* Don't reuse connections while they're still binding */
                        if ( LDAP_BACK_CONN_BINDING( lc ) ) {
-                               ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
-                               ldap_pvt_thread_yield();
-                               goto retry_lock;
-                       }
+                               if ( !LDAP_BACK_USE_TEMPORARIES( li ) ) {
+                                       ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
+
+                                       ldap_pvt_thread_yield();
+                                       goto retry_lock;
+                               }
+
+                               lc = NULL;
+
+                       } else {
+
+                               if ( op->o_tag == LDAP_REQ_BIND ) {
+                                       /* right now, this is the only possible case */
+                                       assert( ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) );
+                                       LDAP_BACK_CONN_BINDING_SET( lc );
+                               }
 
-                       refcnt = ++lc->lc_refcnt;
-                       binding = ++lc->lc_binding;
+                               refcnt = ++lc->lc_refcnt;
+                               binding = ++lc->lc_binding;
+                       }
                }
                ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
        }
@@ -825,21 +882,14 @@ retry_lock:
                        break;
 
                case -1:
-                       if ( !( sendok & LDAP_BACK_BINDING ) ) {
+                       if ( !( sendok & LDAP_BACK_BINDING ) && !LDAP_BACK_USE_TEMPORARIES( li ) ) {
                                /* duplicate: free and try to get the newly created one */
+                               ldap_back_conn_free( lc );
+                               lc = NULL;
                                goto retry_lock;
                        }
+
                        /* taint connection, so that it'll be freed when released */
-                       ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
-#if LDAP_BACK_PRINT_CONNTREE > 0
-                       ldap_back_print_conntree( li->li_conninfo.lai_tree, ">>> ldap_back_getconn(delete)" );
-#endif /* LDAP_BACK_PRINT_CONNTREE */
-                       (void *)avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc,
-                                       ldap_back_conndnlc_cmp );
-#if LDAP_BACK_PRINT_CONNTREE > 0
-                       ldap_back_print_conntree( li->li_conninfo.lai_tree, "<<< ldap_back_getconn(delete)" );
-#endif /* LDAP_BACK_PRINT_CONNTREE */
-                       ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
                        LDAP_BACK_CONN_TAINTED_SET( lc );
                        break;
 
@@ -926,7 +976,7 @@ ldap_back_quarantine(
        Operation       *op,
        SlapReply       *rs )
 {
-       ldapinfo_t      *li = (ldapinfo_t *)op->o_bd->be_private;
+       ldapinfo_t              *li = (ldapinfo_t *)op->o_bd->be_private;
 
        slap_retry_info_t       *ri = &li->li_quarantine;
 
@@ -971,9 +1021,13 @@ ldap_back_quarantine(
                ri->ri_last = new_last;
 
        } else if ( li->li_isquarantined != LDAP_BACK_FQ_NO ) {
+               if ( ri->ri_last == slap_get_time() ) {
+                       goto done;
+               }
+
                Debug( LDAP_DEBUG_ANY,
-                       "%s: ldap_back_quarantine exit.\n",
-                       op->o_log_prefix, ri->ri_idx, ri->ri_count );
+                       "%s: ldap_back_quarantine exit (%d) err=%d.\n",
+                       op->o_log_prefix, li->li_isquarantined, rs->sr_err );
 
                if ( li->li_quarantine_f ) {
                        (void)li->li_quarantine_f( li, li->li_quarantine_p );
@@ -1466,7 +1520,7 @@ retry:;
                 * LDAP_COMPARE_{TRUE|FALSE}) */
                default:
                        /* only touch when activity actually took place... */
-                       if ( li->li_idle_timeout ) {
+                       if ( li->li_idle_timeout && lc ) {
                                lc->lc_time = op->o_time;
                        }
 
@@ -1590,6 +1644,9 @@ ldap_back_retry( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_
                        *lcp = NULL;
                        rc = 0;
 
+               } else if ( ( sendok & LDAP_BACK_BINDING ) ) {
+                       rc = 1;
+
                } else {
                        rc = ldap_back_dobind_int( lcp, op, rs, sendok, 0, 0 );
                        if ( rc == 0 && *lcp != NULL ) {
index d43ef4d8d53196cbe8493c5404e23cb2ddf35d20..ad2bf7c02c7ab61c88bbbb316b926a829f42f489 100644 (file)
@@ -65,6 +65,7 @@ enum {
        LDAP_BACK_CFG_NETWORK_TIMEOUT,
        LDAP_BACK_CFG_VERSION,
        LDAP_BACK_CFG_SINGLECONN,
+       LDAP_BACK_CFG_USETEMP,
        LDAP_BACK_CFG_CANCEL,
        LDAP_BACK_CFG_QUARANTINE,
        LDAP_BACK_CFG_REWRITE,
@@ -277,6 +278,14 @@ static ConfigTable ldapcfg[] = {
                        "SYNTAX OMsDirectoryString "
                        "SINGLE-VALUE )",
                NULL, NULL },
+       { "use-temporaries", "TRUE/FALSE", 2, 0, 0,
+               ARG_MAGIC|ARG_ON_OFF|LDAP_BACK_CFG_USETEMP,
+               ldap_back_cf_gen, "( OLcfgDbAt:3.22 "
+                       "NAME 'olcDbUseTemporaries' "
+                       "DESC 'Use temporary connections if the cached one is busy' "
+                       "SYNTAX OMsBoolean "
+                       "SINGLE-VALUE )",
+               NULL, NULL },
        { "suffixmassage", "[virtual]> <real", 2, 3, 0,
                ARG_STRING|ARG_MAGIC|LDAP_BACK_CFG_REWRITE,
                ldap_back_cf_gen, NULL, NULL, NULL },
@@ -314,6 +323,7 @@ static ConfigOCs ldapocs[] = {
                        "$ olcDbSingleConn "
                        "$ olcDbCancel "
                        "$ olcDbQuarantine "
+                       "$ olcDbUseTemporaries "
                ") )",
                        Cft_Database, ldapcfg},
        { NULL, 0, NULL }
@@ -530,15 +540,42 @@ slap_idassert_authzfrom_parse( ConfigArgs *c, slap_idassert_t *si )
        struct berval   in;
        int             rc;
 
-       ber_str2bv( c->argv[ 1 ], 0, 0, &in );
-       rc = authzNormalize( 0, NULL, NULL, &in, &bv, NULL );
-       if ( rc != LDAP_SUCCESS ) {
-               snprintf( c->msg, sizeof( c->msg ),
-                       "\"idassert-authzFrom <authz>\": "
-                       "invalid syntax" );
-               Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
-               return 1;
-       }
+       if ( strcmp( c->argv[ 1 ], "*" ) == 0
+               || strcmp( c->argv[ 1 ], ".*" ) == 0
+               || strcmp( c->argv[ 1 ], "dn:*" ) == 0
+               || strcasecmp( c->argv[ 1 ], "dn.regex:.*" ) == 0 )
+       {
+               if ( si->si_authz != NULL ) {
+                       snprintf( c->msg, sizeof( c->msg ),
+                               "\"idassert-authzFrom <authz>\": "
+                               "\"%s\" conflicts with existing authz rules",
+                               c->argv[ 1 ] );
+                       Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+                       return 1;
+               }
+               si->si_flags |= LDAP_BACK_AUTH_AUTHZ_ALL;
+               return 0;
+       } else if ( ( si->si_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) ) {
+               snprintf( c->msg, sizeof( c->msg ),
+                       "\"idassert-authzFrom <authz>\": "
+                       "\"<authz>\" conflicts with \"*\"" );
+               Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+               return 1;
+       }
+       
+       ber_str2bv( c->argv[ 1 ], 0, 0, &in );
+       rc = authzNormalize( 0, NULL, NULL, &in, &bv, NULL );
+       if ( rc != LDAP_SUCCESS ) {
+               snprintf( c->msg, sizeof( c->msg ),
+                       "\"idassert-authzFrom <authz>\": "
+                       "invalid syntax" );
+               Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
+               return 1;
+       }
+  
        ber_bvarray_add( &si->si_authz, &bv );
 
        return 0;
@@ -776,7 +813,13 @@ ldap_back_cf_gen( ConfigArgs *c )
                        int             i;
 
                        if ( li->li_idassert_authz == NULL ) {
-                               rc = 1;
+                               if ( ( li->li_idassert_flags & LDAP_BACK_AUTH_AUTHZ_ALL ) ) {
+                                       BER_BVSTR( &bv, "*" );
+                                       value_add_one( &c->rvalue_vals, &bv );
+
+                               } else {
+                                       rc = 1;
+                               }
                                break;
                        }
 
@@ -1013,6 +1056,10 @@ ldap_back_cf_gen( ConfigArgs *c )
                        c->value_int = LDAP_BACK_SINGLECONN( li );
                        break;
 
+               case LDAP_BACK_CFG_USETEMP:
+                       c->value_int = LDAP_BACK_USE_TEMPORARIES( li );
+                       break;
+
                case LDAP_BACK_CFG_CANCEL: {
                        slap_mask_t     mask = LDAP_BACK_F_CANCEL_MASK2;
 
@@ -1139,6 +1186,10 @@ ldap_back_cf_gen( ConfigArgs *c )
                        li->li_flags &= ~LDAP_BACK_F_SINGLECONN;
                        break;
 
+               case LDAP_BACK_CFG_USETEMP:
+                       li->li_flags &= ~LDAP_BACK_F_USE_TEMPORARIES;
+                       break;
+
                case LDAP_BACK_CFG_QUARANTINE:
                        if ( !LDAP_BACK_QUARANTINE( li ) ) {
                                break;
@@ -1684,6 +1735,15 @@ done_url:;
                }
                break;
 
+       case LDAP_BACK_CFG_USETEMP:
+               if ( c->value_int ) {
+                       li->li_flags |= LDAP_BACK_F_USE_TEMPORARIES;
+
+               } else {
+                       li->li_flags &= ~LDAP_BACK_F_USE_TEMPORARIES;
+               }
+               break;
+
        case LDAP_BACK_CFG_CANCEL: {
                slap_mask_t             mask;