Description of problem: I'm writing a ns/slapi directory plugin and am seeing some strange behaviour. The plugin registers a function that is run when the server is passing entries back to the client (i.e. registered as SLAPI_PLUGIN_PRE_ENTRY_FN in the plugin init script). The plugin is fairly simple (can supply if needed), currently, it simply adds a list of telephone numbers (held in a special attribute called qmulInternalTelephoneNumber) to the standard telephoneNumber attribute. The attributes are retrieved and set from the entry with the slapi api (slapi_attr_first_value/slapi_entry_add_value). But it seems that the modified entry is cached somewhere and is used in place of the original in subsequent searches. Version-Release number of selected component (if applicable): 1.0.4 How reproducible: Always. Steps to Reproduce: 1. Load plugin. 2. Restart slapd 3. Run 2 identical searches. Actual results: The first search fails to return an entry that has added the list of qmulinternalTelephoneNumbers to telephoneNumber. This code currently (its in development) looks like this (just a 2 dumb loops): /* get the search entry */ if (slapi_pblock_get(pb, SLAPI_SEARCH_RESULT_ENTRY, &e)!=0) { LOG("[%i] failed to get original_results\n",conn_id); goto end; } /* get the internal number if there is one if there isnt one then we have nothing to do. */ if (slapi_entry_attr_find(e,"qmulInternalTelephoneNumber",&ai)) { DEBUG("[%i] no qmulInternalTelephoneNumber - skipping to end\n",conn_id); goto end; } /* get the external number if there is one - dont care if it is there or not. */ slapi_entry_attr_find(e,"telephoneNumber",&ae); /* loop over the external number to see if we already have the internal numbers listed */ { Slapi_Value *ve=NULL; Slapi_Value *vi=NULL; char *se; char *si; int he,hi; for (hi=slapi_attr_first_value(ai,&vi); hi!=-1; hi=slapi_attr_next_value(ai,hi,&vi)) { si=(char*)slapi_value_get_string(vi); int notgotit=1; for (he=slapi_attr_first_value(ae,&ve); he!=-1; he=slapi_attr_next_value(ae,he,&ve )) { se=(char*)slapi_value_get_string(ve); DEBUG("[%i]cmp si=%s se=%s\n",conn_id,si,se); if(!strcmp(si,se)){ notgotit=0; DEBUG("[%i] found.\n",conn_id); } } if(notgotit){ LOG("[%i] adding int tel: %s\n",conn_id,si); slapi_entry_add_value(e,"telephoneNumber",slapi_value_dup(vi)); } } return (LDAP_SUCCESS) But the first search fails to return the combined list: The bash-3.1$ ldapsearch -h xxx.qmul.ac.uk -x -s sub -b"o=queen mary and westfield college,c=gb" -LLL "(mail=xxxx.uk)" dn: cn=M D T Evans, ou=Information Services, o=Queen Mary and Westfield Colleg e, c=GB <snip> telephoneNumber: +44 20 7822 XXXX telephoneNumber: +44 20 7822 YYYY qmulInternalTelephoneNumber: 13 XXXX qmulInternalTelephoneNumber: 13 YYYY But the error log suggests that the code is working: [16/Jan/2007:13:15:05 +0000] dirfilter (debug) - [2] processing results of search under: o=queen mary and westfield college,c=gb [16/Jan/2007:13:15:05 +0000] dirfilter (debug) - [2]cmp si=13 3739 se=+44 20 7822 3739 [16/Jan/2007:13:15:05 +0000] dirfilter (debug) - [2]cmp si=13 3739 se=+44 20 7822 5555 [16/Jan/2007:13:15:05 +0000] dirfilter - [2] adding int tel: 13 3739 [16/Jan/2007:13:15:05 +0000] dirfilter (debug) - [2]cmp si=13 5555 se=+44 20 7822 3739 [16/Jan/2007:13:15:05 +0000] dirfilter (debug) - [2]cmp si=13 5555 se=+44 20 7822 5555 [16/Jan/2007:13:15:05 +0000] dirfilter (debug) - [2]cmp si=13 5555 se=13 3739 [16/Jan/2007:13:15:05 +0000] dirfilter - [2] adding int tel: 13 5555 [16/Jan/2007:13:15:05 +0000] dirfilter (debug) - [2] finish A subsequent search gives the combined list of telephone attributes, but the log suggests that the values are already in the entry recovered with SLAPI_SEARCH_RESULT_ENTRY. i.e. ==> /opt/fedora-ds/slapd-mdte3/logs/errors <== [16/Jan/2007:13:15:16 +0000] dirfilter (debug) - [3] processing results of search under: o=queen mary and westfield college,c=gb [16/Jan/2007:13:15:16 +0000] dirfilter (debug) - [3]cmp si=13 3739 se=+44 20 7822 3739 [16/Jan/2007:13:15:16 +0000] dirfilter (debug) - [3]cmp si=13 3739 se=+44 20 7822 5555 [16/Jan/2007:13:15:16 +0000] dirfilter (debug) - [3]cmp si=13 3739 se=13 3739 [16/Jan/2007:13:15:16 +0000] dirfilter (debug) - [3] found. [16/Jan/2007:13:15:16 +0000] dirfilter (debug) - [3]cmp si=13 3739 se=13 5555 [16/Jan/2007:13:15:16 +0000] dirfilter (debug) - [3]cmp si=13 5555 se=+44 20 7822 3739 [16/Jan/2007:13:15:16 +0000] dirfilter (debug) - [3]cmp si=13 5555 se=+44 20 7822 5555 [16/Jan/2007:13:15:16 +0000] dirfilter (debug) - [3]cmp si=13 5555 se=13 3739 [16/Jan/2007:13:15:16 +0000] dirfilter (debug) - [3]cmp si=13 5555 se=13 5555 [16/Jan/2007:13:15:16 +0000] dirfilter (debug) - [3] found. [16/Jan/2007:13:15:16 +0000] dirfilter (debug) - [3] finish Expected results: I'd expect entries recovered by the parameter block call to SLAPI_SEARCH_RESULT_ENTRY to be the same and not to include the combined attribute list. Additional info: My suspicion is that the plugin function I have called is using a modified cached value of the entry.
Yes, that's what's happening. When you modify the SLAPI_SEARCH_RESULT_ENTRY, you are modifying the entry directly inside the entry cache. The entry provided by SLAPI_SEARCH_RESULT_ENTRY in a SLAPI_PLUGIN_PRE_ENTRY_FN should be considered read only - there is no way to modify the entry to be returned. At the point in the code where SLAPI_PLUGIN_PRE_ENTRY_FN is called (flush_ber() - result.c:1488) the BER has already been formed. I'm not sure what the purpose of the SLAPI_PLUGIN_PRE_ENTRY_FN is except possibly to allow you to look at the entry to be returned or possibly abort the return, but not to modify it. If you want to change the results as they are returned to the client, you should probably look at the virtual attribute interface. I _think_ this will allow you to add "virtual" values to telephoneNumber.
OK. Fair enough. I've had a look at the vattr interface and it seems that I can do everything that I want to with that. Thanks for the tip.