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-2021 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
allop_db_config(BackendDB * be,const char * fname,int lineno,int argc,char ** argv)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
allop_db_destroy(BackendDB * be,ConfigReply * cr)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
allop_op_search(Operation * op,SlapReply * rs)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
allop_init()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
init_module(int argc,char * argv[])257 init_module( int argc, char *argv[] )
258 {
259 return allop_init();
260 }
261
262