| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927 |
- /** BEGIN COPYRIGHT BLOCK
- * This Program is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License as published by the Free Software
- * Foundation; version 2 of the License.
- *
- * This Program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
- * Place, Suite 330, Boston, MA 02111-1307 USA.
- *
- * In addition, as a special exception, Red Hat, Inc. gives You the additional
- * right to link the code of this Program with code not covered under the GNU
- * General Public License ("Non-GPL Code") and to distribute linked combinations
- * including the two, subject to the limitations in this paragraph. Non-GPL Code
- * permitted under this exception must only link to the code of this Program
- * through those well defined interfaces identified in the file named EXCEPTION
- * found in the source code files (the "Approved Interfaces"). The files of
- * Non-GPL Code may instantiate templates or use macros or inline functions from
- * the Approved Interfaces without causing the resulting work to be covered by
- * the GNU General Public License. Only Red Hat, Inc. may make changes or
- * additions to the list of Approved Interfaces. You must obey the GNU General
- * Public License in all respects for all of the Program code and other code used
- * in conjunction with the Program except the Non-GPL Code covered by this
- * exception. If you modify this file, you may extend this exception to your
- * version of the file, but you are not obligated to do so. If you do not wish to
- * provide this exception without modification, you must delete this exception
- * statement from your version and license this file solely under the GPL without
- * exception.
- *
- *
- * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
- * Copyright (C) 2005 Red Hat, Inc.
- * All rights reserved.
- * END COPYRIGHT BLOCK **/
- #ifdef HAVE_CONFIG_H
- # include <config.h>
- #endif
- /* [email protected] June 13 1997 */
- #include <stdio.h>
- #include <sys/types.h>
- #include "slapi-plugin.h"
- #include "slap.h"
- #include <ssl.h>
- /* entry list node */
- typedef struct Entry_Node{
- Slapi_Entry *data;
- struct Entry_Node *next;
- } Entry_Node;
- /* referral list node */
- typedef struct Referral_Node{
- char *data;
- struct Referral_Node *next;
- } Referral_Node;
- /* data that must be passed to slapi_search_internal_callback */
- typedef struct plugin_search_internal_data{
- int rc;
- int num_entries;
- int num_referrals;
- Entry_Node *entry_list_head;
- Referral_Node *referral_list_head;
- } plugin_search_internal_data;
- /* callback functions */
- typedef struct callback_fn_ptrs{
- plugin_result_callback p_res_callback;
- plugin_search_entry_callback p_srch_entry_callback;
- plugin_referral_entry_callback p_ref_entry_callback;
- void *callback_data;
- }callback_fn_ptrs;
- /* forward declarations */
- static int seq_internal_callback_pb (Slapi_PBlock *pb, void *callback_data,
- plugin_result_callback prc,
- plugin_search_entry_callback psec,
- plugin_referral_entry_callback prec);
- static int search_internal_pb (Slapi_PBlock *pb);
- static int search_internal_callback_pb (Slapi_PBlock *pb, void *callback_data, plugin_result_callback prc,
- plugin_search_entry_callback psec, plugin_referral_entry_callback prec);
- void
- internal_getresult_callback(struct conn *unused1,
- struct op *op,
- int err,
- char *unused2,
- char *unused3,
- int unused4,
- struct berval **unused5)
- {
- if (op != NULL)
- {
- *((int *)op->o_handler_data) = err;
- }
- }
- void
- internal_res_callback(struct conn *unused1, struct op *op, int err, char *unused2,
- char *unused3, int unused4, struct berval **unused5)
- {
- /* make sure the user has a callback defined, if so do it, otherwise do nothing */
- if( ((callback_fn_ptrs *)op->o_handler_data) != NULL
- && ((callback_fn_ptrs *)op->o_handler_data)->p_res_callback != NULL
- )
- {
- ((callback_fn_ptrs *)op->o_handler_data)->p_res_callback
- (err, ((callback_fn_ptrs *)op->o_handler_data)->callback_data);
- }
- }
- int
- internal_srch_entry_callback(Slapi_Backend* be, Connection* conn,
- Operation* op, Slapi_Entry* e)
- {
- /* make sure the user has a callback defined, if so do it, otherwise do nothing */
- if( ((callback_fn_ptrs *)op->o_handler_data) != NULL
- && ((callback_fn_ptrs *)op->o_handler_data)->p_srch_entry_callback != NULL
- )
- {
- return(((callback_fn_ptrs *)op->o_handler_data)->p_srch_entry_callback
- (e, ((callback_fn_ptrs *)op->o_handler_data)->callback_data));
- }
- return(0);
- }
- int
- internal_ref_entry_callback(Slapi_Backend * be, Connection *conn,
- Operation *op, struct berval **ireferral)
- {
- int i;
- /* make sure the user has a callback defined, if so do it, otherwise do nothing */
- if( ((callback_fn_ptrs *)op->o_handler_data) != NULL
- && ((callback_fn_ptrs *)op->o_handler_data)->p_ref_entry_callback != NULL
- && ireferral != NULL
- )
- {
- /* loop over referrals calling callback for each one */
- for(i=0; ireferral[i] != NULL; i++)
- {
- ((callback_fn_ptrs *)op->o_handler_data)->p_ref_entry_callback(ireferral[i]->bv_val,
- ((callback_fn_ptrs *)op->o_handler_data)->callback_data);
- }
- }
- return(0);
- }
- Slapi_Operation*
- internal_operation_new(unsigned long op_type, int flags)
- {
- Slapi_Operation *op= operation_new(flags | OP_FLAG_INTERNAL /*Internal*/);
- /* set operation type: add, delete, etc */
- operation_set_type(op,op_type);
- /* Call the plugin extension constructors */
- op->o_extension = factory_create_extension(get_operation_object_type(),op,NULL /* Parent */);
- return op;
- }
- /******************************************************************************
- *
- * do_disconnect_server
- *
- *
- *
- *
- *******************************************************************************/
- /* this is just a wrapper exposed to the plugins */
- void
- slapi_disconnect_server(Slapi_Connection *conn)
- {
- do_disconnect_server(conn, conn->c_connid, -1);
- }
- static get_disconnect_server_fn_ptr disconnect_server_fn = NULL;
- void
- do_disconnect_server(Connection *conn, PRUint64 opconnid, int opid)
- {
- if (NULL == disconnect_server_fn) {
- if (get_entry_point(ENTRY_POINT_DISCONNECT_SERVER, (caddr_t *)(&disconnect_server_fn)) < 0) {
- return;
- }
- }
- /* It seems that we only call this from result.c when the ber_flush fails. */
- (disconnect_server_fn)(conn, opconnid, opid, SLAPD_DISCONNECT_BER_FLUSH, 0);
- }
- /******************************************************************************
- *
- * slapi_compare_internal
- *
- * no plans to implement this, but placeholder incase we change our mind
- *
- *
- *******************************************************************************/
- Slapi_PBlock *
- slapi_compare_internal(char * dn,
- char *attr,
- char *value,
- LDAPControl **controls)
- {
- printf("slapi_compare_internal not yet implemented \n");
- return(0);
- }
- int
- slapi_seq_callback( const char *ibase,
- int type,
- char *attrname,
- char *val,
- char **attrs,
- int attrsonly,
- void *callback_data,
- LDAPControl **controls,
- plugin_result_callback res_callback,
- plugin_search_entry_callback srch_callback,
- plugin_referral_entry_callback ref_callback)
- {
- int r;
- Slapi_PBlock pb;
- if (ibase == NULL)
- {
- slapi_log_error(SLAPI_LOG_FATAL, NULL,
- "slapi_seq_callback: NULL parameter\n");
- return -1;
- }
- pblock_init(&pb);
- slapi_seq_internal_set_pb(&pb, (char *)ibase, type, attrname, val, attrs, attrsonly, controls,
- plugin_get_default_component_id(), 0);
- r= seq_internal_callback_pb (&pb, callback_data, res_callback, srch_callback, ref_callback);
- pblock_done(&pb);
- return r;
- }
- /* pblock should contain the following data (can be set via call to slapi_seq_internal_set_pb):
- SLAPI_SEARCH_TARGET set to search base
- SAPI_SEQ_TYPE set to sequential access type (SLAPI_SEQ_FIRST, SLAPI_SEQ_NEXT, etc.
- SLAPI_SEQ_ATTRNAME the next two fields define attribute value assertion
- SLAPI_SEQ_VAL relative to which access is performed.
- SLAPI_CONTROLS_ARG set to request controls if present
- SLAPI_SEARCH_ATTRS set to the list of attributes to return
- SLAPI_SEARCH_ATTRSONLY tells whether attribute values should be returned.
- */
- int slapi_seq_internal_callback_pb (Slapi_PBlock *pb, void *callback_data, plugin_result_callback res_callback,
- plugin_search_entry_callback srch_callback,
- plugin_referral_entry_callback ref_callback)
- {
- if (pb == NULL)
- return -1;
- if (!allow_operation (pb))
- {
- send_ldap_result( pb, LDAP_UNWILLING_TO_PERFORM, NULL,
- "This plugin is not configured to access operation target data", 0, NULL );
- return 0;
- }
- return (seq_internal_callback_pb (pb, callback_data, res_callback, srch_callback, ref_callback));
- }
- void slapi_search_internal_set_pb (Slapi_PBlock *pb, const char *base, int scope, const char *filter, char **attrs,
- int attrsonly, LDAPControl **controls, const char *uniqueid,
- Slapi_ComponentId *plugin_identity, int operation_flags)
- {
- Operation *op;
- if (pb == NULL || base == NULL)
- {
- slapi_log_error(SLAPI_LOG_FATAL, NULL,
- "slapi_search_internal_set_pb: NULL parameter\n");
- return;
- }
- op= internal_operation_new(SLAPI_OPERATION_SEARCH,operation_flags);
- slapi_pblock_set(pb, SLAPI_OPERATION, op);
- slapi_pblock_set(pb, SLAPI_SEARCH_TARGET, (void*)base);
- slapi_pblock_set(pb, SLAPI_SEARCH_SCOPE, &scope);
- slapi_pblock_set(pb, SLAPI_SEARCH_STRFILTER, (void*)filter);
- slapi_pblock_set(pb, SLAPI_CONTROLS_ARG, controls);
- slapi_pblock_set(pb, SLAPI_SEARCH_ATTRS, attrs);
- slapi_pblock_set(pb, SLAPI_SEARCH_ATTRSONLY, &attrsonly);
- if (uniqueid)
- {
- slapi_pblock_set(pb, SLAPI_TARGET_UNIQUEID, (void*)uniqueid);
- }
- slapi_pblock_set(pb, SLAPI_PLUGIN_IDENTITY, (void*)plugin_identity);
- }
- void slapi_seq_internal_set_pb(Slapi_PBlock *pb, char *base, int type, char *attrname, char *val,
- char **attrs, int attrsonly, LDAPControl **controls,
- Slapi_ComponentId *plugin_identity, int operation_flags)
- {
- Operation *op;
- if (pb == NULL || base == NULL)
- {
- slapi_log_error(SLAPI_LOG_FATAL, NULL,
- "slapi_seq_internal_set_pb: NULL parameter\n");
- return;
- }
- op= internal_operation_new(SLAPI_OPERATION_SEARCH,operation_flags);
- slapi_pblock_set(pb, SLAPI_OPERATION, op);
- slapi_pblock_set(pb, SLAPI_SEARCH_TARGET, base);
- slapi_pblock_set(pb, SLAPI_SEQ_TYPE, &type);
- slapi_pblock_set(pb, SLAPI_SEQ_ATTRNAME, attrname);
- slapi_pblock_set(pb, SLAPI_SEQ_VAL, val);
- slapi_pblock_set(pb, SLAPI_SEARCH_ATTRS, attrs);
- slapi_pblock_set(pb, SLAPI_SEARCH_ATTRSONLY, &attrsonly);
- slapi_pblock_set(pb, SLAPI_CONTROLS_ARG, controls);
- slapi_pblock_set(pb, SLAPI_PLUGIN_IDENTITY, plugin_identity);
- }
- static int seq_internal_callback_pb (Slapi_PBlock *pb, void *callback_data,
- plugin_result_callback prc,
- plugin_search_entry_callback psec,
- plugin_referral_entry_callback prec)
- {
- int rc;
- LDAPControl **controls;
- Operation *op;
- struct callback_fn_ptrs callback_handler_data;
- Slapi_Backend *be;
- Slapi_DN sdn;
- char *base;
- char *attrname, *val;
- slapi_pblock_get(pb, SLAPI_SEARCH_TARGET, &base);
- slapi_pblock_get(pb, SLAPI_CONTROLS_ARG, &controls);
- if (base == NULL) {
- slapi_sdn_init_dn_byval(&sdn,"");
- } else {
- slapi_sdn_init_dn_byval(&sdn, base);
- }
- be = slapi_be_select(&sdn);
- callback_handler_data.p_res_callback = prc;
- callback_handler_data.p_srch_entry_callback = psec;
- callback_handler_data.p_ref_entry_callback = prec;
- callback_handler_data.callback_data = callback_data;
- slapi_pblock_get(pb, SLAPI_OPERATION, &op);
- op->o_handler_data = (void *)&callback_handler_data;
- op->o_result_handler = internal_res_callback;
- op->o_search_entry_handler = internal_srch_entry_callback;
- op->o_search_referral_handler = internal_ref_entry_callback;
-
- /* set target specification of the operation used to decide which plugins are called for the operation */
- operation_set_target_spec (op, &sdn);
- /* Normalize the attribute type and value */
- slapi_pblock_get (pb, SLAPI_SEQ_ATTRNAME, &attrname);
- slapi_pblock_get (pb, SLAPI_SEQ_VAL, &val);
- attrname = slapi_attr_syntax_normalize(attrname);
- val = ( NULL == val ) ? NULL : slapi_ch_strdup( val );
- slapi_pblock_set(pb, SLAPI_BACKEND, be);
- slapi_pblock_set(pb, SLAPI_PLUGIN, be->be_database);
- slapi_pblock_set(pb, SLAPI_SEQ_ATTRNAME, attrname);
- slapi_pblock_set(pb, SLAPI_SEQ_VAL, val);
- slapi_pblock_set(pb, SLAPI_REQCONTROLS, controls);
- /* set actions taken to process the operation */
- set_config_params (pb);
- /* set common parameters */
- set_common_params (pb);
- if (be->be_seq != NULL)
- {
- rc = (*be->be_seq)(pb);
- }
- else
- {
- send_ldap_result(pb, LDAP_UNWILLING_TO_PERFORM, NULL, "Function not implemented", 0, NULL);
- rc = 0;
- }
- slapi_ch_free((void **) &attrname);
- slapi_ch_free((void **) &val);
- slapi_sdn_done(&sdn);
- return rc;
- }
- int
- slapi_search_internal_callback(const char *ibase,
- int scope,
- const char *ifstr,
- char **attrs,
- int attrsonly,
- void *callback_data,
- LDAPControl **controls,
- plugin_result_callback res_callback,
- plugin_search_entry_callback srch_callback,
- plugin_referral_entry_callback ref_callback)
- {
- Slapi_PBlock pb;
- int rc = 0;
- pblock_init(&pb);
- slapi_search_internal_set_pb (&pb, ibase, scope, ifstr, attrs, attrsonly,
- controls, NULL, plugin_get_default_component_id(), 0);
-
- rc = search_internal_callback_pb (&pb, callback_data, res_callback,
- srch_callback, ref_callback);
- pblock_done(&pb);
- return (rc);
- }
- Slapi_PBlock *
- slapi_search_internal(const char *base,
- int scope,
- const char *filter,
- LDAPControl **controls,
- char **attrs,
- int attrsonly)
- {
-
- Slapi_PBlock *pb;
- /* initialize pb */
- pb = slapi_pblock_new();
- if (pb)
- {
- slapi_search_internal_set_pb (pb, base, scope, filter, attrs, attrsonly, controls,
- NULL, plugin_get_default_component_id(), 0);
-
- search_internal_pb (pb);
- }
-
- return pb;
- }
- /* This function free searchs result or referral set on internal_ops in pblocks */
- void
- slapi_free_search_results_internal(Slapi_PBlock *pb)
- {
- int i;
-
- if(pb == NULL)
- {
- return;
- }
- if(pb->pb_plugin_internal_search_op_entries != NULL)
- {
- for(i=0; pb->pb_plugin_internal_search_op_entries[i] != NULL; i++)
- {
- slapi_entry_free(pb->pb_plugin_internal_search_op_entries[i]);
- }
- slapi_ch_free((void**)&(pb->pb_plugin_internal_search_op_entries));
- }
- /* free v3 referrals made from result handler */
- if(pb->pb_plugin_internal_search_op_referrals != NULL)
- {
- for(i=0; pb->pb_plugin_internal_search_op_referrals[i] != NULL; i++)
- {
- slapi_ch_free((void**)&(pb->pb_plugin_internal_search_op_referrals[i]));
- }
- slapi_ch_free((void**)&(pb->pb_plugin_internal_search_op_referrals));
- }
- }
- /* this functions can be used for dn as well as uniqueid based operations */
- /* pblock should contain the following data (can be set via call to slapi_search_internal_set_pb):
- For uniqueid based search:
- SLAPI_TARGET_DN set to dn that allows to select right backend
- SLAPI_TARGET_UNIQUEID set to the uniqueid of the entry we are looking for
- For dn based search:
- SLAPI_TARGET_DN set to search base
- SLAPI_ORIGINAL_TARGET_DN set to original un-normalized search base
- SLAPI_SEARCH_SCOPE set to search scope
- SLAPI_SEARCH_STRFILTER set to search filter
- SLAPI_CONTROLS_ARG set to request controls if present
- SLAPI_SEARCH_ATTRS set to the list of attributes to return
- SLAPI_SEARCH_ATTRSONLY tells whether attribute values should be returned.
- */
- int slapi_search_internal_pb (Slapi_PBlock *pb)
- {
- if (pb == NULL)
- return -1;
- if (!allow_operation (pb))
- {
- slapi_send_ldap_result( pb, LDAP_UNWILLING_TO_PERFORM, NULL,
- "This plugin is not configured to access operation target data", 0, NULL );
- return 0;
- }
- return search_internal_pb (pb);
- }
- /* pblock should contain the same data as for slapi_search_internal_pb */
- int slapi_search_internal_callback_pb (Slapi_PBlock *pb, void *callback_data,
- plugin_result_callback prc,
- plugin_search_entry_callback psec,
- plugin_referral_entry_callback prec)
- {
- if (pb == NULL)
- return -1;
- if (!allow_operation (pb))
- {
- send_ldap_result( pb, LDAP_UNWILLING_TO_PERFORM, NULL,
- "This plugin is not configured to access operation target data", 0, NULL );
- return 0;
- }
- return (search_internal_callback_pb (pb, callback_data, prc, psec, prec));
- }
- static int
- internal_plugin_search_entry_callback(Slapi_Entry *e, void *callback_data)
- {
- Entry_Node *this_entry;
-
- /* add this entry to the list of entries we are making */
- this_entry = (Entry_Node *)slapi_ch_calloc(1,sizeof(Entry_Node));
-
- if ((this_entry->data = slapi_entry_dup(e)) == NULL)
- {
- return(0);
- }
- this_entry->next = ((plugin_search_internal_data *) callback_data)->entry_list_head;
- ((plugin_search_internal_data *) callback_data)->entry_list_head = this_entry;
- ((plugin_search_internal_data *) callback_data)->num_entries++;
- return(0);
- }
- static int
- internal_plugin_search_referral_callback(char *referral, void *callback_data)
- {
- Referral_Node *this_referral;
-
- /* add this to the list of referrals we are making */
- this_referral = (Referral_Node *)slapi_ch_calloc(1,sizeof(Referral_Node));
- this_referral->data = slapi_ch_strdup(referral);
- this_referral->next = ((plugin_search_internal_data *) callback_data)->referral_list_head;
- ((plugin_search_internal_data *) callback_data)->referral_list_head = this_referral;
- ((plugin_search_internal_data *) callback_data)->num_referrals++;
- return(0);
- }
- static void internal_plugin_result_callback(int rc, void *callback_data)
- {
- /* put the result into pb_op_result */
- ((plugin_search_internal_data *) callback_data)->rc = rc;
- }
- static int search_internal_pb (Slapi_PBlock *pb)
- {
- plugin_search_internal_data psid;
- Entry_Node *iterator, *tmp;
- Referral_Node *ref_iterator, *ref_tmp;
- int i;
- int opresult = 0;
- Slapi_Entry **pb_search_entries = NULL;
- char **pb_search_referrals = NULL;
- PR_ASSERT (pb);
- /* initialize psid */
- psid.rc = -1;
- psid.num_entries =0;
- psid.num_referrals =0;
- psid.entry_list_head = NULL;
- psid.referral_list_head = NULL;
- /* setup additional pb data */
- slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_RESULT, &opresult);
- slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, pb_search_entries);
- slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_SEARCH_REFERRALS, pb_search_referrals);
-
- /* call internal search callback, define search_entry_callback, and result_callback such
- that the results of the search are stuffed into pb */
- search_internal_callback_pb (pb, &psid, internal_plugin_result_callback,
- internal_plugin_search_entry_callback,
- internal_plugin_search_referral_callback);
- opresult = psid.rc;
- /* stuff search entry pointers from linked list to contiguous array for pblock */
- pb_search_entries = (Slapi_Entry **)slapi_ch_calloc((psid.num_entries + 1), sizeof(Slapi_Entry *));
- for(i=0,iterator = psid.entry_list_head; iterator !=NULL; iterator=iterator->next, i++)
- {
- pb_search_entries[i]= iterator->data;
- }
- pb_search_entries[i]=NULL;
- /* free the linked list now that data has been put in the array */
- iterator=psid.entry_list_head;
- while(iterator != NULL)
- {
- /* free the data held in this node */
- tmp = iterator;
- iterator = iterator->next;
- /* free the node */
- if(tmp != NULL)
- {
- slapi_ch_free((void **) &tmp);
- }
- }
- psid.entry_list_head = NULL;
- /* stuff referrals list into an array if we got any to put into the pblock */
- if(psid.num_referrals != 0)
- {
- pb_search_referrals = (char **)slapi_ch_calloc((psid.num_referrals + 1), sizeof(char *));
- for(i=0, ref_iterator = psid.referral_list_head; ref_iterator !=NULL; ref_iterator=ref_iterator->next, i++)
- {
- pb_search_referrals[i]= ref_iterator->data;
- }
- pb_search_referrals[i]=NULL;
- /* free the linked list now that data has been put in the array */
- ref_iterator=psid.referral_list_head;
- while(ref_iterator != NULL)
- {
- ref_tmp = ref_iterator;
- ref_iterator = ref_iterator->next;
- /* free the node */
- if(ref_tmp != NULL)
- {
- slapi_ch_free((void **) &ref_tmp);
- }
- }
- psid.referral_list_head = NULL;
- }
- /* set the result, the array of entries, and the array of referrals in pb */
- slapi_pblock_set(pb, SLAPI_NENTRIES, &psid.num_entries);
- slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_RESULT, &opresult);
- slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, pb_search_entries);
- slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_SEARCH_REFERRALS, pb_search_referrals);
- return 0;
- }
- static int search_internal_callback_pb (Slapi_PBlock *pb, void *callback_data,
- plugin_result_callback prc,
- plugin_search_entry_callback psec,
- plugin_referral_entry_callback prec)
- {
- LDAPControl **controls;
- Operation *op;
- struct slapi_filter *filter = NULL;
- char *fstr = NULL;
- struct callback_fn_ptrs callback_handler_data;
- int scope;
- char *ifstr;
- int opresult;
- int rc = 0;
- char *original_base = 0;
- char *new_base = 0;
- PR_ASSERT (pb);
- /* retrieve search parameters */
- slapi_pblock_get(pb, SLAPI_SEARCH_SCOPE, &scope);
- slapi_pblock_get(pb, SLAPI_SEARCH_STRFILTER, &ifstr);
- slapi_pblock_get(pb, SLAPI_CONTROLS_ARG, &controls);
- /* data validation */
- if (ifstr == NULL || (scope != LDAP_SCOPE_BASE && scope != LDAP_SCOPE_ONELEVEL
- && scope != LDAP_SCOPE_SUBTREE))
- {
- opresult = LDAP_PARAM_ERROR;
- slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_RESULT, &opresult);
- return -1;
- }
- callback_handler_data.p_res_callback = prc;
- callback_handler_data.p_srch_entry_callback = psec;
- callback_handler_data.p_ref_entry_callback = prec;
- callback_handler_data.callback_data = callback_data;
- slapi_pblock_get(pb, SLAPI_OPERATION, &op);
- op->o_handler_data = (void *)&callback_handler_data;
- op->o_result_handler = internal_res_callback;
- op->o_search_entry_handler = internal_srch_entry_callback;
- op->o_search_referral_handler = internal_ref_entry_callback;
-
- filter = slapi_str2filter((fstr = slapi_ch_strdup(ifstr)));
- if(scope == LDAP_SCOPE_BASE) {
- filter->f_flags |= (SLAPI_FILTER_LDAPSUBENTRY |
- SLAPI_FILTER_TOMBSTONE | SLAPI_FILTER_RUV);
- }
- if (NULL == filter)
- {
- send_ldap_result(pb, LDAP_FILTER_ERROR, NULL, NULL, 0, NULL);
- rc = -1;
- goto done;
- }
- filter_normalize(filter);
- slapi_pblock_set(pb, SLAPI_SEARCH_FILTER, filter);
- slapi_pblock_set(pb, SLAPI_REQCONTROLS, controls);
- /* set actions taken to process the operation */
- set_config_params (pb);
- /* set parameters common for all internal operations */
- set_common_params (pb);
- {
- int timelimit = -1;
- int sizelimit = -1;
- int deref = LDAP_DEREF_ALWAYS;
- slapi_pblock_set(pb, SLAPI_SEARCH_DEREF, &deref);
- slapi_pblock_set(pb, SLAPI_SEARCH_TIMELIMIT, &timelimit);
- slapi_pblock_set(pb, SLAPI_SEARCH_SIZELIMIT, &sizelimit);
- }
- /* plugins which play with the search may
- * change the search params may allocate
- * memory so we need to keep track of
- * changed base search strings
- */
- slapi_pblock_get(pb, SLAPI_SEARCH_TARGET, &original_base);
- slapi_pblock_set(pb, SLAPI_ORIGINAL_TARGET_DN, slapi_ch_strdup(original_base));
- op_shared_search (pb, 1);
- slapi_pblock_get(pb, SLAPI_SEARCH_TARGET, &new_base);
- slapi_pblock_get(pb, SLAPI_SEARCH_FILTER, &filter);
- done:
- slapi_ch_free((void **) & fstr);
- if (filter != NULL)
- {
- slapi_filter_free(filter, 1 /* recurse */);
- }
- if(original_base != new_base)
- slapi_ch_free_string(&new_base);
- /* we strdup'd this above - need to free */
- slapi_pblock_get(pb, SLAPI_ORIGINAL_TARGET_DN, &original_base);
- slapi_ch_free_string(&original_base);
- return(rc);
- }
- /* allow/disallow operation based of the plugin configuration */
- PRBool allow_operation (Slapi_PBlock *pb)
- {
- char *dn = NULL;
- struct slapdplugin *plugin = NULL;
- Slapi_DN sdn;
- PRBool allow;
- struct slapi_componentid * cid=NULL;
- PR_ASSERT (pb);
-
- /* make sure that users of new API provide plugin identity */
- slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &cid);
- if (cid == NULL)
- {
- slapi_log_error( SLAPI_LOG_FATAL, NULL, "allow_operation: component identity is NULL\n");
- return PR_FALSE;
- }
- plugin=(struct slapdplugin *) cid->sci_plugin;
- if (plugin == NULL)
- {
- slapi_log_error( SLAPI_LOG_FATAL, NULL, "allow_operation: plugin identity is NULL\n");
- return PR_FALSE;
- }
- slapi_pblock_get (pb, SLAPI_TARGET_DN, &dn);
- if (dn == NULL) {
- slapi_sdn_init_dn_byval(&sdn,"");
- } else {
- slapi_sdn_init_dn_byval(&sdn, dn);
- }
- allow = plugin_allow_internal_op (&sdn, plugin);
-
- slapi_sdn_done (&sdn);
- return allow;
- }
- /* set operation configuration based on the plugin configuration */
- void set_config_params (Slapi_PBlock *pb)
- {
- Slapi_Operation *operation;
- struct slapdplugin *plugin = NULL;
- char *dn;
- struct slapi_componentid * cid=NULL;
- slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &cid);
- if (cid)
- plugin=(struct slapdplugin *) cid->sci_plugin;
- /* set actions */
- slapi_pblock_get( pb, SLAPI_OPERATION, &operation);
- operation_set_flag(operation,plugin_build_operation_action_bitmap(operation->o_flags, plugin));
-
- /* Check if we have a flag to keep the operation secret */
- if (operation_is_flag_set(operation, OP_FLAG_ACTION_NOLOG)) {
- /* Clear the LOG_AUDIT and LOG_CHANGES flag */
- operation_clear_flag(operation, OP_FLAG_ACTION_LOG_AUDIT | OP_FLAG_ACTION_LOG_CHANGES);
- }
-
- /* set name to be used for creator's and modifiers attributes */
- dn = plugin_get_dn (plugin);
- if (dn)
- slapi_sdn_init_dn_passin(&operation->o_sdn, dn);
- }
- /* set parameters common for all internal operations */
- void set_common_params (Slapi_PBlock *pb)
- {
- int isroot = 1;
- LDAPControl **controls;
- slapi_pblock_get(pb, SLAPI_CONTROLS_ARG, &controls);
- if (NULL != controls)
- {
- int managedsait = slapi_control_present(controls,
- LDAP_CONTROL_MANAGEDSAIT, NULL, NULL);
- int pwpolicy_ctrl = slapi_control_present(controls,
- LDAP_X_CONTROL_PWPOLICY_REQUEST, NULL, NULL);
-
- slapi_pblock_set(pb, SLAPI_MANAGEDSAIT, &managedsait);
- slapi_pblock_set(pb, SLAPI_PWPOLICY, &pwpolicy_ctrl);
- }
- slapi_pblock_set(pb, SLAPI_REQUESTOR_ISROOT, &isroot);
- }
- /*
- * Given a DN, find an entry by doing an internal search. An LDAP error
- * code is returned. To check if an entry exists without returning a
- * copy of the entry, NULL can be passed for ret_entry.
- */
- int
- slapi_search_internal_get_entry_ext( Slapi_DN *dn, char ** attrs, Slapi_Entry **ret_entry , void * component_identity, void *txn )
- {
- Slapi_Entry **entries = NULL;
- Slapi_PBlock *int_search_pb = NULL;
- int rc = 0;
-
- if (ret_entry) {
- *ret_entry = NULL;
- }
- int_search_pb = slapi_pblock_new ();
- slapi_search_internal_set_pb ( int_search_pb, slapi_sdn_get_dn(dn), LDAP_SCOPE_BASE, "(|(objectclass=*)(objectclass=ldapsubentry))",
- attrs ,
- 0 /* attrsonly */, NULL /* controls */,
- NULL /* uniqueid */,
- component_identity, 0 /* actions */ );
- slapi_pblock_set( int_search_pb, SLAPI_TXN, txn );
- slapi_search_internal_pb ( int_search_pb );
- slapi_pblock_get( int_search_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc );
- if ( LDAP_SUCCESS == rc ) {
- slapi_pblock_get( int_search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries );
- if ( NULL != entries && NULL != entries[ 0 ]) {
- /* Only need to dup the entry if the caller passed ret_entry in. */
- if (ret_entry) {
- Slapi_Entry *temp_entry = NULL;
- temp_entry = entries[ 0 ];
- *ret_entry = slapi_entry_dup(temp_entry);
- }
- } else {
- /* No entry there */
- rc = LDAP_NO_SUCH_OBJECT;
- }
- }
- slapi_free_search_results_internal(int_search_pb);
- slapi_pblock_destroy(int_search_pb);
- int_search_pb = NULL;
- return rc;
- }
- /*
- * Given a DN, find an entry by doing an internal search. An LDAP error
- * code is returned. To check if an entry exists without returning a
- * copy of the entry, NULL can be passed for ret_entry.
- */
- int
- slapi_search_internal_get_entry( Slapi_DN *dn, char ** attrs, Slapi_Entry **ret_entry , void * component_identity)
- {
- return slapi_search_internal_get_entry_ext(dn, attrs, ret_entry, component_identity, NULL);
- }
|