]> git.sur5r.net Git - openldap/blob - contrib/slapd-modules/allop/allop.c
56a536d11f2ef421a7766325202fcd8919c06703
[openldap] / contrib / slapd-modules / allop / 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 #include <stdio.h>
39 #include <ac/string.h>
40
41 #include "slap.h"
42
43 #define SLAP_OVER_VERSION_REQUIRE(major,minor,patch) \
44         ( \
45                 ( LDAP_VENDOR_VERSION_MAJOR == X || LDAP_VENDOR_VERSION_MAJOR >= (major) ) \
46                 && ( LDAP_VENDOR_VERSION_MINOR == X || LDAP_VENDOR_VERSION_MINOR >= (minor) ) \
47                 && ( LDAP_VENDOR_VERSION_PATCH == X || LDAP_VENDOR_VERSION_PATCH >= (patch) ) \
48         )
49
50 #if !SLAP_OVER_VERSION_REQUIRE(2,3,0)
51 #error "version mismatch"
52 #endif
53
54 typedef struct allop_t {
55         struct berval   ao_ndn;
56         int             ao_scope;
57 } allop_t;
58
59 static int
60 allop_db_config(
61         BackendDB       *be,
62         const char      *fname,
63         int             lineno,
64         int             argc,
65         char            **argv )
66 {
67         slap_overinst   *on = (slap_overinst *)be->bd_info;
68         allop_t         *ao = (allop_t *)on->on_bi.bi_private;
69
70         if ( strcasecmp( argv[ 0 ], "allop-uri" ) == 0 ) {
71                 LDAPURLDesc     *lud;
72                 struct berval   dn,
73                                 ndn;
74                 int             scope,
75                                 rc = LDAP_SUCCESS;
76
77                 if ( argc != 2 ) {
78                         fprintf( stderr, "%s line %d: "
79                                 "need exactly 1 arg "
80                                 "in \"allop-uri <ldapURI>\" "
81                                 "directive.\n",
82                                 fname, lineno );
83                         return 1;
84                 }
85
86                 if ( ldap_url_parse( argv[ 1 ], &lud ) != LDAP_URL_SUCCESS ) {
87                         return -1;
88                 }
89
90                 scope = lud->lud_scope;
91                 if ( scope == LDAP_SCOPE_DEFAULT ) {
92                         scope = LDAP_SCOPE_BASE;
93                 }
94
95                 if ( lud->lud_dn == NULL || lud->lud_dn[ 0 ] == '\0' ) {
96                         if ( scope == LDAP_SCOPE_BASE ) {
97                                 BER_BVZERO( &ndn );
98
99                         } else {
100                                 ber_str2bv( "", 0, 1, &ndn );
101                         }
102
103                 } else {
104
105                         ber_str2bv( lud->lud_dn, 0, 0, &dn );
106                         rc = dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL );
107                 }
108
109                 ldap_free_urldesc( lud );
110                 if ( rc != LDAP_SUCCESS ) {
111                         return -1;
112                 }
113
114                 if ( BER_BVISNULL( &ndn ) ) {
115                         /* rootDSE */
116                         if ( ao != NULL ) {
117                                 ch_free( ao->ao_ndn.bv_val );
118                                 ch_free( ao );
119                                 on->on_bi.bi_private = NULL;
120                         }
121
122                 } else {
123                         if ( ao == NULL ) {
124                                 ao = ch_calloc( 1, sizeof( allop_t ) );
125                                 on->on_bi.bi_private = (void *)ao;
126
127                         } else {
128                                 ch_free( ao->ao_ndn.bv_val );
129                         }
130
131                         ao->ao_ndn = ndn;
132                         ao->ao_scope = scope;
133                 }
134
135         } else {
136                 return SLAP_CONF_UNKNOWN;
137         }
138
139         return 0;
140 }
141
142 static int
143 allop_db_destroy( BackendDB *be )
144 {
145         slap_overinst   *on = (slap_overinst *)be->bd_info;
146         allop_t         *ao = (allop_t *)on->on_bi.bi_private;
147
148         if ( ao != NULL ) {
149                 assert( !BER_BVISNULL( &ao->ao_ndn ) );
150
151                 ch_free( ao->ao_ndn.bv_val );
152                 ch_free( ao );
153                 on->on_bi.bi_private = NULL;
154         }
155
156         return 0;
157 }
158
159 static int
160 allop_op_search( Operation *op, SlapReply *rs )
161 {
162         slap_overinst   *on = (slap_overinst *)op->o_bd->bd_info;
163         allop_t         *ao = (allop_t *)on->on_bi.bi_private;
164
165         slap_mask_t     mask;
166         int             i,
167                         add_allUser = 0;
168
169         if ( ao == NULL ) {
170                 if ( !BER_BVISEMPTY( &op->o_req_ndn )
171                         || op->ors_scope != LDAP_SCOPE_BASE )
172                 {
173                         return SLAP_CB_CONTINUE;
174                 }
175
176         } else {
177                 if ( !dnIsSuffix( &op->o_req_ndn, &ao->ao_ndn ) ) {
178                         return SLAP_CB_CONTINUE;
179                 }
180
181                 switch ( ao->ao_scope ) {
182                 case LDAP_SCOPE_BASE:
183                         if ( op->o_req_ndn.bv_len != ao->ao_ndn.bv_len ) {
184                                 return SLAP_CB_CONTINUE;
185                         }
186                         break;
187
188                 case LDAP_SCOPE_ONELEVEL:
189                         if ( op->ors_scope == LDAP_SCOPE_BASE ) {
190                                 struct berval   rdn = op->o_req_ndn;
191
192                                 rdn.bv_len -= ao->ao_ndn.bv_len + STRLENOF( "," );
193                                 if ( !dnIsOneLevelRDN( &rdn ) ) {
194                                         return SLAP_CB_CONTINUE;
195                                 }
196
197                                 break;
198                         }
199                         return SLAP_CB_CONTINUE;
200
201                 case LDAP_SCOPE_SUBTREE:
202                         break;
203                 }
204         }
205
206         mask = slap_attr_flags( op->ors_attrs );
207         if ( SLAP_OPATTRS( mask ) ) {
208                 return SLAP_CB_CONTINUE;
209         }
210
211         if ( !SLAP_USERATTRS( mask ) ) {
212                 return SLAP_CB_CONTINUE;
213         }
214
215         i = 0;
216         if ( op->ors_attrs == NULL ) {
217                 add_allUser = 1;
218
219         } else {
220                 for ( ; !BER_BVISNULL( &op->ors_attrs[ i ].an_name ); i++ )
221                         ;
222         }
223
224         op->ors_attrs = op->o_tmprealloc( op->ors_attrs,
225                 sizeof( AttributeName ) * ( i + add_allUser + 2 ),
226                 op->o_tmpmemctx );
227
228         if ( add_allUser ) {
229                 op->ors_attrs[ i ] = slap_anlist_all_user_attributes[ 0 ];
230                 i++;
231         }
232
233         op->ors_attrs[ i ] = slap_anlist_all_operational_attributes[ 0 ];
234
235         BER_BVZERO( &op->ors_attrs[ i + 1 ].an_name );
236
237         return SLAP_CB_CONTINUE;
238 }
239
240 static slap_overinst            allop;
241
242 int
243 allop_init()
244 {
245         allop.on_bi.bi_type = "allop";
246
247         allop.on_bi.bi_db_config = allop_db_config;
248         allop.on_bi.bi_db_destroy = allop_db_destroy;
249
250         allop.on_bi.bi_op_search = allop_op_search;
251
252         return overlay_register( &allop );
253 }
254
255 int
256 init_module( int argc, char *argv[] )
257 {
258         return allop_init();
259 }
260