]> git.sur5r.net Git - openldap/blob - servers/slapd/slapi/slapi_pblock.c
Add SLAPI_X_GROUP_TARGET_ENTRY so that group plugin can use target entry
[openldap] / servers / slapd / slapi / slapi_pblock.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 2002-2004 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 #include <slap.h>
25 #include <slapi.h>
26
27 static int 
28 isOkNetscapeParam( int param ) 
29 {
30         switch ( param ) {
31         case SLAPI_BACKEND:
32         case SLAPI_CONNECTION:
33         case SLAPI_OPERATION:
34         case SLAPI_OPERATION_PARAMETERS:
35         case SLAPI_OPERATION_TYPE:
36         case SLAPI_OPERATION_ID:
37         case SLAPI_OPERATION_AUTHTYPE:
38         case SLAPI_REQUESTOR_ISROOT:
39         case SLAPI_BE_MONITORDN:
40         case SLAPI_BE_TYPE:
41         case SLAPI_BE_READONLY:
42         case SLAPI_BE_LASTMOD:
43         case SLAPI_CONN_ID:
44         case SLAPI_OPINITIATED_TIME:
45         case SLAPI_REQUESTOR_DN:
46         case SLAPI_REQUESTOR_ISUPDATEDN:
47         case SLAPI_CONN_DN:
48         case SLAPI_CONN_CLIENTIP:
49         case SLAPI_CONN_SERVERIP:
50         case SLAPI_CONN_AUTHTYPE:
51         case SLAPI_CONN_AUTHMETHOD:
52         case SLAPI_CONN_CERT:
53         case SLAPI_X_CONN_IS_UDP:
54         case SLAPI_X_CONN_CLIENTPATH:
55         case SLAPI_X_CONN_SERVERPATH:
56         case SLAPI_X_CONN_SSF:
57         case SLAPI_X_CONN_SASL_CONTEXT:
58         case SLAPI_IBM_CONN_DN_ALT:
59         case SLAPI_IBM_CONN_DN_ORIG:
60         case SLAPI_IBM_GSSAPI_CONTEXT:
61         case SLAPI_PLUGIN:
62         case SLAPI_PLUGIN_PRIVATE:
63         case SLAPI_PLUGIN_TYPE:
64         case SLAPI_PLUGIN_ARGV:
65         case SLAPI_PLUGIN_ARGC:
66         case SLAPI_PLUGIN_VERSION:
67         case SLAPI_PLUGIN_OPRETURN:
68         case SLAPI_PLUGIN_OBJECT:
69         case SLAPI_PLUGIN_DESTROY_FN:
70         case SLAPI_PLUGIN_DESCRIPTION:
71         case SLAPI_PLUGIN_INTOP_RESULT:
72         case SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES:
73         case SLAPI_PLUGIN_INTOP_SEARCH_REFERRALS:
74         case SLAPI_PLUGIN_DB_BIND_FN:
75         case SLAPI_PLUGIN_DB_UNBIND_FN:
76         case SLAPI_PLUGIN_DB_SEARCH_FN:
77         case SLAPI_PLUGIN_DB_COMPARE_FN:
78         case SLAPI_PLUGIN_DB_MODIFY_FN:
79         case SLAPI_PLUGIN_DB_MODRDN_FN:
80         case SLAPI_PLUGIN_DB_ADD_FN:
81         case SLAPI_PLUGIN_DB_DELETE_FN:
82         case SLAPI_PLUGIN_DB_ABANDON_FN:
83         case SLAPI_PLUGIN_DB_CONFIG_FN:
84         case SLAPI_PLUGIN_CLOSE_FN:
85         case SLAPI_PLUGIN_DB_FLUSH_FN:
86         case SLAPI_PLUGIN_START_FN:
87         case SLAPI_PLUGIN_DB_SEQ_FN:
88         case SLAPI_PLUGIN_DB_ENTRY_FN:
89         case SLAPI_PLUGIN_DB_REFERRAL_FN:
90         case SLAPI_PLUGIN_DB_RESULT_FN:
91         case SLAPI_PLUGIN_DB_LDIF2DB_FN:
92         case SLAPI_PLUGIN_DB_DB2LDIF_FN:
93         case SLAPI_PLUGIN_DB_BEGIN_FN:
94         case SLAPI_PLUGIN_DB_COMMIT_FN:
95         case SLAPI_PLUGIN_DB_ABORT_FN:
96         case SLAPI_PLUGIN_DB_ARCHIVE2DB_FN:
97         case SLAPI_PLUGIN_DB_DB2ARCHIVE_FN:
98         case SLAPI_PLUGIN_DB_NEXT_SEARCH_ENTRY_FN:
99         case SLAPI_PLUGIN_DB_FREE_RESULT_SET_FN:
100         case SLAPI_PLUGIN_DB_SIZE_FN:
101         case SLAPI_PLUGIN_DB_TEST_FN:
102         case SLAPI_PLUGIN_DB_NO_ACL:
103         case SLAPI_PLUGIN_EXT_OP_FN:
104         case SLAPI_PLUGIN_EXT_OP_OIDLIST:
105         case SLAPI_PLUGIN_PRE_BIND_FN:
106         case SLAPI_PLUGIN_PRE_UNBIND_FN:
107         case SLAPI_PLUGIN_PRE_SEARCH_FN:
108         case SLAPI_PLUGIN_PRE_COMPARE_FN:
109         case SLAPI_PLUGIN_PRE_MODIFY_FN:
110         case SLAPI_PLUGIN_PRE_MODRDN_FN:
111         case SLAPI_PLUGIN_PRE_ADD_FN:
112         case SLAPI_PLUGIN_PRE_DELETE_FN:
113         case SLAPI_PLUGIN_PRE_ABANDON_FN:
114         case SLAPI_PLUGIN_PRE_ENTRY_FN:
115         case SLAPI_PLUGIN_PRE_REFERRAL_FN:
116         case SLAPI_PLUGIN_PRE_RESULT_FN:
117         case SLAPI_PLUGIN_POST_BIND_FN:
118         case SLAPI_PLUGIN_POST_UNBIND_FN:
119         case SLAPI_PLUGIN_POST_SEARCH_FN:
120         case SLAPI_PLUGIN_POST_COMPARE_FN:
121         case SLAPI_PLUGIN_POST_MODIFY_FN:
122         case SLAPI_PLUGIN_POST_MODRDN_FN:
123         case SLAPI_PLUGIN_POST_ADD_FN:
124         case SLAPI_PLUGIN_POST_DELETE_FN:
125         case SLAPI_PLUGIN_POST_ABANDON_FN:
126         case SLAPI_PLUGIN_POST_ENTRY_FN:
127         case SLAPI_PLUGIN_POST_REFERRAL_FN:
128         case SLAPI_PLUGIN_POST_RESULT_FN:
129         case SLAPI_PLUGIN_MR_FILTER_CREATE_FN:
130         case SLAPI_PLUGIN_MR_INDEXER_CREATE_FN:
131         case SLAPI_PLUGIN_MR_FILTER_MATCH_FN:
132         case SLAPI_PLUGIN_MR_FILTER_INDEX_FN:
133         case SLAPI_PLUGIN_MR_FILTER_RESET_FN:
134         case SLAPI_PLUGIN_MR_INDEX_FN:
135         case SLAPI_PLUGIN_MR_OID:
136         case SLAPI_PLUGIN_MR_TYPE:
137         case SLAPI_PLUGIN_MR_VALUE:
138         case SLAPI_PLUGIN_MR_VALUES:
139         case SLAPI_PLUGIN_MR_KEYS:
140         case SLAPI_PLUGIN_MR_FILTER_REUSABLE:
141         case SLAPI_PLUGIN_MR_QUERY_OPERATOR:
142         case SLAPI_PLUGIN_MR_USAGE:
143         case SLAPI_OP_LESS:
144         case SLAPI_OP_LESS_OR_EQUAL:
145         case SLAPI_PLUGIN_MR_USAGE_INDEX:
146         case SLAPI_PLUGIN_SYNTAX_FILTER_AVA:
147         case SLAPI_PLUGIN_SYNTAX_FILTER_SUB:
148         case SLAPI_PLUGIN_SYNTAX_VALUES2KEYS:
149         case SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_AVA:
150         case SLAPI_PLUGIN_SYNTAX_ASSERTION2KEYS_SUB:
151         case SLAPI_PLUGIN_SYNTAX_NAMES:
152         case SLAPI_PLUGIN_SYNTAX_OID:
153         case SLAPI_PLUGIN_SYNTAX_FLAGS:
154         case SLAPI_PLUGIN_SYNTAX_COMPARE:
155         case SLAPI_MANAGEDSAIT:
156         case SLAPI_CONFIG_FILENAME:
157         case SLAPI_CONFIG_LINENO:
158         case SLAPI_CONFIG_ARGC:
159         case SLAPI_CONFIG_ARGV:
160         case SLAPI_TARGET_DN:
161         case SLAPI_REQCONTROLS:
162         case SLAPI_ENTRY_PRE_OP:
163         case SLAPI_ENTRY_POST_OP:
164         case SLAPI_RESCONTROLS:
165         case SLAPI_ADD_RESCONTROL:
166         case SLAPI_ADD_ENTRY:
167         case SLAPI_BIND_METHOD:
168         case SLAPI_BIND_CREDENTIALS:
169         case SLAPI_BIND_SASLMECHANISM:
170         case SLAPI_BIND_RET_SASLCREDS:
171         case SLAPI_COMPARE_TYPE:
172         case SLAPI_COMPARE_VALUE:
173         case SLAPI_MODIFY_MODS:
174         case SLAPI_MODRDN_NEWRDN:
175         case SLAPI_MODRDN_DELOLDRDN:
176         case SLAPI_MODRDN_NEWSUPERIOR:
177         case SLAPI_SEARCH_SCOPE:
178         case SLAPI_SEARCH_DEREF:
179         case SLAPI_SEARCH_SIZELIMIT:
180         case SLAPI_SEARCH_TIMELIMIT:
181         case SLAPI_SEARCH_FILTER:
182         case SLAPI_SEARCH_STRFILTER:
183         case SLAPI_SEARCH_ATTRS:
184         case SLAPI_SEARCH_ATTRSONLY:
185         case SLAPI_ABANDON_MSGID:
186         case SLAPI_SEQ_TYPE:
187         case SLAPI_SEQ_ATTRNAME:
188         case SLAPI_SEQ_VAL:
189         case SLAPI_EXT_OP_REQ_OID:
190         case SLAPI_EXT_OP_REQ_VALUE:
191         case SLAPI_EXT_OP_RET_OID:
192         case SLAPI_EXT_OP_RET_VALUE:
193         case SLAPI_MR_FILTER_ENTRY:
194         case SLAPI_MR_FILTER_TYPE:
195         case SLAPI_MR_FILTER_VALUE:
196         case SLAPI_MR_FILTER_OID:
197         case SLAPI_MR_FILTER_DNATTRS:
198         case SLAPI_LDIF2DB_FILE:
199         case SLAPI_LDIF2DB_REMOVEDUPVALS:
200         case SLAPI_DB2LDIF_PRINTKEY:
201         case SLAPI_PARENT_TXN:
202         case SLAPI_TXN:
203         case SLAPI_SEARCH_RESULT_SET:
204         case SLAPI_SEARCH_RESULT_ENTRY:
205         case SLAPI_NENTRIES:
206         case SLAPI_SEARCH_REFERRALS:
207         case SLAPI_CHANGENUMBER:
208         case SLAPI_LOG_OPERATION:
209         case SLAPI_DBSIZE:
210         case SLAPI_RESULT_CODE:
211         case SLAPI_RESULT_TEXT:
212         case SLAPI_RESULT_MATCHED:
213         case SLAPI_PLUGIN_COMPUTE_EVALUATOR_FN:
214         case SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN:
215         case SLAPI_PLUGIN_ACL_ALLOW_ACCESS:
216         case SLAPI_X_PLUGIN_PRE_GROUP_FN:
217         case SLAPI_X_PLUGIN_POST_GROUP_FN:
218         case SLAPI_X_GROUP_ENTRY:
219         case SLAPI_X_GROUP_ATTRIBUTE:
220         case SLAPI_X_GROUP_OPERATION_DN:
221         case SLAPI_X_GROUP_TARGET_ENTRY:
222                 return LDAP_SUCCESS;
223         default:
224                 return INVALID_PARAM;
225         }
226 }
227
228 static int
229 isValidParam( Slapi_PBlock *pb, int param ) 
230 {
231         if ( pb->ckParams == TRUE ) {
232                 if ( IBM_RESERVED( param ) ) return LDAP_SUCCESS;
233                 if (param == SLAPI_PLUGIN_AUDIT_FN ||
234                                 param == SLAPI_PLUGIN_AUDIT_DATA )
235                         return LDAP_SUCCESS;
236                 if ( param < LAST_IBM_PARAM ) {
237                         return INVALID_PARAM;
238                 } else if ( NETSCAPE_RESERVED( param ) ) {
239                         return INVALID_PARAM;
240                 } else {
241                         return isOkNetscapeParam(param);
242                 }
243         } else {
244                 return LDAP_SUCCESS;
245         }
246 }
247
248 static void
249 Lock( Slapi_PBlock *pb )
250 {
251         ldap_pvt_thread_mutex_lock(&pb->pblockMutex);
252 }
253
254 static void
255 unLock( Slapi_PBlock *pb )
256 {
257         ldap_pvt_thread_mutex_unlock(&pb->pblockMutex);
258 }
259
260 static int 
261 get( Slapi_PBlock *pb, int param, void **val ) 
262 {       
263         int i;
264
265         if ( isValidParam( pb, param ) == INVALID_PARAM ) {
266                 return PBLOCK_ERROR;
267         }
268         
269         Lock( pb );
270         
271         *val = NULL;
272         for ( i = 0; i < pb->numParams; i++ ) {
273                 if ( pb->curParams[i] == param ) {
274                         *val = pb->curVals[i];
275                         break;
276                 }
277         }
278         unLock( pb );   
279         return LDAP_SUCCESS;
280 }
281
282 static int 
283 set( Slapi_PBlock *pb, int param, void *val ) 
284 {
285 #if defined(LDAP_SLAPI)
286         int i, freeit;
287         int addcon = 0;
288
289         if ( isValidParam( pb, param ) == INVALID_PARAM ) {
290                 return PBLOCK_ERROR;
291         }
292
293         Lock( pb );     
294
295         if ( pb->numParams == PBLOCK_MAX_PARAMS ) {
296                 unLock( pb );
297                 return PBLOCK_ERROR; 
298         }
299
300         if ( param == SLAPI_ADD_RESCONTROL ) {
301                 addcon = 1;
302                 param = SLAPI_RES_CONTROLS;
303         }
304
305         switch ( param ) {
306         case SLAPI_CONN_DN:
307         case SLAPI_CONN_AUTHMETHOD:
308         case SLAPI_IBM_CONN_DN_ALT:
309         case SLAPI_IBM_CONN_DN_ORIG:
310         case SLAPI_RESULT_TEXT:
311         case SLAPI_RESULT_MATCHED:
312                 freeit = 1; break;
313         default:
314                 freeit = 0; break;
315         }
316         for( i = 0; i < pb->numParams; i++ ) { 
317                 if ( pb->curParams[i] == param ) {
318                         break;
319                 }
320         }
321
322         if ( i >= pb->numParams ) {
323                 pb->curParams[i] = param;
324                 pb->numParams++;
325         }
326         if ( addcon ) {
327                 LDAPControl **ctrls = pb->curVals[i];
328                 int j;
329
330                 if ( ctrls ) {
331                         for (j=0; ctrls[j]; j++);
332                         ctrls = ch_realloc( ctrls, (j+2)*sizeof(LDAPControl *) );
333                 } else {
334                         ctrls = ch_malloc( 2 * sizeof(LDAPControl *) );
335                         j = 0;
336                 }
337                 ctrls[j] = val;
338                 ctrls[j+1] = NULL;
339                 pb->curVals[i] = ctrls;
340         } else {
341                 if ( freeit ) ch_free( pb->curVals[i] );
342                 pb->curVals[i] = val;
343         }
344
345         unLock( pb );   
346         return LDAP_SUCCESS;
347 #endif /* LDAP_SLAPI */
348         return PBLOCK_ERROR;
349 }
350
351 static void
352 clearPB( Slapi_PBlock *pb ) 
353 {
354         pb->numParams = 1;
355 }
356
357 static void
358 checkParams( Slapi_PBlock *pb, int flag ) 
359 {
360         pb->ckParams = flag;
361 }
362
363 static int
364 deleteParam( Slapi_PBlock *p, int param ) 
365 {
366         int i;
367
368         Lock(p);
369         for ( i = 0; i < p->numParams; i++ ) { 
370                 if ( p->curParams[i] == param ) {
371                         break;
372                 }
373         }
374     
375         if (i >= p->numParams ) {
376                 unLock( p );
377                 return PBLOCK_ERROR;
378         }
379         if ( p->numParams > 1 ) {
380                 p->curParams[i] = p->curParams[p->numParams];
381                 p->curVals[i] = p->curVals[p->numParams];
382         }
383         p->numParams--;
384         unLock( p );    
385         return LDAP_SUCCESS;
386 }
387
388 Slapi_PBlock *
389 slapi_pblock_new() 
390 {
391 #if defined(LDAP_SLAPI)
392         Slapi_PBlock *pb;
393
394         pb = (Slapi_PBlock *) ch_malloc(sizeof(Slapi_PBlock));
395         if ( pb != NULL ) {
396                 pb->ckParams = TRUE;
397                 ldap_pvt_thread_mutex_init( &pb->pblockMutex );
398                 memset( pb->curParams, 0, sizeof(pb->curParams) );
399                 memset( pb->curVals, 0, sizeof(pb->curVals) );
400                 pb->curParams[0] = SLAPI_IBM_PBLOCK;
401                 pb->curVals[0] = NULL;
402                 pb->numParams = 1;
403         }
404         return pb;
405 #endif /* LDAP_SLAPI */
406         return NULL;
407 }
408
409 void 
410 slapi_pblock_destroy( Slapi_PBlock* pb ) 
411 {
412 #if defined(LDAP_SLAPI)
413         char *str = NULL;
414         LDAPControl **rescontrols = NULL;
415
416         get( pb, SLAPI_CONN_DN,(void **)&str );
417         if ( str != NULL ) {
418                 ch_free( str );
419                 str = NULL;
420         }
421
422         get( pb, SLAPI_CONN_AUTHMETHOD, (void **)&str );
423         if ( str != NULL ) {
424                 ch_free( str );
425                 str = NULL;
426         }
427
428         get( pb, SLAPI_IBM_CONN_DN_ALT, (void **)&str );
429         if ( str != NULL ) {
430                 ch_free( str );
431                 str = NULL;
432         }
433
434         get( pb, SLAPI_IBM_CONN_DN_ORIG, (void **)&str );
435         if ( str != NULL ) {
436                 ch_free( str );
437         }
438
439         get( pb, SLAPI_RESULT_TEXT, (void **)&str );
440         if ( str != NULL ) {
441                 ch_free( str );
442                 str = NULL;
443         }
444
445         get( pb, SLAPI_RESULT_MATCHED, (void **)&str );
446         if ( str != NULL ) {
447                 ch_free( str );
448                 str = NULL;
449         }
450
451         get( pb, SLAPI_RESCONTROLS, (void **)&rescontrols );
452         if ( rescontrols != NULL ) {
453                 ldap_controls_free( rescontrols );
454                 rescontrols = NULL;
455         }
456
457         ldap_pvt_thread_mutex_destroy( &pb->pblockMutex );
458
459         ch_free( pb ); 
460 #endif /* LDAP_SLAPI */
461 }
462
463 int 
464 slapi_pblock_get( Slapi_PBlock *pb, int arg, void *value ) 
465 {
466 #if defined(LDAP_SLAPI)
467         return get( pb, arg, (void **)value );
468 #endif /* LDAP_SLAPI */
469         return PBLOCK_ERROR;
470 }
471
472 int 
473 slapi_pblock_set( Slapi_PBlock *pb, int arg, void *value ) 
474 {
475 #if defined(LDAP_SLAPI)
476         void *pTmp = NULL;
477
478         switch ( arg ) {
479         case SLAPI_CONN_DN:
480         case SLAPI_CONN_AUTHMETHOD:
481         case SLAPI_IBM_CONN_DN_ALT:
482         case SLAPI_IBM_CONN_DN_ORIG:
483         case SLAPI_RESULT_TEXT:
484         case SLAPI_RESULT_MATCHED:
485                 if ( value != NULL ) {
486                         pTmp = (void *)slapi_ch_strdup((char *)value);
487                         if ( pTmp == NULL ) {
488                                 return LDAP_NO_MEMORY;
489                         }
490                 }
491                 break;
492         default:
493                 pTmp = value;
494                 break;
495         }
496         return set( pb, arg, pTmp );
497 #endif /* LDAP_SLAPI */
498         return LDAP_NO_MEMORY;
499 }
500
501 void
502 slapi_pblock_clear( Slapi_PBlock *pb ) 
503 {
504 #if defined(LDAP_SLAPI)
505    clearPB( pb );
506 #endif /* LDAP_SLAPI */
507 }
508
509 int 
510 slapi_pblock_delete_param( Slapi_PBlock *p, int param ) 
511 {
512 #if defined(LDAP_SLAPI)
513         return deleteParam( p, param );
514 #endif /* LDAP_SLAPI */
515         return PBLOCK_ERROR;
516 }
517
518 void
519 slapi_pblock_check_params( Slapi_PBlock *pb, int flag ) 
520 {
521 #if defined(LDAP_SLAPI)
522         checkParams( pb, flag );
523 #endif /* LDAP_SLAPI */
524 }
525
526 /*
527  * OpenLDAP extension
528  */
529 int
530 slapi_int_pblock_get_first( Backend *be, Slapi_PBlock **pb )
531 {
532 #if defined(LDAP_SLAPI)
533         assert( pb );
534         *pb = (Slapi_PBlock *)be->be_pb;
535         return (*pb == NULL ? LDAP_OTHER : LDAP_SUCCESS);
536 #else /* LDAP_SLAPI */
537         return LDAP_OTHER;
538 #endif /* LDAP_SLAPI */
539 }
540
541 /*
542  * OpenLDAP extension
543  */
544 int
545 slapi_int_pblock_get_next( Slapi_PBlock **pb )
546 {
547 #if defined(LDAP_SLAPI)
548         assert( pb );
549         return slapi_pblock_get( *pb, SLAPI_IBM_PBLOCK, pb );
550 #else /* LDAP_SLAPI */
551         return LDAP_OTHER;
552 #endif /* LDAP_SLAPI */
553 }
554