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