1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3 *
4 * Copyright 2002-2021 The OpenLDAP Foundation.
5 * Portions Copyright 1997,2002-2003 IBM Corporation.
6 * All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
10 * Public License.
11 *
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
15 */
16 /* ACKNOWLEDGEMENTS:
17 * This work was initially developed by IBM Corporation for use in
18 * IBM products and subsequently ported to OpenLDAP Software by
19 * Steve Omrani. Additional significant contributors include:
20 * Luke Howard
21 */
22
23 #include "portable.h"
24
25 /*
26 * Note: if ltdl.h is not available, slapi should not be compiled
27 */
28
29 #ifdef HAVE_LTDL_H
30 #include "ldap_pvt_thread.h"
31 #include "slap.h"
32 #include "slap-config.h"
33 #include "slapi.h"
34 #include "lutil.h"
35
36 #include <ltdl.h>
37
38 static int slapi_int_load_plugin( Slapi_PBlock *, const char *, const char *, int,
39 SLAPI_FUNC *, lt_dlhandle * );
40
41 /* pointer to link list of extended objects */
42 static ExtendedOp *pGExtendedOps = NULL;
43
44 /*********************************************************************
45 * Function Name: plugin_pblock_new
46 *
47 * Description: This routine creates a new Slapi_PBlock structure,
48 * loads in the plugin module and executes the init
49 * function provided by the module.
50 *
51 * Input: type - type of the plugin, such as SASL, database, etc.
52 * path - the loadpath to load the module in
53 * initfunc - name of the plugin function to execute first
54 * argc - number of arguments
55 * argv[] - an array of char pointers point to
56 * the arguments passed in via
57 * the configuration file.
58 *
59 * Output:
60 *
61 * Return Values: a pointer to a newly created Slapi_PBlock structure or
62 * NULL - function failed
63 *
64 * Messages: None
65 *********************************************************************/
66
67 static Slapi_PBlock *
plugin_pblock_new(int type,int argc,char * argv[])68 plugin_pblock_new(
69 int type,
70 int argc,
71 char *argv[] )
72 {
73 Slapi_PBlock *pPlugin = NULL;
74 Slapi_PluginDesc *pPluginDesc = NULL;
75 lt_dlhandle hdLoadHandle;
76 int rc;
77 char **av2 = NULL, **ppPluginArgv;
78 char *path = argv[2];
79 char *initfunc = argv[3];
80
81 pPlugin = slapi_pblock_new();
82 if ( pPlugin == NULL ) {
83 rc = LDAP_NO_MEMORY;
84 goto done;
85 }
86
87 slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)&type );
88 slapi_pblock_set( pPlugin, SLAPI_PLUGIN_ARGC, (void *)&argc );
89
90 av2 = ldap_charray_dup( argv );
91 if ( av2 == NULL ) {
92 rc = LDAP_NO_MEMORY;
93 goto done;
94 }
95
96 if ( argc > 0 ) {
97 ppPluginArgv = &av2[4];
98 } else {
99 ppPluginArgv = NULL;
100 }
101
102 slapi_pblock_set( pPlugin, SLAPI_PLUGIN_ARGV, (void *)ppPluginArgv );
103 slapi_pblock_set( pPlugin, SLAPI_X_CONFIG_ARGV, (void *)av2 );
104
105 rc = slapi_int_load_plugin( pPlugin, path, initfunc, 1, NULL, &hdLoadHandle );
106 if ( rc != 0 ) {
107 goto done;
108 }
109
110 if ( slapi_pblock_get( pPlugin, SLAPI_PLUGIN_DESCRIPTION, (void **)&pPluginDesc ) == 0 &&
111 pPluginDesc != NULL ) {
112 slapi_log_error(SLAPI_LOG_TRACE, "plugin_pblock_new",
113 "Registered plugin %s %s [%s] (%s)\n",
114 pPluginDesc->spd_id,
115 pPluginDesc->spd_version,
116 pPluginDesc->spd_vendor,
117 pPluginDesc->spd_description);
118 }
119
120 done:
121 if ( rc != 0 && pPlugin != NULL ) {
122 slapi_pblock_destroy( pPlugin );
123 pPlugin = NULL;
124 if ( av2 != NULL ) {
125 ldap_charray_free( av2 );
126 }
127 }
128
129 return pPlugin;
130 }
131
132 /*********************************************************************
133 * Function Name: slapi_int_register_plugin
134 *
135 * Description: insert the slapi_pblock structure to a given position the end of the plugin
136 * list
137 *
138 * Input: a pointer to a plugin slapi_pblock structure to be added to
139 * the list
140 *
141 * Output: none
142 *
143 * Return Values: LDAP_SUCCESS - successfully inserted.
144 * LDAP_LOCAL_ERROR.
145 *
146 * Messages: None
147 *********************************************************************/
148 int
slapi_int_register_plugin_index(Backend * be,Slapi_PBlock * pPB,int index)149 slapi_int_register_plugin_index(
150 Backend *be,
151 Slapi_PBlock *pPB,
152 int index )
153 {
154 Slapi_PBlock *pTmpPB;
155 Slapi_PBlock *pSavePB;
156 int pos = 0, rc = LDAP_SUCCESS;
157
158 assert( be != NULL );
159
160 pTmpPB = SLAPI_BACKEND_PBLOCK( be );
161 if ( pTmpPB == NULL || index == 0 ) {
162 SLAPI_BACKEND_PBLOCK( be ) = pPB;
163 } else {
164 while ( pTmpPB != NULL && rc == LDAP_SUCCESS &&
165 ( index < 0 || pos++ < index ) ) {
166 pSavePB = pTmpPB;
167 rc = slapi_pblock_get( pTmpPB, SLAPI_IBM_PBLOCK, &pTmpPB );
168 }
169
170 if ( rc == LDAP_SUCCESS ) {
171 rc = slapi_pblock_set( pSavePB, SLAPI_IBM_PBLOCK, (void *)pPB );
172 }
173 }
174
175 if ( index >= 0 && rc == LDAP_SUCCESS ) {
176 rc = slapi_pblock_set( pPB, SLAPI_IBM_PBLOCK, (void *)pTmpPB );
177 }
178
179 return ( rc != LDAP_SUCCESS ) ? LDAP_OTHER : LDAP_SUCCESS;
180 }
181
182 int
slapi_int_register_plugin(Backend * be,Slapi_PBlock * pPB)183 slapi_int_register_plugin(
184 Backend *be,
185 Slapi_PBlock *pPB )
186 {
187 return slapi_int_register_plugin_index( be, pPB, -1 );
188 }
189
190 /*********************************************************************
191 * Function Name: slapi_int_get_plugins
192 *
193 * Description: get the desired type of function pointers defined
194 * in all the plugins
195 *
196 * Input: the type of the functions to get, such as pre-operation,etc.
197 *
198 * Output: none
199 *
200 * Return Values: this routine returns a pointer to an array of function
201 * pointers containing backend-specific plugin functions
202 * followed by global plugin functions
203 *
204 * Messages: None
205 *********************************************************************/
206 int
slapi_int_get_plugins(Backend * be,int functype,SLAPI_FUNC ** ppFuncPtrs)207 slapi_int_get_plugins(
208 Backend *be,
209 int functype,
210 SLAPI_FUNC **ppFuncPtrs )
211 {
212
213 Slapi_PBlock *pCurrentPB;
214 SLAPI_FUNC FuncPtr;
215 SLAPI_FUNC *pTmpFuncPtr;
216 int numPB = 0;
217 int rc = LDAP_SUCCESS;
218
219 assert( ppFuncPtrs != NULL );
220 *ppFuncPtrs = NULL;
221
222 if ( be == NULL ) {
223 goto done;
224 }
225
226 pCurrentPB = SLAPI_BACKEND_PBLOCK( be );
227
228 while ( pCurrentPB != NULL && rc == LDAP_SUCCESS ) {
229 rc = slapi_pblock_get( pCurrentPB, functype, &FuncPtr );
230 if ( rc == LDAP_SUCCESS ) {
231 if ( FuncPtr != NULL ) {
232 numPB++;
233 }
234 rc = slapi_pblock_get( pCurrentPB,
235 SLAPI_IBM_PBLOCK, &pCurrentPB );
236 }
237 }
238
239 if ( numPB == 0 ) {
240 rc = LDAP_SUCCESS;
241 goto done;
242 }
243
244 /*
245 * Now, build the function pointer array of backend-specific
246 * plugins followed by global plugins.
247 */
248 *ppFuncPtrs = pTmpFuncPtr =
249 (SLAPI_FUNC *)ch_malloc( ( numPB + 1 ) * sizeof(SLAPI_FUNC) );
250 if ( ppFuncPtrs == NULL ) {
251 rc = LDAP_NO_MEMORY;
252 goto done;
253 }
254
255 pCurrentPB = SLAPI_BACKEND_PBLOCK( be );
256
257 while ( pCurrentPB != NULL && rc == LDAP_SUCCESS ) {
258 rc = slapi_pblock_get( pCurrentPB, functype, &FuncPtr );
259 if ( rc == LDAP_SUCCESS ) {
260 if ( FuncPtr != NULL ) {
261 *pTmpFuncPtr = FuncPtr;
262 pTmpFuncPtr++;
263 }
264 rc = slapi_pblock_get( pCurrentPB,
265 SLAPI_IBM_PBLOCK, &pCurrentPB );
266 }
267 }
268
269 *pTmpFuncPtr = NULL;
270
271
272 done:
273 if ( rc != LDAP_SUCCESS && *ppFuncPtrs != NULL ) {
274 ch_free( *ppFuncPtrs );
275 *ppFuncPtrs = NULL;
276 }
277
278 return rc;
279 }
280
281 /*********************************************************************
282 * Function Name: createExtendedOp
283 *
284 * Description: Creates an extended operation structure and
285 * initializes the fields
286 *
287 * Return value: A newly allocated structure or NULL
288 ********************************************************************/
289 ExtendedOp *
createExtendedOp()290 createExtendedOp()
291 {
292 ExtendedOp *ret;
293
294 ret = (ExtendedOp *)slapi_ch_malloc(sizeof(ExtendedOp));
295 ret->ext_oid.bv_val = NULL;
296 ret->ext_oid.bv_len = 0;
297 ret->ext_func = NULL;
298 ret->ext_be = NULL;
299 ret->ext_next = NULL;
300
301 return ret;
302 }
303
304
305 /*********************************************************************
306 * Function Name: slapi_int_unregister_extop
307 *
308 * Description: This routine removes the ExtendedOp structures
309 * asscoiated with a particular extended operation
310 * plugin.
311 *
312 * Input: pBE - pointer to a backend structure
313 * opList - pointer to a linked list of extended
314 * operation structures
315 * pPB - pointer to a slapi parameter block
316 *
317 * Output:
318 *
319 * Return Value: none
320 *
321 * Messages: None
322 *********************************************************************/
323 void
slapi_int_unregister_extop(Backend * pBE,ExtendedOp ** opList,Slapi_PBlock * pPB)324 slapi_int_unregister_extop(
325 Backend *pBE,
326 ExtendedOp **opList,
327 Slapi_PBlock *pPB )
328 {
329 ExtendedOp *pTmpExtOp, *backExtOp;
330 char **pTmpOIDs;
331 int i;
332
333 #if 0
334 assert( pBE != NULL); /* unused */
335 #endif /* 0 */
336 assert( opList != NULL );
337 assert( pPB != NULL );
338
339 if ( *opList == NULL ) {
340 return;
341 }
342
343 slapi_pblock_get( pPB, SLAPI_PLUGIN_EXT_OP_OIDLIST, &pTmpOIDs );
344 if ( pTmpOIDs == NULL ) {
345 return;
346 }
347
348 for ( i = 0; pTmpOIDs[i] != NULL; i++ ) {
349 backExtOp = NULL;
350 pTmpExtOp = *opList;
351 for ( ; pTmpExtOp != NULL; pTmpExtOp = pTmpExtOp->ext_next) {
352 int rc;
353 rc = strcasecmp( pTmpExtOp->ext_oid.bv_val,
354 pTmpOIDs[ i ] );
355 if ( rc == 0 ) {
356 if ( backExtOp == NULL ) {
357 *opList = pTmpExtOp->ext_next;
358 } else {
359 backExtOp->ext_next
360 = pTmpExtOp->ext_next;
361 }
362
363 ch_free( pTmpExtOp );
364 break;
365 }
366 backExtOp = pTmpExtOp;
367 }
368 }
369 }
370
371
372 /*********************************************************************
373 * Function Name: slapi_int_register_extop
374 *
375 * Description: This routine creates a new ExtendedOp structure, loads
376 * in the extended op module and put the extended op function address
377 * in the structure. The function will not be executed in
378 * this routine.
379 *
380 * Input: pBE - pointer to a backend structure
381 * opList - pointer to a linked list of extended
382 * operation structures
383 * pPB - pointer to a slapi parameter block
384 *
385 * Output:
386 *
387 * Return Value: an LDAP return code
388 *
389 * Messages: None
390 *********************************************************************/
391 int
slapi_int_register_extop(Backend * pBE,ExtendedOp ** opList,Slapi_PBlock * pPB)392 slapi_int_register_extop(
393 Backend *pBE,
394 ExtendedOp **opList,
395 Slapi_PBlock *pPB )
396 {
397 ExtendedOp *pTmpExtOp = NULL;
398 SLAPI_FUNC tmpFunc;
399 char **pTmpOIDs;
400 int rc = LDAP_OTHER;
401 int i;
402
403 if ( (*opList) == NULL ) {
404 *opList = createExtendedOp();
405 if ( (*opList) == NULL ) {
406 rc = LDAP_NO_MEMORY;
407 goto error_return;
408 }
409 pTmpExtOp = *opList;
410
411 } else { /* Find the end of the list */
412 for ( pTmpExtOp = *opList; pTmpExtOp->ext_next != NULL;
413 pTmpExtOp = pTmpExtOp->ext_next )
414 ; /* EMPTY */
415 pTmpExtOp->ext_next = createExtendedOp();
416 if ( pTmpExtOp->ext_next == NULL ) {
417 rc = LDAP_NO_MEMORY;
418 goto error_return;
419 }
420 pTmpExtOp = pTmpExtOp->ext_next;
421 }
422
423 rc = slapi_pblock_get( pPB,SLAPI_PLUGIN_EXT_OP_OIDLIST, &pTmpOIDs );
424 if ( rc != 0 ) {
425 rc = LDAP_OTHER;
426 goto error_return;
427 }
428
429 rc = slapi_pblock_get(pPB,SLAPI_PLUGIN_EXT_OP_FN, &tmpFunc);
430 if ( rc != 0 ) {
431 rc = LDAP_OTHER;
432 goto error_return;
433 }
434
435 if ( (pTmpOIDs == NULL) || (tmpFunc == NULL) ) {
436 rc = LDAP_OTHER;
437 goto error_return;
438 }
439
440 for ( i = 0; pTmpOIDs[i] != NULL; i++ ) {
441 pTmpExtOp->ext_oid.bv_val = pTmpOIDs[i];
442 pTmpExtOp->ext_oid.bv_len = strlen( pTmpOIDs[i] );
443 pTmpExtOp->ext_func = tmpFunc;
444 pTmpExtOp->ext_be = pBE;
445 if ( pTmpOIDs[i + 1] != NULL ) {
446 pTmpExtOp->ext_next = createExtendedOp();
447 if ( pTmpExtOp->ext_next == NULL ) {
448 rc = LDAP_NO_MEMORY;
449 break;
450 }
451 pTmpExtOp = pTmpExtOp->ext_next;
452 }
453 }
454
455 error_return:
456 return rc;
457 }
458
459 /*********************************************************************
460 * Function Name: slapi_int_get_extop_plugin
461 *
462 * Description: This routine gets the function address for a given function
463 * name.
464 *
465 * Input:
466 * funcName - name of the extended op function, ie. an OID.
467 *
468 * Output: pFuncAddr - the function address of the requested function name.
469 *
470 * Return Values: a pointer to a newly created ExtendOp structure or
471 * NULL - function failed
472 *
473 * Messages: None
474 *********************************************************************/
475 int
slapi_int_get_extop_plugin(struct berval * reqoid,SLAPI_FUNC * pFuncAddr)476 slapi_int_get_extop_plugin(
477 struct berval *reqoid,
478 SLAPI_FUNC *pFuncAddr )
479 {
480 ExtendedOp *pTmpExtOp;
481
482 assert( reqoid != NULL );
483 assert( pFuncAddr != NULL );
484
485 *pFuncAddr = NULL;
486
487 if ( pGExtendedOps == NULL ) {
488 return LDAP_OTHER;
489 }
490
491 pTmpExtOp = pGExtendedOps;
492 while ( pTmpExtOp != NULL ) {
493 int rc;
494
495 rc = strcasecmp( reqoid->bv_val, pTmpExtOp->ext_oid.bv_val );
496 if ( rc == 0 ) {
497 *pFuncAddr = pTmpExtOp->ext_func;
498 break;
499 }
500 pTmpExtOp = pTmpExtOp->ext_next;
501 }
502
503 return ( *pFuncAddr == NULL ? 1 : 0 );
504 }
505
506 /***************************************************************************
507 * This function is similar to slapi_int_get_extop_plugin above. except it returns one OID
508 * per call. It is called from root_dse_info (root_dse.c).
509 * The function is a modified version of get_supported_extop (file extended.c).
510 ***************************************************************************/
511 struct berval *
slapi_int_get_supported_extop(int index)512 slapi_int_get_supported_extop( int index )
513 {
514 ExtendedOp *ext;
515
516 for ( ext = pGExtendedOps ; ext != NULL && --index >= 0;
517 ext = ext->ext_next) {
518 ; /* empty */
519 }
520
521 if ( ext == NULL ) {
522 return NULL;
523 }
524
525 return &ext->ext_oid ;
526 }
527
528 /*********************************************************************
529 * Function Name: slapi_int_load_plugin
530 *
531 * Description: This routine loads the specified DLL, gets and executes the init function
532 * if requested.
533 *
534 * Input:
535 * pPlugin - a pointer to a Slapi_PBlock struct which will be passed to
536 * the DLL init function.
537 * path - path name of the DLL to be load.
538 * initfunc - either the DLL initialization function or an OID of the
539 * loaded extended operation.
540 * doInit - if it is TRUE, execute the init function, otherwise, save the
541 * function address but not execute it.
542 *
543 * Output: pInitFunc - the function address of the loaded function. This param
544 * should be not be null if doInit is FALSE.
545 * pLdHandle - handle returned by lt_dlopen()
546 *
547 * Return Values: LDAP_SUCCESS, LDAP_LOCAL_ERROR
548 *
549 * Messages: None
550 *********************************************************************/
551
552 static int
slapi_int_load_plugin(Slapi_PBlock * pPlugin,const char * path,const char * initfunc,int doInit,SLAPI_FUNC * pInitFunc,lt_dlhandle * pLdHandle)553 slapi_int_load_plugin(
554 Slapi_PBlock *pPlugin,
555 const char *path,
556 const char *initfunc,
557 int doInit,
558 SLAPI_FUNC *pInitFunc,
559 lt_dlhandle *pLdHandle )
560 {
561 int rc = LDAP_SUCCESS;
562 SLAPI_FUNC fpInitFunc = NULL;
563
564 assert( pLdHandle != NULL );
565
566 if ( lt_dlinit() ) {
567 return LDAP_LOCAL_ERROR;
568 }
569
570 /* load in the module */
571 *pLdHandle = lt_dlopen( path );
572 if ( *pLdHandle == NULL ) {
573 fprintf( stderr, "failed to load plugin %s: %s\n",
574 path, lt_dlerror() );
575 return LDAP_LOCAL_ERROR;
576 }
577
578 fpInitFunc = (SLAPI_FUNC)lt_dlsym( *pLdHandle, initfunc );
579 if ( fpInitFunc == NULL ) {
580 fprintf( stderr, "failed to find symbol %s in plugin %s: %s\n",
581 initfunc, path, lt_dlerror() );
582 lt_dlclose( *pLdHandle );
583 return LDAP_LOCAL_ERROR;
584 }
585
586 if ( doInit ) {
587 rc = ( *fpInitFunc )( pPlugin );
588 if ( rc != LDAP_SUCCESS ) {
589 lt_dlclose( *pLdHandle );
590 }
591
592 } else {
593 *pInitFunc = fpInitFunc;
594 }
595
596 return rc;
597 }
598
599 /*
600 * Special support for computed attribute plugins
601 */
602 int
slapi_int_call_plugins(Backend * be,int funcType,Slapi_PBlock * pPB)603 slapi_int_call_plugins(
604 Backend *be,
605 int funcType,
606 Slapi_PBlock *pPB )
607 {
608
609 int rc = 0;
610 SLAPI_FUNC *pGetPlugin = NULL, *tmpPlugin = NULL;
611
612 if ( pPB == NULL ) {
613 return 1;
614 }
615
616 rc = slapi_int_get_plugins( be, funcType, &tmpPlugin );
617 if ( rc != LDAP_SUCCESS || tmpPlugin == NULL ) {
618 /* Nothing to do, front-end should ignore. */
619 return rc;
620 }
621
622 for ( pGetPlugin = tmpPlugin ; *pGetPlugin != NULL; pGetPlugin++ ) {
623 rc = (*pGetPlugin)(pPB);
624
625 /*
626 * Only non-postoperation plugins abort processing on
627 * failure (confirmed with SLAPI specification).
628 */
629 if ( !SLAPI_PLUGIN_IS_POST_FN( funcType ) && rc != 0 ) {
630 /*
631 * Plugins generally return negative error codes
632 * to indicate failure, although in the case of
633 * bind plugins they may return SLAPI_BIND_xxx
634 */
635 break;
636 }
637 }
638
639 slapi_ch_free( (void **)&tmpPlugin );
640
641 return rc;
642 }
643
644 int
slapi_int_read_config(Backend * be,const char * fname,int lineno,int argc,char ** argv,int index)645 slapi_int_read_config(
646 Backend *be,
647 const char *fname,
648 int lineno,
649 int argc,
650 char **argv,
651 int index )
652 {
653 int iType = -1;
654 int numPluginArgc = 0;
655
656 if ( argc < 4 ) {
657 fprintf( stderr,
658 "%s: line %d: missing arguments "
659 "in \"plugin <plugin_type> <lib_path> "
660 "<init_function> [<arguments>]\" line\n",
661 fname, lineno );
662 return 1;
663 }
664
665 /* automatically instantiate overlay if necessary */
666 if ( !slapi_over_is_inst( be ) ) {
667 ConfigReply cr = { 0 };
668 if ( slapi_over_config( be, &cr ) != 0 ) {
669 fprintf( stderr, "Failed to instantiate SLAPI overlay: "
670 "err=%d msg=\"%s\"\n", cr.err, cr.msg );
671 return -1;
672 }
673 }
674
675 if ( strcasecmp( argv[1], "preoperation" ) == 0 ) {
676 iType = SLAPI_PLUGIN_PREOPERATION;
677 } else if ( strcasecmp( argv[1], "postoperation" ) == 0 ) {
678 iType = SLAPI_PLUGIN_POSTOPERATION;
679 } else if ( strcasecmp( argv[1], "extendedop" ) == 0 ) {
680 iType = SLAPI_PLUGIN_EXTENDEDOP;
681 } else if ( strcasecmp( argv[1], "object" ) == 0 ) {
682 iType = SLAPI_PLUGIN_OBJECT;
683 } else {
684 fprintf( stderr, "%s: line %d: invalid plugin type \"%s\".\n",
685 fname, lineno, argv[1] );
686 return 1;
687 }
688
689 numPluginArgc = argc - 4;
690
691 if ( iType == SLAPI_PLUGIN_PREOPERATION ||
692 iType == SLAPI_PLUGIN_EXTENDEDOP ||
693 iType == SLAPI_PLUGIN_POSTOPERATION ||
694 iType == SLAPI_PLUGIN_OBJECT ) {
695 int rc;
696 Slapi_PBlock *pPlugin;
697
698 pPlugin = plugin_pblock_new( iType, numPluginArgc, argv );
699 if (pPlugin == NULL) {
700 return 1;
701 }
702
703 if (iType == SLAPI_PLUGIN_EXTENDEDOP) {
704 rc = slapi_int_register_extop(be, &pGExtendedOps, pPlugin);
705 if ( rc != LDAP_SUCCESS ) {
706 slapi_pblock_destroy( pPlugin );
707 return 1;
708 }
709 }
710
711 rc = slapi_int_register_plugin_index( be, pPlugin, index );
712 if ( rc != LDAP_SUCCESS ) {
713 if ( iType == SLAPI_PLUGIN_EXTENDEDOP ) {
714 slapi_int_unregister_extop( be, &pGExtendedOps, pPlugin );
715 }
716 slapi_pblock_destroy( pPlugin );
717 return 1;
718 }
719 }
720
721 return 0;
722 }
723
724 int
slapi_int_unregister_plugin(Backend * be,Slapi_PBlock * pPlugin,Slapi_PBlock * pPrev)725 slapi_int_unregister_plugin(
726 Backend *be,
727 Slapi_PBlock *pPlugin,
728 Slapi_PBlock *pPrev
729 )
730 {
731 int type;
732
733 assert( pPlugin != NULL );
734
735 slapi_pblock_get( pPlugin, SLAPI_PLUGIN_TYPE, (void *)&type );
736 if ( type == SLAPI_PLUGIN_EXTENDEDOP ) {
737 slapi_int_unregister_extop( be, &pGExtendedOps, pPlugin );
738 }
739
740 if ( pPrev != NULL ) {
741 Slapi_PBlock *pNext = NULL;
742
743 slapi_pblock_get( pPlugin, SLAPI_IBM_PBLOCK, &pNext );
744 slapi_pblock_set( pPrev, SLAPI_IBM_PBLOCK, &pNext );
745 }
746 slapi_pblock_destroy( pPlugin );
747
748 return LDAP_SUCCESS;
749 }
750
751 int
slapi_int_unregister_plugins(Backend * be,int index)752 slapi_int_unregister_plugins(
753 Backend *be,
754 int index
755 )
756 {
757 Slapi_PBlock *pTmpPB = NULL;
758 Slapi_PBlock *pSavePB = NULL;
759 int rc = LDAP_SUCCESS;
760
761 pTmpPB = SLAPI_BACKEND_PBLOCK( be );
762 if ( pTmpPB == NULL ) {
763 return ( index < 0 ) ? LDAP_SUCCESS : LDAP_OTHER;
764 }
765
766 if ( index < 0 ) {
767 /* All plugins must go */
768 while ( pTmpPB != NULL && rc == LDAP_SUCCESS ) {
769 pSavePB = pTmpPB;
770 rc = slapi_pblock_get( pTmpPB, SLAPI_IBM_PBLOCK, &pTmpPB );
771 if ( pSavePB != NULL ) {
772 slapi_int_unregister_plugin( be, pSavePB, NULL );
773 }
774 }
775 } else if ( index == 0 ) {
776 slapi_pblock_get( pTmpPB, SLAPI_IBM_PBLOCK, &pSavePB );
777 SLAPI_BACKEND_PBLOCK( be ) = pSavePB;
778 slapi_int_unregister_plugin( be, pTmpPB, NULL );
779 } else {
780 int pos = -1;
781 while ( pTmpPB != NULL && rc == LDAP_SUCCESS && ++pos < index ) {
782 pSavePB = pTmpPB;
783 rc = slapi_pblock_get( pTmpPB, SLAPI_IBM_PBLOCK, &pTmpPB );
784 }
785 if ( pos == index ) {
786 slapi_int_unregister_plugin( be, pTmpPB, pSavePB );
787 }
788 }
789 return rc;
790 }
791
792 void
slapi_int_plugin_unparse(Backend * be,BerVarray * out)793 slapi_int_plugin_unparse(
794 Backend *be,
795 BerVarray *out
796 )
797 {
798 Slapi_PBlock *pp;
799 int i, j;
800 char **argv, ibuf[32], *ptr;
801 struct berval idx, bv;
802
803 *out = NULL;
804 idx.bv_val = ibuf;
805 i = 0;
806
807 for ( pp = SLAPI_BACKEND_PBLOCK( be );
808 pp != NULL;
809 slapi_pblock_get( pp, SLAPI_IBM_PBLOCK, &pp ) )
810 {
811 slapi_pblock_get( pp, SLAPI_X_CONFIG_ARGV, &argv );
812 if ( argv == NULL ) /* could be dynamic plugin */
813 continue;
814 idx.bv_len = snprintf( idx.bv_val, sizeof( ibuf ), "{%d}", i );
815 if ( idx.bv_len >= sizeof( ibuf ) ) {
816 /* FIXME: just truncating by now */
817 idx.bv_len = sizeof( ibuf ) - 1;
818 }
819 bv.bv_len = idx.bv_len;
820 for (j=1; argv[j]; j++) {
821 bv.bv_len += strlen(argv[j]);
822 if ( j ) bv.bv_len++;
823 }
824 bv.bv_val = ch_malloc( bv.bv_len + 1 );
825 ptr = lutil_strcopy( bv.bv_val, ibuf );
826 for (j=1; argv[j]; j++) {
827 if ( j ) *ptr++ = ' ';
828 ptr = lutil_strcopy( ptr, argv[j] );
829 }
830 ber_bvarray_add( out, &bv );
831 }
832 }
833 #endif /* HAVE_LTDL_H */
834