]> git.sur5r.net Git - openldap/blob - servers/slapd/overlays/allop.c
all-operational overlay: allows to configure part of te DIT so that requests
[openldap] / servers / slapd / overlays / allop.c
1 /* allop.c - returns all operational attributes when appropriate */
2 /* $OpenLDAP$ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4  *
5  * Copyright 2005 The OpenLDAP Foundation.
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 Pierangelo Masarati for inclusion in
18  * OpenLDAP Software.
19  */
20
21 /*
22  * The intended usage is as a global overlay for use with those clients
23  * that do not make use of the RFC3673 allOp ("+") in the requested 
24  * attribute list, but expect all operational attributes to be returned.
25  * Usage: add
26  *
27
28 overlay         allop
29 allop-URI       <ldapURI>
30
31  *
32  * if the allop-URI is not given, the rootDSE, i.e. "ldap:///??base",
33  * is assumed.
34  */
35
36 #include "portable.h"
37
38 #ifdef SLAPD_OVER_ALLOP
39
40 #include <stdio.h>
41 #include <ac/string.h>
42
43 #include "slap.h"
44
45 typedef struct allop_t {
46         struct berval   ao_ndn;
47         int             ao_scope;
48 } allop_t;
49
50 static int
51 allop_db_config(
52         BackendDB       *be,
53         const char      *fname,
54         int             lineno,
55         int             argc,
56         char            **argv )
57 {
58         slap_overinst   *on = (slap_overinst *)be->bd_info;
59         allop_t         *ao = (allop_t *)on->on_bi.bi_private;
60
61         if ( strcasecmp( argv[ 0 ], "allop-uri" ) == 0 ) {
62                 LDAPURLDesc     *lud;
63                 struct berval   dn,
64                                 ndn;
65                 int             scope,
66                                 rc = LDAP_SUCCESS;
67
68                 if ( argc != 2 ) {
69                         fprintf( stderr, "%s line %d: "
70                                 "need exactly 1 arg "
71                                 "in \"allop-uri <ldapURI>\" "
72                                 "directive.\n",
73                                 fname, lineno );
74                         return 1;
75                 }
76
77                 if ( ldap_url_parse( argv[ 1 ], &lud ) != LDAP_URL_SUCCESS ) {
78                         return -1;
79                 }
80
81                 scope = lud->lud_scope;
82                 if ( scope == LDAP_SCOPE_DEFAULT ) {
83                         scope = LDAP_SCOPE_BASE;
84                 }
85
86                 if ( lud->lud_dn == NULL || lud->lud_dn[ 0 ] == '\0' ) {
87                         if ( scope == LDAP_SCOPE_BASE ) {
88                                 BER_BVZERO( &ndn );
89
90                         } else {
91                                 ber_str2bv( "", 0, 1, &ndn );
92                         }
93
94                 } else {
95
96                         ber_str2bv( lud->lud_dn, 0, 0, &dn );
97                         rc = dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL );
98                 }
99
100                 ldap_free_urldesc( lud );
101                 if ( rc != LDAP_SUCCESS ) {
102                         return -1;
103                 }
104
105                 if ( BER_BVISNULL( &ndn ) ) {
106                         /* rootDSE */
107                         if ( ao != NULL ) {
108                                 ch_free( ao->ao_ndn.bv_val );
109                                 ch_free( ao );
110                                 on->on_bi.bi_private = NULL;
111                         }
112
113                 } else {
114                         if ( ao == NULL ) {
115                                 ao = ch_calloc( 1, sizeof( allop_t ) );
116                                 on->on_bi.bi_private = (void *)ao;
117
118                         } else {
119                                 ch_free( ao->ao_ndn.bv_val );
120                         }
121
122                         ao->ao_ndn = ndn;
123                         ao->ao_scope = scope;
124                 }
125
126         } else {
127                 return SLAP_CONF_UNKNOWN;
128         }
129
130         return 0;
131 }
132
133 static int
134 allop_db_destroy( BackendDB *be )
135 {
136         slap_overinst   *on = (slap_overinst *)be->bd_info;
137         allop_t         *ao = (allop_t *)on->on_bi.bi_private;
138
139         if ( ao != NULL ) {
140                 assert( !BER_BVISNULL( &ao->ao_ndn ) );
141
142                 ch_free( ao->ao_ndn.bv_val );
143                 ch_free( ao );
144                 on->on_bi.bi_private = NULL;
145         }
146
147         return 0;
148 }
149
150 static int
151 allop_op_search( Operation *op, SlapReply *rs )
152 {
153         slap_overinst   *on = (slap_overinst *)op->o_bd->bd_info;
154         allop_t         *ao = (allop_t *)on->on_bi.bi_private;
155
156         slap_mask_t     mask;
157         int             i,
158                         add_allUser = 0;
159
160         if ( ao == NULL ) {
161                 if ( !BER_BVISEMPTY( &op->o_req_ndn )
162                         || op->ors_scope != LDAP_SCOPE_BASE )
163                 {
164                         return SLAP_CB_CONTINUE;
165                 }
166
167         } else {
168                 if ( !dnIsSuffix( &op->o_req_ndn, &ao->ao_ndn ) ) {
169                         return SLAP_CB_CONTINUE;
170                 }
171
172                 switch ( ao->ao_scope ) {
173                 case LDAP_SCOPE_BASE:
174                         if ( op->o_req_ndn.bv_len != ao->ao_ndn.bv_len ) {
175                                 return SLAP_CB_CONTINUE;
176                         }
177                         break;
178
179                 case LDAP_SCOPE_ONELEVEL:
180                         if ( op->ors_scope == LDAP_SCOPE_BASE ) {
181                                 struct berval   rdn = op->o_req_ndn;
182
183                                 rdn.bv_len -= ao->ao_ndn.bv_len + STRLENOF( "," );
184                                 if ( !dnIsOneLevelRDN( &rdn ) ) {
185                                         return SLAP_CB_CONTINUE;
186                                 }
187
188                                 break;
189                         }
190                         return SLAP_CB_CONTINUE;
191
192                 case LDAP_SCOPE_SUBTREE:
193                         break;
194                 }
195         }
196
197         mask = slap_attr_flags( op->ors_attrs );
198         if ( SLAP_OPATTRS( mask ) ) {
199                 return SLAP_CB_CONTINUE;
200         }
201
202         if ( !SLAP_USERATTRS( mask ) ) {
203                 return SLAP_CB_CONTINUE;
204         }
205
206         i = 0;
207         if ( op->ors_attrs == NULL ) {
208                 add_allUser = 1;
209
210         } else {
211                 for ( ; !BER_BVISNULL( &op->ors_attrs[ i ].an_name ); i++ )
212                         ;
213         }
214
215         op->ors_attrs = op->o_tmprealloc( op->ors_attrs,
216                 sizeof( AttributeName ) * ( i + add_allUser + 2 ),
217                 op->o_tmpmemctx );
218
219         if ( add_allUser ) {
220                 op->ors_attrs[ i ] = slap_anlist_all_user_attributes[ 0 ];
221                 i++;
222         }
223
224         op->ors_attrs[ i ] = slap_anlist_all_operational_attributes[ 0 ];
225
226         BER_BVZERO( &op->ors_attrs[ i + 1 ].an_name );
227
228         return SLAP_CB_CONTINUE;
229 }
230
231 static slap_overinst            allop;
232
233 int
234 allop_init()
235 {
236         allop.on_bi.bi_type = "allop";
237
238         allop.on_bi.bi_db_config = allop_db_config;
239         allop.on_bi.bi_db_destroy = allop_db_destroy;
240
241         allop.on_bi.bi_op_search = allop_op_search;
242
243         return overlay_register( &allop );
244 }
245
246 #if SLAPD_OVER_ALLOP == SLAPD_MOD_DYNAMIC
247 int
248 init_module( int argc, char *argv[] )
249 {
250         return allop_init();
251 }
252 #endif /* SLAPD_OVER_ALLOP == SLAPD_MOD_DYNAMIC */
253
254 #endif /* defined(SLAPD_OVER_ALLOP) */