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