0, 0, 0 );
 #endif
                        rc = LDAP_INSUFFICIENT_ACCESS;
+                       text = "no write access to parent";
                        goto return_results;;
                }
 
                                                0, 0, 0 );
 #endif
                                        rc = LDAP_INSUFFICIENT_ACCESS;
+                                       text = "no write access to parent";
                                        goto return_results;;
                                }
 
                        0, 0, 0 );
 #endif
                rc = LDAP_INSUFFICIENT_ACCESS;
+               text = "no write access to entry";
                goto return_results;;
        }
 
 
                if ( !rc  ) {
 #ifdef NEW_LOGGING
                        LDAP_LOG ( OPERATION, DETAIL1, 
-                               "<=- bdb_delete: no access to parent\n", 0, 0, 0 );
+                               "<=- bdb_delete: no write access to parent\n", 0, 0, 0 );
 #else
                        Debug( LDAP_DEBUG_TRACE,
-                               "<=- bdb_delete: no access to parent\n",
+                               "<=- bdb_delete: no write access to parent\n",
                                0, 0, 0 );
 #endif
                        rc = LDAP_INSUFFICIENT_ACCESS;
+                       text = "no write access to parent";
                        goto return_results;
                }
 
                                                "to parent\n", 0, 0, 0 );
 #endif
                                        rc = LDAP_INSUFFICIENT_ACCESS;
+                                       text = "no write access to parent";
                                        goto return_results;
                                }
 
        if ( !rc  ) {
 #ifdef NEW_LOGGING
                LDAP_LOG ( OPERATION, DETAIL1, 
-                       "<=- bdb_delete: no access to entry\n", 0, 0, 0 );
+                       "<=- bdb_delete: no write access to entry\n", 0, 0, 0 );
 #else
                Debug( LDAP_DEBUG_TRACE,
-                       "<=- bdb_delete: no access to entry\n",
+                       "<=- bdb_delete: no write access to entry\n",
                        0, 0, 0 );
 #endif
                rc = LDAP_INSUFFICIENT_ACCESS;
+               text = "no write access to entry";
                goto return_results;
        }
 
 
        ID               id = NOID;
        const char      *text = NULL;
        AttributeDescription *children = slap_schema.si_ad_children;
+       AttributeDescription *entry = slap_schema.si_ad_entry;
        char textbuf[SLAP_TEXT_BUFLEN];
        size_t textlen = sizeof textbuf;
 
        Debug(LDAP_DEBUG_ARGS, "==> ldbm_back_add: %s\n", e->e_dn, 0, 0);
 #endif
 
-       /* grab giant lock for writing */
-       ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock);
-
-       if ( ( rc = dn2id( be, &e->e_nname, &id ) ) || id != NOID ) {
-               /* if (rc) something bad happened to ldbm cache */
-               ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
-               send_ldap_result( conn, op, 
-                       rc ? LDAP_OTHER : LDAP_ALREADY_EXISTS,
-                       NULL, NULL, NULL, NULL );
-               return( -1 );
-       }
-
        rc = entry_schema_check( be, e, NULL, &text, textbuf, textlen );
-
        if ( rc != LDAP_SUCCESS ) {
-               ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
-
 #ifdef NEW_LOGGING
                LDAP_LOG( BACK_LDBM, ERR, 
                        "ldbm_back_add: entry (%s) failed schema check.\n", e->e_dn, 0, 0 );
                return( -1 );
        }
 
+       if ( ! access_allowed( be, conn, op, e,
+               entry, NULL, ACL_WRITE, NULL ) )
+       {
+#ifdef NEW_LOGGING
+               LDAP_LOG( BACK_LDBM, ERR, 
+                       "ldbm_back_add: No write access to entry (%s).\n", 
+                       e->e_dn, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_TRACE, "no write access to entry\n", 0,
+                   0, 0 );
+#endif
+
+               send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
+                   NULL, "no write access to entry", NULL, NULL );
+
+               return -1;
+       }
+
+       /* grab giant lock for writing */
+       ldap_pvt_thread_rdwr_wlock(&li->li_giant_rwlock);
+
+       if ( ( rc = dn2id( be, &e->e_nname, &id ) ) || id != NOID ) {
+               /* if (rc) something bad happened to ldbm cache */
+               ldap_pvt_thread_rdwr_wunlock(&li->li_giant_rwlock);
+               send_ldap_result( conn, op, 
+                       rc ? LDAP_OTHER : LDAP_ALREADY_EXISTS,
+                       NULL, NULL, NULL, NULL );
+               return( -1 );
+       }
+
        /*
         * Get the parent dn and see if the corresponding entry exists.
         * If the parent does not exist, only allow the "root" user to
 
        int     rc = -1;
        int             manageDSAit = get_manageDSAit( op );
        AttributeDescription *children = slap_schema.si_ad_children;
+       AttributeDescription *entry = slap_schema.si_ad_entry;
 
 #ifdef NEW_LOGGING
        LDAP_LOG( BACK_LDBM, ENTRY, "ldbm_back_delete: %s\n", dn->bv_val, 0, 0 );
                return( -1 );
        }
 
+       /* check entry for "entry" acl */
+       if ( ! access_allowed( be, conn, op, e,
+               entry, NULL, ACL_WRITE, NULL ) )
+       {
+#ifdef NEW_LOGGING
+               LDAP_LOG( BACK_LDBM, ERR, 
+                       "ldbm_back_delete: no write access to entry of (%s)\n", 
+                       dn->bv_val, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_TRACE,
+                       "<=- ldbm_back_delete: no write access to entry\n", 0,
+                       0, 0 );
+#endif
+
+               send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
+                       NULL, "no write access to entry", NULL, NULL );
+
+               rc = 1;
+               goto return_results;
+       }
+
     if ( !manageDSAit && is_entry_referral( e ) ) {
                /* parent is a referral, don't allow add */
                /* parent is an alias, don't allow add */
                goto return_results;
        }
 
-
        if ( has_children( be, e ) ) {
 #ifdef NEW_LOGGING
                LDAP_LOG( BACK_LDBM, ERR, 
 #endif
 
                        send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
-                               NULL, NULL, NULL, NULL );
+                               NULL, "no write access to parent", NULL, NULL );
                        goto return_results;
                }
 
                                                "access to parent\n", 0, 0, 0 );
 #endif
 
-                                       send_ldap_result( conn, op, 
-                                               LDAP_INSUFFICIENT_ACCESS,
-                                               NULL, NULL, NULL, NULL );
+                                       send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
+                                               NULL, "no write access to parent", NULL, NULL );
                                        goto return_results;
                                }
 
 
 )
 {
        AttributeDescription *children = slap_schema.si_ad_children;
+       AttributeDescription *entry = slap_schema.si_ad_entry;
        struct ldbminfo *li = (struct ldbminfo *) be->be_private;
        struct berval   p_dn, p_ndn;
        struct berval   new_dn = { 0, NULL}, new_ndn = { 0, NULL };
                return( -1 );
        }
 
+       /* check entry for "entry" acl */
+       if ( ! access_allowed( be, conn, op, e,
+               entry, NULL, ACL_WRITE, NULL ) )
+       {
+#ifdef NEW_LOGGING
+               LDAP_LOG( BACK_LDBM, ERR, 
+                       "ldbm_back_modrdn: no write access to entry of (%s)\n", 
+                       dn->bv_val, 0, 0 );
+#else
+               Debug( LDAP_DEBUG_TRACE,
+                       "<=- ldbm_back_modrdn: no write access to entry\n", 0,
+                       0, 0 );
+#endif
+
+               send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
+                       NULL, "no write access to entry", NULL, NULL );
+
+               goto return_results;
+       }
+
        if (!manageDSAit && is_entry_referral( e ) ) {
                /* parent is a referral, don't allow add */
                /* parent is an alias, don't allow add */
 
 )
 {
        struct shellinfo        *si = (struct shellinfo *) be->be_private;
+       AttributeDescription *entry = slap_schema.si_ad_entry;
        FILE                    *rfp, *wfp;
        int                     len;
 
                return( -1 );
        }
 
+       if ( ! access_allowed( be, conn, op, e,
+               entry, NULL, ACL_WRITE, NULL ) )
+       {
+               send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
+                       NULL, NULL, NULL, NULL );
+               return -1;
+       }
+
        if ( (op->o_private = (void *) forkandexec( si->si_add, &rfp, &wfp )) == (void *) -1 ) {
                send_ldap_result( conn, op, LDAP_OTHER, NULL,
                    "could not fork/exec", NULL, NULL );
 
 )
 {
        struct shellinfo        *si = (struct shellinfo *) be->be_private;
+       AttributeDescription *entry = slap_schema.si_ad_entry;
+       Entry e;
        FILE                    *rfp, *wfp;
 
        if ( IS_NULLCMD( si->si_delete ) ) {
                return( -1 );
        }
 
+       e.e_id = NOID;
+       e.e_name = *dn;
+       e.e_nname = *ndn;
+       e.e_attrs = NULL;
+       e.e_ocflags = 0;
+       e.e_bv.bv_len = 0;
+       e.e_bv.bv_val = NULL;
+       e.e_private = NULL;
+
+       if ( ! access_allowed( be, conn, op, &e,
+               entry, NULL, ACL_WRITE, NULL ) )
+       {
+               send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
+                       NULL, NULL, NULL, NULL );
+               return -1;
+       }
+
        if ( (op->o_private = (void *) forkandexec( si->si_delete, &rfp, &wfp ))
            == (void *) -1 ) {
                send_ldap_result( conn, op, LDAP_OTHER, NULL,
 
 )
 {
        struct shellinfo        *si = (struct shellinfo *) be->be_private;
+       AttributeDescription *entry = slap_schema.si_ad_entry;
+       Entry e;
        FILE                    *rfp, *wfp;
 
        if ( IS_NULLCMD( si->si_modrdn ) ) {
                return( -1 );
        }
 
+       e.e_id = NOID;
+       e.e_name = *dn;
+       e.e_nname = *ndn;
+       e.e_attrs = NULL;
+       e.e_ocflags = 0;
+       e.e_bv.bv_len = 0;
+       e.e_bv.bv_val = NULL;
+       e.e_private = NULL;
+
+       if ( ! access_allowed( be, conn, op, &e,
+               entry, NULL, ACL_WRITE, NULL ) )
+       {
+               send_ldap_result( conn, op, LDAP_INSUFFICIENT_ACCESS,
+                       NULL, NULL, NULL, NULL );
+               return -1;
+       }
+
        if ( (op->o_private = (void *) forkandexec( si->si_modrdn, &rfp, &wfp ))
            == (void *) -1 ) {
                send_ldap_result( conn, op, LDAP_OTHER, NULL,