]> git.sur5r.net Git - openldap/commitdiff
First pass at replacing proprietary OpenLDAP virtual attribute API
authorLuke Howard <lukeh@openldap.org>
Wed, 22 Jan 2003 13:06:46 +0000 (13:06 +0000)
committerLuke Howard <lukeh@openldap.org>
Wed, 22 Jan 2003 13:06:46 +0000 (13:06 +0000)
(which existed briefly for a day!) with Sun ONE DS 5.x computed
attribute API

servers/slapd/result.c
servers/slapd/slapi/plugin.c
servers/slapd/slapi/slapi.h
servers/slapd/slapi/slapi_pblock.c
servers/slapd/slapi/slapi_utils.c
servers/slapd/slapi/slapi_utils.h

index 272c28a713a579d8f7e58856ba8e7425b61ecfd9..bd38e61a8fa96ffe74990111610531a5dff24e63 100644 (file)
@@ -687,9 +687,9 @@ slap_send_search_entry(
        int             opattrs;
        AccessControlState acl_state = ACL_STATE_INIT;
 #ifdef LDAP_SLAPI
-       /* Support virtual attribute plugins. */
-       Slapi_PBlock *pb = op->o_pb;
-       Slapi_AttrSet *vattrs = NULL;
+       /* Support for computed attribute plugins */
+       computed_attr_context    ctx;
+       AttributeName   *anp;
 #endif
 
        AttributeDescription *ad_entry = slap_schema.si_ad_entry;
@@ -1148,149 +1148,39 @@ slap_send_search_entry(
                }
        }
 
-#if defined( LDAP_SLAPI )
-       /* Add virtual attributes */
-       vattrs = slapi_x_attrset_new();
-       slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_ENTRY, (void *)e );
-       slapi_pblock_set( pb, SLAPI_PLUGIN_OPATTR_COALESCE_DATA, (void *)vattrs );
-       rc = doPluginFNs( be, SLAPI_PLUGIN_OPATTR_COALESCE_FN, pb );
-       if ( rc == 0 ) {
-               /*
-                * Re-fetch this to be safe; plugin could have freed and
-                * changed it, although it shouldn't.
-                */
-               rc = slapi_pblock_get( pb, SLAPI_PLUGIN_OPATTR_COALESCE_DATA, (void **)&vattrs );
-               if ( rc != 0 ) {
-                       /* Something bad happened. */
-                       vattrs = NULL;
-               }
-       }
-
-       /* Now, send the virtual attributes. */
-       if ( vattrs != NULL ) {
-               for (a = *vattrs, j = 0; a != NULL; a = a->a_next, j++ ) {
-                       AttributeDescription *desc = a->a_desc;
-       
-                       if ( attrs == NULL ) {
-                               /* all attrs request, skip operational attributes */
-                               if( is_at_operational( desc->ad_type ) ) {
-                                       continue;
-                               }
-       
-                       } else {
-                               /* specific attrs requested */
-                               if( is_at_operational( desc->ad_type ) ) {
-                                       if( !opattrs && !ad_inlist( desc, attrs ) ) {
-                                               continue;
-                                       }
-                               } else {
-                                       if (!userattrs && !ad_inlist( desc, attrs ) )
-                                       {
-                                               continue;
-                                       }
-                               }
-                       }
-       
-                       if ( ! access_allowed( be, conn, op, e, desc, NULL,
-                               ACL_READ, &acl_state ) )
-                       {
-#ifdef NEW_LOGGING
-                               LDAP_LOG( ACL, INFO, 
-                                       "send_search_entry: conn %lu "
-                                       "access to attribute %s not allowed\n",
-                                       op->o_connid, desc->ad_cname.bv_val, 0 );
-#else
-                               Debug( LDAP_DEBUG_ACL, "acl: access to attribute %s "
-                                               "not allowed\n",
-                                               desc->ad_cname.bv_val, 0, 0 );
-#endif
-       
-                               continue;
-                       }
-       
-                       rc = ber_printf( ber, "{O[" /*]}*/ , &desc->ad_cname );
-                       if ( rc == -1 ) {
-#ifdef NEW_LOGGING
-                               LDAP_LOG( OPERATION, ERR, 
-                                       "send_search_entry: conn %lu  "
-                                       "ber_printf failed\n", op->o_connid, 0, 0 );
-#else
-                               Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
-#endif
-       
-                               ber_free_buf( ber );
-                               send_ldap_result( conn, op, LDAP_OTHER,
-                                   NULL, "encoding description error", NULL, NULL );
-       
-                               attrs_free( aa );
-                               goto error_return;
-                       }
-       
-                       if ( ! attrsonly ) {
-                               for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
-                                       if ( ! access_allowed( be, conn, op, e,
-                                               desc, &a->a_vals[i], ACL_READ, &acl_state ) )
-                                       {
-#ifdef NEW_LOGGING
-                                               LDAP_LOG( ACL, INFO, 
-                                                       "send_search_entry: conn %lu "
-                                                       "access to %s, value %d not allowed\n",
-                                                       op->o_connid, desc->ad_cname.bv_val, i );
-#else
-                                               Debug( LDAP_DEBUG_ACL,
-                                                       "acl: access to attribute %s, "
-                                                       "value %d not allowed\n",
-                                                       desc->ad_cname.bv_val, i, 0 );
-#endif
-       
-                                               continue;
-                                       }
-       
-                                       if ( op->vrFilter && e_flags[j][i] == 0 ){
-                                               continue;
-                                       }
-       
-                                       if (( rc = ber_printf( ber, "O", &a->a_vals[i] )) == -1 ) {
-#ifdef NEW_LOGGING
-                                               LDAP_LOG( OPERATION, ERR, 
-                                                       "send_search_entry: conn %lu  ber_printf failed\n", 
-                                                       op->o_connid, 0, 0 );
-#else
-                                               Debug( LDAP_DEBUG_ANY,
-                                                   "ber_printf failed\n", 0, 0, 0 );
-#endif
-       
-                                               ber_free_buf( ber );
-                                               send_ldap_result( conn, op, LDAP_OTHER,
-                                                       NULL, "encoding values error", 
-                                                       NULL, NULL );
-
-                                               attrs_free( aa );
-                                               goto error_return;
-                                       }
-                               }
-                       }
-
-                       if (( rc = ber_printf( ber, /*{[*/ "]N}" )) == -1 ) {
-#ifdef NEW_LOGGING
-                               LDAP_LOG( OPERATION, ERR, 
-                                       "send_search_entry: conn %lu  ber_printf failed\n",
-                                       op->o_connid, 0, 0 );
-#else
-                               Debug( LDAP_DEBUG_ANY, "ber_printf failed\n", 0, 0, 0 );
-#endif
-
-                               ber_free_buf( ber );
-                               send_ldap_result( conn, op, LDAP_OTHER,
-                                   NULL, "encode end error", NULL, NULL );
+#ifdef LDAP_SLAPI
+       /* Support Sun ONE DS 5.x computed attributes */
 
-                               attrs_free( aa );
-                               goto error_return;
+       /*
+        * First, setup the computed attribute context that is
+        * passed to all plugins.
+        */
+       ctx.cac_pb = op->o_pb;
+       ctx.cac_attrs = attrs;
+       ctx.cac_attrsonly = attrsonly;
+       ctx.cac_userattrs = userattrs;
+       ctx.cac_opattrs = opattrs;
+       ctx.cac_acl_state = acl_state;
+       ctx.cac_private = (void *)ber;
+
+       /*
+        * For each client requested attribute, call the plugins.
+        */
+       if ( attrs != NULL ) {
+               for ( anp = attrs; anp->an_name.bv_val != NULL; anp++ ) {
+                       rc = compute_evaluator( &ctx, anp->an_name.bv_val, e, slapi_x_compute_output_ber );
+                       if ( rc == 1 ) {
+                               break;
                        }
                }
-               slapi_x_attrset_free( &vattrs );
-               slapi_pblock_set( pb, SLAPI_SEARCH_RESULT_ENTRY, NULL );
-               slapi_pblock_set( pb, SLAPI_PLUGIN_OPATTR_COALESCE_DATA, NULL );
+       } else {
+               rc = compute_evaluator( &ctx, "*", e, slapi_x_compute_output_ber );
+       }
+       if ( rc == 1 ) {
+               ber_free_buf( ber );
+               send_ldap_result( conn, op, LDAP_OTHER,
+                       NULL, "computed attribute error", NULL, NULL );
+               goto error_return;
        }
 #endif /* LDAP_SLAPI */
 
index fd603bb821d4109d36787befc7760d739077ef22..5acd5261eb2c00e09680f5d91cd1a6a0249fece6 100644 (file)
@@ -86,6 +86,10 @@ newPlugin(
        }
 
        rc = loadPlugin( pPlugin, path, initfunc, TRUE, NULL, &hdLoadHandle );
+       if ( rc != 0 ) {
+               rc = LDAP_OTHER;
+               goto done;
+       }
 
 done:
        if ( rc != LDAP_SUCCESS && pPlugin != NULL ) {
@@ -557,7 +561,9 @@ loadPlugin(
        return rc;
 }
 
-
+/*
+ * Special support for computed attribute plugins
+ */
 int 
 doPluginFNs(
        Backend         *be,    
@@ -607,7 +613,7 @@ doPluginFNs(
         * backend); same logic as above.
         */
        if ( be != NULL ) {
-               rc = getAllPluginFuncs( be, funcType, &tmpPlugin );
+               rc = getAllPluginFuncs( NULL, funcType, &tmpPlugin );
                if ( rc != LDAP_SUCCESS || tmpPlugin == NULL )
                        return 0;
                for ( pGetPlugin = tmpPlugin; *pGetPlugin != NULL; pGetPlugin++ ) {
@@ -650,8 +656,8 @@ netscape_plugin(
                iType = SLAPI_PLUGIN_POSTOPERATION;
        } else if ( strcasecmp( argv[1], "extendedop" ) == 0 ) {
                iType = SLAPI_PLUGIN_EXTENDEDOP;
-       } else if ( strcasecmp( argv[1], "opattrsp" ) == 0 ) {
-               iType = SLAPI_PLUGIN_OPATTR_SP;
+       } else if ( strcasecmp( argv[1], "object" ) == 0 ) {
+               iType = SLAPI_PLUGIN_OBJECT;
        } else {
                fprintf( stderr, "%s: line %d: invalid plugin type \"%s\".\n",
                                fname, lineno, argv[1] );
@@ -667,8 +673,7 @@ netscape_plugin(
 
        if ( iType == SLAPI_PLUGIN_PREOPERATION ||
                        iType == SLAPI_PLUGIN_EXTENDEDOP ||
-                       iType == SLAPI_PLUGIN_POSTOPERATION ||
-                       iType == SLAPI_PLUGIN_OPATTR_SP ) {
+                       iType == SLAPI_PLUGIN_POSTOPERATION ) {
                int rc;
                Slapi_PBlock *pPlugin;
 
index d8c9e938b46d8590177dc5d920ba9494df1d1211..e0c36c1eb48224648f34a5eeae87cddee2d8a67e 100644 (file)
@@ -20,7 +20,6 @@ LDAP_BEGIN_DECL
 typedef struct slapi_pblock    Slapi_PBlock;
 typedef struct slap_entry      Slapi_Entry;
 typedef struct slap_attr       Slapi_Attr;
-typedef struct slap_attr *     Slapi_AttrSet;
 typedef struct berval          Slapi_Value;
 typedef BerVarray              Slapi_ValueSet;
 typedef Filter                 Slapi_Filter;
@@ -88,15 +87,6 @@ LDAP_BEGIN_DECL
 #define SLAPI_PLUGIN_PWD_STORAGE_SCHEME         14
 #define SLAPI_PLUGIN_VATTR_SP                   15
 #define SLAPI_PLUGIN_REVER_PWD_STORAGE_SCHEME   16
-/*
- * Because the Sun ONE DS virtual attribute service
- * is quite complicated, we've added a "lightweight"
- * virtual attribute service. Virtual attribute
- * plugins are called for each search result; 
- * they should examine the list of attributes
- * requested to minimise the performance impact.
- */
-#define SLAPI_PLUGIN_OPATTR_SP                 17
 
 #define SLAPI_PLUGIN_EXTENDED_SENT_RESULT       -1
 #define SLAPI_PLUGIN_EXTENDED_NOT_HANDLED       -2
@@ -250,17 +240,16 @@ LDAP_BEGIN_DECL
 #define SLAPI_RESULT_TEXT                      882
 #define SLAPI_RESULT_MATCHED                   883
 
-/* Virtual attribute service provider */
-#define SLAPI_PLUGIN_OPATTR_COALESCE_DATA      900
-/* Pointer to a Slapi_AttrSet */
-#define SLAPI_PLUGIN_OPATTR_COALESCE_FN                901
-
 #define SLAPI_PLUGIN_SYNTAX_FLAG_ORKEYS                        1
 #define SLAPI_PLUGIN_SYNTAX_FLAG_ORDERING              2
 
 #define SLAPI_PLUGIN_AUDIT_DATA                 1100
 #define SLAPI_PLUGIN_AUDIT_FN                   1101
 
+/* DS 5.x Computed Attribute Callbacks (not exposed) */
+#define SLAPI_PLUGIN_COMPUTE_EVALUATOR_FN      1200
+#define SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN        1201
+
 #define SLAPI_MANAGEDSAIT                      1000
 
 #define SLAPI_CONFIG_FILENAME                  40
index 786f9cc9eadb0b62099c9682784fe7bac53b33cc..71822447d3b9829d88dbc9a6d57b83dd5e2587e9 100644 (file)
@@ -196,8 +196,8 @@ isOkNetscapeParam( int param )
        case SLAPI_RESULT_CODE:
        case SLAPI_RESULT_TEXT:
        case SLAPI_RESULT_MATCHED:
-       case SLAPI_PLUGIN_OPATTR_COALESCE_FN:
-       case SLAPI_PLUGIN_OPATTR_COALESCE_DATA:
+       case SLAPI_PLUGIN_COMPUTE_EVALUATOR_FN:
+       case SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN:
                return LDAP_SUCCESS;
        default:
                return INVALID_PARAM;
index 5acfdbcb62eb1fac7f55b3cf270b6659e32e2ed1..235577223d55341bb1de0c899698f3eb3142a754 100644 (file)
@@ -2438,209 +2438,6 @@ int slapi_acl_check_mods(Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char
 #endif
 }
 
-/*
- * Attribute sets are an OpenLDAP extension for the 
- * virtual operational attribute coalescing plugin  
- *
- * Subject to going away very soon; do not use
- */
-Slapi_AttrSet *slapi_x_attrset_new( void )
-{
-#ifdef LDAP_SLAPI
-       Slapi_AttrSet *a;
-
-       /*
-        * Like a Slapi_ValueSet, a Slapi_AttrSet is a container
-        * for objects: we need this because it may be initially
-        * empty.
-        */
-       a = (Slapi_AttrSet *)slapi_ch_malloc( sizeof( *a ) );
-       *a = NULL;
-
-       return a;
-#else
-       return NULL;
-#endif
-}
-
-Slapi_AttrSet *slapi_x_attrset_init( Slapi_AttrSet *as, Slapi_Attr *a )
-{
-#ifdef LDAP_SLAPI
-       *as = a;
-       a->a_next = NULL;
-
-       return as;
-#else
-       return NULL;
-#endif
-}
-
-void slapi_x_attrset_free( Slapi_AttrSet **pAs )
-{
-#ifdef LDAP_SLAPI
-       Slapi_AttrSet *as = *pAs;
-
-       if ( as != NULL ) {
-               attrs_free( *as );
-               slapi_ch_free( (void **)pAs );
-       }
-#endif
-}
-
-Slapi_AttrSet *slapi_x_attrset_dup( Slapi_AttrSet *as )
-{
-#ifdef LDAP_SLAPI
-       Slapi_AttrSet *newAs = slapi_x_attrset_new();
-       
-       if ( *as != NULL )
-               *newAs = attrs_dup( *as );
-
-       return newAs;
-#else
-       return NULL;
-#endif
-}
-
-int slapi_x_attrset_add_attr( Slapi_AttrSet *as, Slapi_Attr *a )
-{
-#ifdef LDAP_SLAPI
-       Slapi_Attr *nextAttr;
-
-       if ( as == NULL || a == NULL )
-               return -1;
-
-       if ( *as == NULL ) {
-               /* First attribute */
-               nextAttr = NULL;
-               (*as) = a;
-       } else {
-               /* Non-first attribute */
-               nextAttr = (*as)->a_next;
-               (*as)->a_next = a;
-       }
-
-       a->a_next = nextAttr;
-
-       return 0;
-#else
-       return -1;
-#endif
-}
-
-int slapi_x_attrset_add_attr_copy( Slapi_AttrSet *as, Slapi_Attr *a )
-{
-#ifdef LDAP_SLAPI
-       Slapi_Attr *adup;
-
-       adup = slapi_attr_dup( a );
-       return slapi_x_attrset_add_attr( as, adup );
-#else
-       return -1;
-#endif
-}
-
-int slapi_x_attrset_find( Slapi_AttrSet *as, const char *type, Slapi_Attr **attr )
-{
-#ifdef LDAP_SLAPI
-       AttributeDescription *ad = NULL;
-       const char *text;
-
-       if ( as == NULL || *as == NULL ) {
-               return -1;
-       }
-
-       if ( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
-               return -1;
-       }
-       *attr = attrs_find( *as, ad );
-       return ( *attr == NULL ) ? -1 : 0;
-#else
-       return -1;
-#endif
-}
-
-int slapi_x_attrset_merge( Slapi_AttrSet *as, const char *type, Slapi_ValueSet *vals )
-{
-#ifdef LDAP_SLAPI
-       AttributeDescription *ad = NULL;
-       Slapi_AttrSet *a;
-       const char *text;
-
-       if ( vals == NULL || *vals == NULL ) {
-               /* Must have something to add. */
-               return -1;
-       }
-
-       if ( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
-               return -1;
-       }
-
-       for ( a = as; *a != NULL; a = &(*a)->a_next ) {
-               if ( ad_cmp( (*a)->a_desc, ad ) == 0 ) {
-                       break;
-               }
-       }
-
-       if ( *a == NULL ) {
-               *a = (Slapi_Attr *) slapi_ch_malloc( sizeof(Attribute) );
-               (*a)->a_desc = ad;
-               (*a)->a_vals = NULL;
-               (*a)->a_next = NULL;
-               (*a)->a_flags = 0;
-       }
-
-       return value_add ( &(*a)->a_vals, *vals );
-#else
-       return -1;
-#endif
-}
-
-int slapi_x_attrset_merge_bervals( Slapi_AttrSet *as, const char *type, struct berval **vals )
-{
-#ifdef LDAP_SLAPI
-       BerVarray vp;
-       int rc;
-
-       if ( bvptr2obj( vals, &vp ) != LDAP_SUCCESS ) {
-               return -1;
-       }
-       rc = slapi_x_attrset_merge( as, type, &vp );
-       slapi_ch_free( (void **)&vp );
-
-       return rc;
-#else
-       return -1;
-#endif
-}
-
-int slapi_x_attrset_delete( Slapi_AttrSet *as, const char *type )
-{
-#ifdef LDAP_SLAPI
-       AttributeDescription *ad = NULL;
-       const char *text;
-
-       if ( as == NULL ) {
-               return -1;
-       }
-
-       if ( *as == NULL ) {
-               return -1;
-       }
-
-       if ( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
-               return -1;
-       }
-
-       if ( attr_delete( as, ad ) != LDAP_SUCCESS ) {
-               return -1;
-       }
-
-       return 0;
-#else
-       return -1;
-#endif
-}
-
 /*
  * Synthesise an LDAPMod array from a Modifications list to pass
  * to SLAPI. This synthesis is destructive and as such the 
@@ -2799,3 +2596,238 @@ void slapi_x_free_ldapmods (LDAPMod **mods)
 #endif /* LDAP_SLAPI */
 }
 
+/*
+ * Sun ONE DS 5.x computed attribute support
+ */
+
+/*
+ * Write the computed attribute to a BerElement.
+ */
+int slapi_x_compute_output_ber(computed_attr_context *c, Slapi_Attr *a, Slapi_Entry *e)
+{
+#ifdef LDAP_SLAPI
+       Backend *be = NULL;
+       Connection *conn = NULL;
+       Operation *op = NULL;
+       BerElement *ber;
+       AttributeDescription *desc;
+       int rc;
+       int i;
+
+       if ( c == NULL ) {
+               return 1;
+       }
+
+       if ( a == NULL ) {
+               return 1;
+       }
+
+       if ( e == NULL ) {
+               return 1;
+       }
+
+       rc = slapi_pblock_get( c->cac_pb, SLAPI_BACKEND, (void *)&be );
+       if ( rc != 0 ) {
+               be = NULL; /* no backend for root DSE */
+       }
+
+       rc = slapi_pblock_get( c->cac_pb, SLAPI_CONNECTION, (void *)&conn );
+       if ( rc != 0 || conn == NULL ) {
+               return rc;
+       }
+
+       rc = slapi_pblock_get( c->cac_pb, SLAPI_OPERATION, (void *)&op );
+       if ( rc != 0 || op == NULL ) {
+               return rc;
+       }
+
+       ber = (BerElement *)c->cac_private;
+       desc = a->a_desc;
+
+       if ( c->cac_attrs == NULL ) {
+               /* All attrs request, skip operational attributes */
+               if ( is_at_operational( desc->ad_type ) ) {
+                       return 0;
+               }
+       } else {
+               /* Specific attrs requested */
+               if ( is_at_operational( desc->ad_type ) ) {
+                       if ( !c->cac_opattrs && !ad_inlist( desc, c->cac_attrs ) ) {
+                               return 0;
+                       }
+               } else {
+                       if ( !c->cac_userattrs && !ad_inlist( desc, c->cac_attrs ) ) {
+                               return 0;
+                       }
+               }
+       }
+
+       if ( !access_allowed( be, conn, op, e, desc, NULL, ACL_READ, &c->cac_acl_state) ) {
+               slapi_log_error( SLAPI_LOG_ACL, "SLAPI_COMPUTE",
+                       "acl: access to attribute %s not allowed\n",
+                       desc->ad_cname.bv_val );
+               return 0;
+       }
+
+       rc = ber_printf( ber, "{O[" /*]}*/ , &desc->ad_cname );
+       if (rc == -1 ) {
+               slapi_log_error( SLAPI_LOG_BER, "SLAPI_COMPUTE",
+                       "ber_printf failed\n");
+               return 1;
+       }
+
+       if ( !c->cac_attrsonly ) {
+               for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
+                       if ( !access_allowed( be, conn, 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 "
+                                       "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",
+                                       "ber_printf failed\n");
+                               return 1;
+                       }
+               }
+       }
+
+       if (( rc = ber_printf( ber, /*{[*/ "]N}" )) == -1 ) {
+               slapi_log_error( SLAPI_LOG_BER, "SLAPI_COMPUTE",
+                       "ber_printf failed\n" );
+               return 1;
+       }
+
+       return 0;
+#else
+       return 1;
+#endif
+}
+
+int slapi_compute_add_evaluator(slapi_compute_callback_t function)
+{
+#ifdef LDAP_SLAPI
+       Slapi_PBlock *pPlugin = NULL;
+       int rc;
+
+       pPlugin = slapi_pblock_new();
+       if ( pPlugin == NULL ) {
+               rc = LDAP_NO_MEMORY;
+               goto done;
+       }
+
+       rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)SLAPI_PLUGIN_OBJECT );
+       if ( rc != LDAP_SUCCESS ) {
+               goto done;
+       }
+
+       rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_COMPUTE_EVALUATOR_FN, (void *)function );
+       if ( rc != LDAP_SUCCESS ) {
+               goto done;
+       }
+
+       rc = insertPlugin( NULL, pPlugin );
+       if ( rc != 0 ) {
+               rc = LDAP_OTHER;
+               goto done;
+       }
+
+done:
+       if ( rc != LDAP_SUCCESS ) {
+               if ( pPlugin != NULL ) {
+                       slapi_pblock_destroy( pPlugin );
+               }
+               return -1;
+       }
+
+       return 0;
+#else
+       return -1;
+#endif /* LDAP_SLAPI */
+}
+
+int slapi_compute_add_search_rewriter(slapi_search_rewrite_callback_t function)
+{
+#ifdef LDAP_SLAPI
+       return -1;
+#else
+       return -1;
+#endif
+}
+
+/*
+ * Call compute evaluators
+ */
+int compute_evaluator(computed_attr_context *c, char *type, Slapi_Entry *e, slapi_compute_output_t outputfn)
+{
+#ifdef LDAP_SLAPI
+       int rc = 0;
+       slapi_compute_callback_t *pGetPlugin, *tmpPlugin;
+
+       rc = getAllPluginFuncs( NULL, SLAPI_PLUGIN_COMPUTE_EVALUATOR_FN, (SLAPI_FUNC **)&tmpPlugin );
+       if ( rc != LDAP_SUCCESS || tmpPlugin == NULL ) {
+               /* Nothing to do; front-end should ignore. */
+               return 0;
+       }
+
+       for ( pGetPlugin = tmpPlugin; *pGetPlugin != NULL; pGetPlugin++ ) {
+               /*
+                * -1: no attribute matched requested type
+                *  0: one attribute matched
+                * >0: error happened
+                */
+               rc = (*pGetPlugin)( c, type, e, outputfn );
+               if ( rc > 0 ) {
+                       break;
+               }
+       }
+
+       slapi_ch_free( (void **)&tmpPlugin );
+
+       return rc;
+#else
+       return 1;
+#endif /* LDAP_SLAPI */
+}
+
+int compute_rewrite_search_filter(Slapi_PBlock *pb)
+{
+#ifdef LDAP_SLAPI
+       Backend *be;
+       int rc;
+
+       rc = slapi_pblock_get( pb, SLAPI_BACKEND, (void *)&be );
+       if ( rc != 0 ) {
+               return rc;
+       }
+
+       return doPluginFNs( be, SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN, pb );
+#else
+       return -1;
+#endif /* LDAP_SLAPI */
+}
+
+/*
+ * New API to provide the plugin with access to the search
+ * pblock. Have informed Sun DS team.
+ */
+int slapi_x_compute_get_pblock(computed_attr_context *c, Slapi_PBlock **pb)
+{
+#ifdef LDAP_SLAPI
+       if ( c == NULL )
+               return -1;
+
+       if ( c->cac_pb == NULL )
+               return -1;
+
+       *pb = c->cac_pb;
+
+       return 0;
+#else
+       return -1;
+#endif /* LDAP_SLAPI */
+}
+
index 05f111b0890bce39207ab81bab5e1382d3ca7c84..fe667e29a5428b6c48244eb64aa7e332a205bfac 100644 (file)
@@ -63,18 +63,6 @@ Slapi_Entry *slapi_entry_alloc();
 void slapi_entry_free( Slapi_Entry *e );
 int slapi_attr_get_values( Slapi_Attr *attr, struct berval ***vals );
 
-/* OpenLDAP AttrSet extensions for virtual attribute service */
-Slapi_AttrSet *slapi_x_attrset_new( void );
-Slapi_AttrSet *slapi_x_attrset_init( Slapi_AttrSet *as, Slapi_Attr *a );
-void slapi_x_attrset_free( Slapi_AttrSet **as );
-Slapi_AttrSet *slapi_x_attrset_dup( Slapi_AttrSet *as );
-int slapi_x_attrset_add_attr( Slapi_AttrSet *as, Slapi_Attr *a );
-int slapi_x_attrset_add_attr_copy( Slapi_AttrSet *as, Slapi_Attr *a );
-int slapi_x_attrset_find( Slapi_AttrSet *as, const char *type, Slapi_Attr **attr );
-int slapi_x_attrset_merge( Slapi_AttrSet *as, const char *type, Slapi_ValueSet *vals );
-int slapi_x_attrset_merge_bervals( Slapi_AttrSet *as, const char *type, struct berval **vals );
-int slapi_x_attrset_delete( Slapi_AttrSet *as, const char *type );
-
 /* DS 5.x SLAPI */
 int slapi_access_allowed( Slapi_PBlock *pb, Slapi_Entry *e, char *attr, struct berval *val, int access );
 int slapi_acl_check_mods( Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char **errbuf );
@@ -204,6 +192,30 @@ LDAPMod **slapi_x_modifications2ldapmods(Modifications **);
 Modifications *slapi_x_ldapmods2modifications(LDAPMod **);
 void slapi_x_free_ldapmods(LDAPMod **);
 
+/* Computed attribute support */
+struct _computed_attr_context {
+       /* slap_send_search_entry() argblock */
+       Slapi_PBlock    *cac_pb;
+       AttributeName   *cac_attrs;
+       int             cac_attrsonly : 1;
+       int             cac_userattrs : 1;
+       int             cac_opattrs : 1;
+       AccessControlState      cac_acl_state;
+       /* private data */
+       void *cac_private;
+};
+typedef struct _computed_attr_context computed_attr_context;
+typedef int (*slapi_compute_output_t)(computed_attr_context *c, Slapi_Attr *a, Slapi_Entry *e);
+typedef int (*slapi_compute_callback_t)(computed_attr_context *c, char *type,
+       Slapi_Entry *e, slapi_compute_output_t outputfn);
+typedef int (*slapi_search_rewrite_callback_t)(Slapi_PBlock *pb);
+int slapi_compute_add_evaluator(slapi_compute_callback_t function);
+int slapi_compute_add_search_rewriter(slapi_search_rewrite_callback_t function);
+int compute_rewrite_search_filter(Slapi_PBlock *pb);
+int compute_evaluator(computed_attr_context *c, char *type, Slapi_Entry *e, slapi_compute_output_t outputfn);
+int slapi_x_compute_output_ber(computed_attr_context *c, Slapi_Attr *a, Slapi_Entry *e);
+int slapi_x_compute_get_pblock(computed_attr_context *c, Slapi_PBlock **pb);
+
 extern ldap_pvt_thread_mutex_t slapi_hn_mutex;
 extern ldap_pvt_thread_mutex_t slapi_time_mutex;
 extern ldap_pvt_thread_mutex_t slapi_printmessage_mutex;