]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/slapi/slapi_utils.c
Sync with HEAD
[openldap] / servers / slapd / slapi / slapi_utils.c
index 6cd270f828b0411d424908c5d7ce04cf7e552bda..7805a319a1506518fc1651bcec9815154a2253ef 100644 (file)
@@ -1,20 +1,23 @@
-/*
- * Copyright 1998-2003 The OpenLDAP Foundation, All Rights Reserved.
- * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
- */
-/*
- * (C) Copyright IBM Corp. 1997,2002
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is 
- * given to IBM Corporation. This software is provided ``as is'' 
- * without express or implied warranty.
+/* $OpenLDAP$ */
+/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
+ *
+ * Copyright 2002-2003 The OpenLDAP Foundation.
+ * Portions Copyright 1997,2002-2003 IBM Corporation.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted only as authorized by the OpenLDAP
+ * Public License.
+ *
+ * A copy of this license is available in the file LICENSE in the
+ * top-level directory of the distribution or, alternatively, at
+ * <http://www.OpenLDAP.org/license.html>.
  */
-/*
- * Portions (C) Copyright PADL Software Pty Ltd. 2003
- * Redistribution and use in source and binary forms are permitted
- * provided that this notice is preserved and that due credit is 
- * given to PADL Software Pty Ltd. This software is provided ``as is'' 
- * without express or implied warranty.
+/* ACKNOWLEDGEMENTS:
+ * This work was initially developed by IBM Corporation for use in
+ * IBM products and subsequently ported to OpenLDAP Software by
+ * Steve Omrani.  Additional significant contributors include:
+ *   Luke Howard
  */
 
 #include "portable.h"
 #include <slap.h>
 #include <slapi.h>
 
-#ifdef _SPARC  
-#include <sys/systeminfo.h>
-#endif
-
 #include <netdb.h>
 
 /*
@@ -169,26 +168,7 @@ Slapi_Entry *
 slapi_entry_dup( Slapi_Entry *e ) 
 {
 #ifdef LDAP_SLAPI
-       char            *tmp = NULL;
-       Slapi_Entry     *tmpEnt;
-       int             len = 0;
-       
-       tmp = slapi_entry2str( e, &len );
-       if ( tmp == NULL ) {
-               return (Slapi_Entry *)NULL;
-       }
-
-       tmpEnt = (Slapi_Entry *)str2entry( tmp );
-       if ( tmpEnt == NULL ) { 
-               slapi_ch_free( (void **)&tmp );
-               return (Slapi_Entry *)NULL;
-       }
-       
-       if (tmp != NULL) {
-               slapi_ch_free( (void **)&tmp );
-       }
-
-       return tmpEnt;
+       return entry_dup( e );
 #else /* LDAP_SLAPI */
        return NULL;
 #endif /* LDAP_SLAPI */
@@ -930,6 +910,139 @@ slapi_dn_issuffix(
 #endif /* LDAP_SLAPI */
 }
 
+int
+slapi_dn_isparent(
+       const char      *parentdn,
+       const char      *childdn )
+{
+#ifdef LDAP_SLAPI
+       struct berval   assertedParentDN, normalizedAssertedParentDN;
+       struct berval   childDN, normalizedChildDN;
+       struct berval   normalizedParentDN;
+       int             match;
+
+       assert( parentdn != NULL );
+       assert( childdn != NULL );
+
+       assertedParentDN.bv_val = (char *)parentdn;
+       assertedParentDN.bv_len = strlen( parentdn );
+
+       if ( dnNormalize( 0, NULL, NULL, &assertedParentDN,
+               &normalizedAssertedParentDN, NULL ) != LDAP_SUCCESS )
+       {
+               return 0;
+       }
+
+       childDN.bv_val = (char *)childdn;
+       childDN.bv_len = strlen( childdn );
+
+       if ( dnNormalize( 0, NULL, NULL, &childDN,
+               &normalizedChildDN, NULL ) != LDAP_SUCCESS )
+       {
+               slapi_ch_free( (void **)&normalizedAssertedParentDN.bv_val );
+               return 0;
+       }
+
+       dnParent( &normalizedChildDN, &normalizedParentDN );
+
+       if ( dnMatch( &match, 0, slap_schema.si_syn_distinguishedName, NULL,
+               &normalizedParentDN, (void *)&normalizedAssertedParentDN ) != LDAP_SUCCESS )
+       {
+               match = -1;
+       }
+
+       slapi_ch_free( (void **)&normalizedAssertedParentDN.bv_val );
+       slapi_ch_free( (void **)&normalizedChildDN.bv_val );
+
+       return ( match == 0 );
+#else
+       return 0;
+#endif /* LDAP_SLAPI */
+}
+
+/*
+ * Returns DN of the parent entry, or NULL if the DN is
+ * an empty string or NULL, or has no parent.
+ */
+char *
+slapi_dn_parent( const char *_dn )
+{
+#ifdef LDAP_SLAPI
+       struct berval   dn, prettyDN;
+       struct berval   parentDN;
+
+       if ( _dn == NULL ) {
+               return NULL;
+       }
+
+       dn.bv_val = (char *)_dn;
+       dn.bv_len = strlen( _dn );
+
+       if ( dn.bv_len == 0 ) {
+               return NULL;
+       }
+
+       if ( dnPretty( NULL, &dn, &prettyDN, NULL ) != LDAP_SUCCESS ) {
+               return NULL;
+       }
+
+       dnParent( &prettyDN, &parentDN ); /* in-place */
+
+       slapi_ch_free( (void **)&prettyDN.bv_val );
+
+       if ( parentDN.bv_len == 0 ) {
+               return NULL;
+       }
+
+       return slapi_ch_strdup( parentDN.bv_val );
+#else
+       return NULL;
+#endif /* LDAP_SLAPI */
+}
+
+/*
+ * Returns DN of the parent entry; or NULL if the DN is
+ * an empty string, if the DN has no parent, or if the
+ * DN is the suffix of the backend database
+ */
+char *slapi_dn_beparent( Slapi_PBlock *pb, const char *_dn )
+{
+#ifdef LDAP_SLAPI
+       Backend         *be;
+       struct berval   dn, prettyDN;
+       struct berval   normalizedDN, parentDN;
+
+       if ( slapi_pblock_get( pb, SLAPI_BACKEND, (void **)&be ) != 0 )
+               be = NULL;
+
+       dn.bv_val = (char *)_dn;
+       dn.bv_len = strlen( _dn );
+
+       if ( dnPrettyNormal( NULL, &dn, &prettyDN, &normalizedDN, NULL ) != LDAP_SUCCESS ) {
+               return NULL;
+       }
+
+       if ( be != NULL && be_issuffix( be, &normalizedDN ) ) {
+               slapi_ch_free( (void **)&prettyDN.bv_val );
+               slapi_ch_free( (void **)&normalizedDN.bv_val );
+               return NULL;
+       }
+
+       dnParent( &prettyDN, &parentDN );
+
+       slapi_ch_free( (void **)&prettyDN.bv_val );
+       slapi_ch_free( (void **)&normalizedDN.bv_val );
+
+       if ( parentDN.bv_len == 0 ) {
+               return NULL;
+       }
+
+       return slapi_ch_strdup( parentDN.bv_val );
+#else
+       return NULL;
+#endif /* LDAP_SLAPI */
+}
+
 char *
 slapi_dn_ignore_case( char *dn )
 {       
@@ -1281,7 +1394,7 @@ slapi_register_supported_saslmechanism( char *mechanism )
 {
 #ifdef LDAP_SLAPI
        /* FIXME -- can not add saslmechanism to OpenLDAP dynamically */
-       slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SASL",
+       slapi_log_error( SLAPI_LOG_FATAL, "slapi_register_supported_saslmechanism",
                        "OpenLDAP does not support dynamic registration of SASL mechanisms\n" );
 #endif /* LDAP_SLAPI */
 }
@@ -1291,7 +1404,7 @@ slapi_get_supported_saslmechanisms( void )
 {
 #ifdef LDAP_SLAPI
        /* FIXME -- can not get the saslmechanism without a connection. */
-       slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SASL",
+       slapi_log_error( SLAPI_LOG_FATAL, "slapi_get_supported_saslmechanisms",
                        "can not get the SASL mechanism list "
                        "without a connection\n" );
        return NULL;
@@ -1450,6 +1563,60 @@ slapi_send_ldap_search_entry(
 #endif /* LDAP_SLAPI */
 }
 
+int 
+slapi_send_ldap_search_reference(
+       Slapi_PBlock    *pb,
+       Slapi_Entry     *e,
+       struct berval   **references,
+       LDAPControl     **ectrls, 
+       struct berval   **v2refs
+       )
+{
+#ifdef LDAP_SLAPI
+       Operation       *pOp;
+       SlapReply       rs = { REP_SEARCHREF };
+       int             rc;
+
+       rs.sr_err = LDAP_SUCCESS;
+       rs.sr_matched = NULL;
+       rs.sr_text = NULL;
+
+       rc = bvptr2obj( references, &rs.sr_ref );
+       if ( rc != LDAP_SUCCESS ) {
+               return rc;
+       }
+
+       rs.sr_ctrls = ectrls;
+       rs.sr_attrs = NULL;
+       rs.sr_entry = e;
+
+       if ( v2refs != NULL ) {
+               rc = bvptr2obj( v2refs, &rs.sr_v2ref );
+               if ( rc != LDAP_SUCCESS ) {
+                       slapi_ch_free( (void **)&rs.sr_ref );
+                       return rc;
+               }
+       } else {
+               rs.sr_v2ref = NULL;
+       }
+
+       if ( slapi_pblock_get( pb, SLAPI_OPERATION, (void *)&pOp ) != 0 ) {
+               return LDAP_OTHER;
+       }
+
+       rc = send_search_reference( pOp, &rs );
+
+       if ( rs.sr_ref != NULL )
+               slapi_ch_free( (void **)&rs.sr_ref );
+
+       if ( rs.sr_v2ref != NULL )
+               slapi_ch_free( (void **)&rs.sr_v2ref );
+
+       return rc;
+#else
+       return -1;
+#endif /* LDAP_SLAPI */
+}
 
 Slapi_Filter *
 slapi_str2filter( char *str ) 
@@ -1938,24 +2105,6 @@ slapi_get_hostname( void )
 {
 #ifdef LDAP_SLAPI
        char            *hn = NULL;
-
-       /*
-        * FIXME: I'd prefer a different check ...
-        */
-#if defined _SPARC 
-       hn = (char *)slapi_ch_malloc( MAX_HOSTNAME );
-       if ( hn == NULL) {
-               slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
-                               "can't malloc memory for hostname\n" );
-               hn = NULL;
-               
-       } else if ( sysinfo( SI_HOSTNAME, hn, MAX_HOSTNAME ) < 0 ) {
-               slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
-                               "can't get hostname\n" );
-               slapi_ch_free( (void **)&hn );
-               hn = NULL;
-       }
-#else /* !_SPARC */
        static int      been_here = 0;   
        static char     *static_hn = NULL;
 
@@ -1963,8 +2112,8 @@ slapi_get_hostname( void )
        if ( !been_here ) {
                static_hn = (char *)slapi_ch_malloc( MAX_HOSTNAME );
                if ( static_hn == NULL) {
-                       slapi_log_error( SLAPI_LOG_FATAL, "SLAPI_SYSINFO",
-                                       "can't malloc memory for hostname\n" );
+                       slapi_log_error( SLAPI_LOG_FATAL, "slapi_get_hostname",
+                                       "Cannot allocate memory for hostname\n" );
                        static_hn = NULL;
                        ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
 
@@ -1973,7 +2122,7 @@ slapi_get_hostname( void )
                } else { 
                        if ( gethostname( static_hn, MAX_HOSTNAME ) != 0 ) {
                                slapi_log_error( SLAPI_LOG_FATAL,
-                                               "SLAPI_SYSINFO",
+                                               "SLAPI",
                                                "can't get hostname\n" );
                                slapi_ch_free( (void **)&static_hn );
                                static_hn = NULL;
@@ -1989,7 +2138,6 @@ slapi_get_hostname( void )
        ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
        
        hn = ch_strdup( static_hn );
-#endif /* !_SPARC */
 
        return hn;
 #else /* LDAP_SLAPI */
@@ -2229,7 +2377,13 @@ static int initConnectionPB( Slapi_PBlock *pb, Connection *conn )
                return rc;
 
        /* Returns pointer to static string */
-       connAuthType = Authorization2AuthType( &conn->c_authz, conn->c_is_tls, 1 );
+       connAuthType = Authorization2AuthType( &conn->c_authz,
+#ifdef HAVE_TLS
+               conn->c_is_tls,
+#else
+               0,
+#endif
+               1 );
        if ( connAuthType != NULL ) {
                rc = slapi_pblock_set(pb, SLAPI_CONN_AUTHTYPE, (void *)connAuthType);
                if ( rc != LDAP_SUCCESS )
@@ -2237,20 +2391,38 @@ static int initConnectionPB( Slapi_PBlock *pb, Connection *conn )
        }
 
        /* Returns pointer to allocated string */
-       connAuthType = Authorization2AuthType( &conn->c_authz, conn->c_is_tls, 0 );
+       connAuthType = Authorization2AuthType( &conn->c_authz,
+#ifdef HAVE_TLS
+               conn->c_is_tls,
+#else
+               0,
+#endif
+               0 );
        if ( connAuthType != NULL ) {
                rc = slapi_pblock_set(pb, SLAPI_CONN_AUTHMETHOD, (void *)connAuthType);
+               /* slapi_pblock_set dups this itself */
+               slapi_ch_free( (void **)&connAuthType );
                if ( rc != LDAP_SUCCESS )
                        return rc;
        }
 
        if ( conn->c_authz.sai_dn.bv_val != NULL ) {
-               char *connDn = slapi_ch_strdup(conn->c_authz.sai_dn.bv_val);
-               rc = slapi_pblock_set(pb, SLAPI_CONN_DN, (void *)connDn);
+               /* slapi_pblock_set dups this itself */
+               rc = slapi_pblock_set(pb, SLAPI_CONN_DN, (void *)conn->c_authz.sai_dn.bv_val);
                if ( rc != LDAP_SUCCESS )
                        return rc;
        }
 
+       rc = slapi_pblock_set(pb, SLAPI_X_CONN_SSF, (void *)conn->c_ssf);
+       if ( rc != LDAP_SUCCESS )
+               return rc;
+
+       rc = slapi_pblock_set(pb, SLAPI_X_CONN_SASL_CONTEXT,
+               ( conn->c_sasl_authctx != NULL ? conn->c_sasl_authctx :
+                                                conn->c_sasl_sockctx ) );
+       if ( rc != LDAP_SUCCESS )
+               return rc;
+
        return rc;
 }
 #endif /* LDAP_SLAPI */
@@ -2258,7 +2430,7 @@ static int initConnectionPB( Slapi_PBlock *pb, Connection *conn )
 /*
  * Internal API to prime a Slapi_PBlock with an Operation.
  */
-int slapi_x_pblock_set_operation( Slapi_PBlock *pb, Operation *op )
+int slapi_int_pblock_set_operation( Slapi_PBlock *pb, Operation *op )
 {
 #ifdef LDAP_SLAPI
        int isRoot = 0;
@@ -2331,7 +2503,11 @@ int slapi_is_connection_ssl( Slapi_PBlock *pb, int *isSSL )
        Connection *conn;
 
        slapi_pblock_get( pb, SLAPI_CONNECTION, &conn );
+#ifdef HAVE_TLS
        *isSSL = conn->c_is_tls;
+#else
+       *isSSL = 0;
+#endif
 
        return LDAP_SUCCESS;
 #else
@@ -3066,14 +3242,14 @@ void slapi_valueset_set_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2)
 int slapi_access_allowed( Slapi_PBlock *pb, Slapi_Entry *e, char *attr,
        struct berval *val, int access )
 {
-#ifdef LDAPI_SLAPI
+#ifdef LDAP_SLAPI
        Backend *be;
        Connection *conn;
        Operation *op;
        int ret;
        slap_access_t slap_access;
        AttributeDescription *ad = NULL;
-       char *text;
+       const char *text;
 
        ret = slap_str2ad( attr, &ad, &text );
        if ( ret != LDAP_SUCCESS ) {
@@ -3113,7 +3289,7 @@ int slapi_access_allowed( Slapi_PBlock *pb, Slapi_Entry *e, char *attr,
                return LDAP_PARAM_ERROR;
        }
 
-       ret = access_allowed( be, conn, op, e, desc, val, slap_access, NULL );
+       ret = access_allowed( op, e, ad, val, slap_access, NULL );
 
        return ret ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS;
 #else
@@ -3125,31 +3301,39 @@ int slapi_acl_check_mods(Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char
 {
 #ifdef LDAP_SLAPI
        Operation *op;
-       int ret;
-       Modifications *ml;
-        Modifications *next;
+       int rc = LDAP_SUCCESS;
+       Modifications *ml, *mp;
 
        if ( slapi_pblock_get( pb, SLAPI_OPERATION, (void *)&op ) != 0 ) {
                return LDAP_PARAM_ERROR;
        }
 
-       ml = slapi_x_ldapmods2modifications( mods );
+       ml = slapi_int_ldapmods2modifications( mods );
        if ( ml == NULL ) {
                return LDAP_OTHER;
        }
 
-       ret = acl_check_modlist( op, e, ml );
+       for ( mp = ml; mp != NULL; mp = mp->sml_next ) {
+               rc = slap_bv2ad( &mp->sml_type, &mp->sml_desc, (const char **)errbuf );
+               if ( rc != LDAP_SUCCESS ) {
+                       break;
+               }
+       }
+
+       if ( rc == LDAP_SUCCESS ) {
+               rc = acl_check_modlist( op, e, ml ) ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS;
+       }
 
        /* Careful when freeing the modlist because it has pointers into the mods array. */
-       for ( ; ml != NULL; ml = next ) {
-               next = ml->sml_next;
+       for ( ; ml != NULL; ml = mp ) {
+               mp = ml->sml_next;
 
                /* just free the containing array */
                slapi_ch_free( (void **)&ml->sml_bvalues );
                slapi_ch_free( (void **)&ml );
        }
 
-       return ret ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS;
+       return rc;
 #else
        return LDAP_UNWILLING_TO_PERFORM;
 #endif
@@ -3163,7 +3347,7 @@ int slapi_acl_check_mods(Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char
  * 
  * This function must also be called before slap_mods_check().
  */
-LDAPMod **slapi_x_modifications2ldapmods(Modifications **pmodlist)
+LDAPMod **slapi_int_modifications2ldapmods(Modifications **pmodlist)
 {
 #ifdef LDAP_SLAPI
        Modifications *ml, *modlist;
@@ -3223,9 +3407,9 @@ LDAPMod **slapi_x_modifications2ldapmods(Modifications **pmodlist)
  * 
  * The returned Modification list contains pointers into the
  * LDAPMods array; the latter MUST be freed with
- * slapi_x_free_ldapmods() (see below).
+ * slapi_int_free_ldapmods() (see below).
  */
-Modifications *slapi_x_ldapmods2modifications (LDAPMod **mods)
+Modifications *slapi_int_ldapmods2modifications (LDAPMod **mods)
 {
 #ifdef LDAP_SLAPI
        Modifications *modlist = NULL, **modtail;
@@ -3255,7 +3439,7 @@ Modifications *slapi_x_ldapmods2modifications (LDAPMod **mods)
                }
 
                if ( i == 0 ) {
-                        mod->sml_bvalues = NULL;
+                       mod->sml_bvalues = NULL;
                } else {
                        mod->sml_bvalues = (BerVarray) ch_malloc( (i + 1) * sizeof(struct berval) );
 
@@ -3288,10 +3472,10 @@ Modifications *slapi_x_ldapmods2modifications (LDAPMod **mods)
 /*
  * This function only frees the parts of the mods array that
  * are not shared with the Modification list that was created
- * by slapi_x_ldapmods2modifications(). 
+ * by slapi_int_ldapmods2modifications(). 
  *
  */
-void slapi_x_free_ldapmods (LDAPMod **mods)
+void slapi_int_free_ldapmods (LDAPMod **mods)
 {
 #ifdef LDAP_SLAPI
        int i, j;
@@ -3331,7 +3515,7 @@ void slapi_x_free_ldapmods (LDAPMod **mods)
  * op->o_callback->sc_sendentry, if you wish to make computed
  * attributes available to it.
  */
-int slapi_x_compute_output_ber(computed_attr_context *c, Slapi_Attr *a, Slapi_Entry *e)
+int slapi_int_compute_output_ber(computed_attr_context *c, Slapi_Attr *a, Slapi_Entry *e)
 {
 #ifdef LDAP_SLAPI
        Operation *op = NULL;
@@ -3379,7 +3563,7 @@ int slapi_x_compute_output_ber(computed_attr_context *c, Slapi_Attr *a, Slapi_En
        }
 
        if ( !access_allowed( op, e, desc, NULL, ACL_READ, &c->cac_acl_state) ) {
-               slapi_log_error( SLAPI_LOG_ACL, "SLAPI_COMPUTE",
+               slapi_log_error( SLAPI_LOG_ACL, "slapi_int_compute_output_ber",
                        "acl: access to attribute %s not allowed\n",
                        desc->ad_cname.bv_val );
                return 0;
@@ -3387,7 +3571,7 @@ int slapi_x_compute_output_ber(computed_attr_context *c, Slapi_Attr *a, Slapi_En
 
        rc = ber_printf( ber, "{O[" /*]}*/ , &desc->ad_cname );
        if (rc == -1 ) {
-               slapi_log_error( SLAPI_LOG_BER, "SLAPI_COMPUTE",
+               slapi_log_error( SLAPI_LOG_BER, "slapi_int_compute_output_ber",
                        "ber_printf failed\n");
                return 1;
        }
@@ -3396,15 +3580,15 @@ int slapi_x_compute_output_ber(computed_attr_context *c, Slapi_Attr *a, Slapi_En
                for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
                        if ( !access_allowed( op, e,
                                desc, &a->a_vals[i], ACL_READ, &c->cac_acl_state)) {
-                               slapi_log_error( SLAPI_LOG_ACL, "SLAPI_COMPUTE",
-                                       "slapi_x_compute_output_ber: conn %lu "
+                               slapi_log_error( SLAPI_LOG_ACL, "slapi_int_compute_output_ber",
+                                       "conn %lu "
                                        "acl: access to %s, value %d not allowed\n",
                                        op->o_connid, desc->ad_cname.bv_val, i  );
                                continue;
                        }
        
                        if (( rc = ber_printf( ber, "O", &a->a_vals[i] )) == -1 ) {
-                               slapi_log_error( SLAPI_LOG_BER, "SLAPI_COMPUTE",
+                               slapi_log_error( SLAPI_LOG_BER, "slapi_int_compute_output_ber",
                                        "ber_printf failed\n");
                                return 1;
                        }
@@ -3412,7 +3596,7 @@ int slapi_x_compute_output_ber(computed_attr_context *c, Slapi_Attr *a, Slapi_En
        }
 
        if (( rc = ber_printf( ber, /*{[*/ "]N}" )) == -1 ) {
-               slapi_log_error( SLAPI_LOG_BER, "SLAPI_COMPUTE",
+               slapi_log_error( SLAPI_LOG_BER, "slapi_int_compute_output_ber",
                        "ber_printf failed\n" );
                return 1;
        }
@@ -3699,3 +3883,66 @@ int slapi_notify_condvar( Slapi_CondVar *cvar, int notify_all )
 #endif
 }
 
+int slapi_int_access_allowed( Operation *op,
+       Entry *entry,
+       AttributeDescription *desc,
+       struct berval *val,
+       slap_access_t access,
+       AccessControlState *state )
+{
+#ifdef LDAP_SLAPI
+       int rc, slap_access = 0;
+       slapi_acl_callback_t *pGetPlugin, *tmpPlugin;
+
+       if ( op->o_pb == NULL ) {
+               /* internal operation */
+               return 1;
+       }
+
+       switch ( access ) {
+       case ACL_WRITE:
+               slap_access |= SLAPI_ACL_ADD | SLAPI_ACL_DELETE | SLAPI_ACL_WRITE;
+               break;
+       case ACL_READ:
+               slap_access |= SLAPI_ACL_READ;
+               break;
+       case ACL_SEARCH:
+               slap_access |= SLAPI_ACL_SEARCH;
+               break;
+       case ACL_COMPARE:
+                slap_access = ACL_COMPARE;
+               break;
+       default:
+               break;
+        }
+
+       rc = getAllPluginFuncs( op->o_bd, SLAPI_PLUGIN_ACL_ALLOW_ACCESS, (SLAPI_FUNC **)&tmpPlugin );
+       if ( rc != LDAP_SUCCESS || tmpPlugin == NULL ) {
+               /* nothing to do; allowed access */
+               return 1;
+       }
+
+       slapi_int_pblock_set_operation( op->o_pb, op );
+
+       rc = 1; /* default allow policy */
+
+       for ( pGetPlugin = tmpPlugin; *pGetPlugin != NULL; pGetPlugin++ ) {
+               /*
+                * 0    access denied
+                * 1    access granted
+                */
+               rc = (*pGetPlugin)( op->o_pb, entry, desc->ad_cname.bv_val,
+                                       val, slap_access, (void *)state );
+               if ( rc == 0 ) {
+                       break;
+               }
+       }
+
+       slapi_ch_free( (void **)&tmpPlugin );
+
+       return rc;
+#else
+       return 1;
+#endif /* LDAP_SLAPI */
+}
+