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