2 * Copyright 1998-2001 The OpenLDAP Foundation, All Rights Reserved.
3 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5 * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
7 * This work has been developed to fulfill the requirements
8 * of SysNet s.n.c. <http:www.sys-net.it> and it has been donated
9 * to the OpenLDAP Foundation in the hope that it may be useful
10 * to the Open Source community, but WITHOUT ANY WARRANTY.
12 * Permission is granted to anyone to use this software for any purpose
13 * on any computer system, and to alter it and redistribute it, subject
14 * to the following restrictions:
16 * 1. The author and SysNet s.n.c. are not responsible for the consequences
17 * of use of this software, no matter how awful, even if they arise from
20 * 2. The origin of this software must not be misrepresented, either by
21 * explicit claim or by omission. Since few users ever read sources,
22 * credits should appear in the documentation.
24 * 3. Altered versions must be plainly marked as such, and must not be
25 * misrepresented as being the original software. Since few users
26 * ever read sources, credits should appear in the documentation.
27 * SysNet s.n.c. cannot be responsible for the consequences of the
30 * 4. This notice may not be removed or altered.
33 * This software is based on the backend back-ldap, implemented
34 * by Howard Chu <hyc@highlandsun.com>, and modified by Mark Valence
35 * <kurash@sassafras.com>, Pierangelo Masarati <ando@sys-net.it> and other
36 * contributors. The contribution of the original software to the present
37 * implementation is acknowledged in this copyright statement.
39 * A special acknowledgement goes to Howard for the overall architecture
40 * (and for borrowing large pieces of code), and to Mark, who implemented
41 * from scratch the attribute/objectclass mapping.
43 * The original copyright statement follows.
45 * Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
47 * Permission is granted to anyone to use this software for any purpose
48 * on any computer system, and to alter it and redistribute it, subject
49 * to the following restrictions:
51 * 1. The author is not responsible for the consequences of use of this
52 * software, no matter how awful, even if they arise from flaws in it.
54 * 2. The origin of this software must not be misrepresented, either by
55 * explicit claim or by omission. Since few users ever read sources,
56 * credits should appear in the documentation.
58 * 3. Altered versions must be plainly marked as such, and must not be
59 * misrepresented as being the original software. Since few users
60 * ever read sources, credits should appear in the
63 * 4. This notice may not be removed or altered.
71 #include <ac/socket.h>
72 #include <ac/string.h>
75 #include "../back-ldap/back-ldap.h"
76 #include "back-meta.h"
79 /* return 0 IFF op_dn is a value in group_at (member) attribute
80 * of entry with gr_dn AND that entry has an objectClass
81 * value of group_oc (groupOfNames)
89 struct berval *gr_ndn,
90 struct berval *op_ndn,
91 ObjectClass *group_oc,
92 AttributeDescription *group_at
95 struct metainfo *li = ( struct metainfo * )be->be_private;
96 int rc = 1, candidate;
98 AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass;
103 char *mop_ndn, *mgr_ndn;
105 char *group_oc_name = NULL;
106 char *group_at_name = group_at->ad_cname.bv_val;
108 if ( group_oc->soc_names && group_oc->soc_names[ 0 ] ) {
109 group_oc_name = group_oc->soc_names[ 0 ];
111 group_oc_name = group_oc->soc_oid;
114 if ( target != NULL && strcmp( target->e_nname.bv_val, gr_ndn->bv_val ) == 0 ) {
115 /* we already have a copy of the entry */
116 /* attribute and objectclass mapping has already been done */
119 * first we need to check if the objectClass attribute
120 * has been retrieved; otherwise we need to repeat the search
122 attr = attr_find( target->e_attrs, ad_objectClass );
123 if ( attr != NULL ) {
126 * Now we can check for the group objectClass value
128 if ( !is_entry_objectclass( target, group_oc ) ) {
133 * This part has been reworked: the group attr compare
134 * fails only if the attribute is PRESENT but the value
135 * is NOT PRESENT; if the attribute is NOT PRESENT, the
136 * search must be repeated as well.
137 * This may happen if a search for an entry has already
138 * been performed (target is not null) but the group
139 * attribute has not been required
141 attr = attr_find( target->e_attrs, group_at );
142 if ( attr != NULL ) {
143 rc = value_find( group_at, attr->a_vals,
145 if ( rc != LDAP_SUCCESS ) {
149 } /* else: repeat the search */
150 } /* else: repeat the search */
151 } /* else: do the search */
153 candidate = meta_back_select_unique_candidate( li, gr_ndn );
154 if ( candidate == -1 ) {
159 * Rewrite the op ndn if needed
161 switch ( rewrite_session( li->targets[ candidate ]->rwinfo, "bindDn",
162 op_ndn->bv_val, conn, &mop_ndn ) ) {
163 case REWRITE_REGEXEC_OK:
164 if ( mop_ndn == NULL ) {
165 mop_ndn = ( char * )op_ndn->bv_val;
168 LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
169 "[rw] bindDn (op ndn in group):"
171 op_ndn->bv_val, mop_ndn));
172 #else /* !NEW_LOGGING */
173 Debug( LDAP_DEBUG_ARGS,
174 "rw> bindDn (op ndn in group):"
175 " \"%s\" -> \"%s\"\n%s",
176 op_ndn->bv_val, mop_ndn, "" );
177 #endif /* !NEW_LOGGING */
180 case REWRITE_REGEXEC_UNWILLING:
181 /* continues to next case */
183 case REWRITE_REGEXEC_ERR:
188 * Rewrite the gr ndn if needed
190 switch ( rewrite_session( li->targets[ candidate ]->rwinfo,
192 gr_ndn->bv_val, conn, &mgr_ndn ) ) {
193 case REWRITE_REGEXEC_OK:
194 if ( mgr_ndn == NULL ) {
195 mgr_ndn = ( char * )gr_ndn->bv_val;
198 LDAP_LOG(( "backend", LDAP_LEVEL_DETAIL1,
199 "[rw] searchBase (gr ndn in group):"
200 " \"%s\" -> \"%s\"\n",
201 gr_ndn->bv_val, mgr_ndn ));
202 #else /* !NEW_LOGGING */
203 Debug( LDAP_DEBUG_ARGS,
204 "rw> searchBase (gr ndn in group):"
205 " \"%s\" -> \"%s\"\n%s",
206 gr_ndn->bv_val, mgr_ndn, "" );
207 #endif /* !NEW_LOGGING */
210 case REWRITE_REGEXEC_UNWILLING:
211 /* continues to next case */
213 case REWRITE_REGEXEC_ERR:
217 group_oc_name = ldap_back_map( &li->targets[ candidate ]->oc_map,
219 if ( group_oc_name == NULL ) {
222 group_at_name = ldap_back_map( &li->targets[ candidate ]->at_map,
224 if ( group_at_name == NULL ) {
228 filter = ch_malloc( sizeof( "(&(objectclass=)(=))" )
229 + strlen( group_oc_name )
230 + strlen( group_at_name )
231 + strlen( mop_ndn ) + 1 );
232 if ( filter == NULL ) {
236 rc = ldap_initialize( &ld, li->targets[ candidate ]->uri );
237 if ( rc != LDAP_SUCCESS ) {
241 rc = ldap_bind_s( ld, li->targets[ candidate ]->binddn->bv_val,
242 li->targets[ candidate ]->bindpw->bv_val,
244 if ( rc != LDAP_SUCCESS ) {
248 strcpy( filter, "(&(objectclass=" );
249 strcat( filter, group_oc_name );
250 strcat( filter, ")(" );
251 strcat( filter, group_at_name );
252 strcat( filter, "=" );
253 strcat( filter, mop_ndn );
254 strcat( filter, "))" );
256 gattr[ 0 ] = "objectclass";
259 if ( ldap_search_ext_s( ld, mgr_ndn, LDAP_SCOPE_BASE, filter,
260 gattr, 0, NULL, NULL, LDAP_NO_LIMIT,
261 LDAP_NO_LIMIT, &result ) == LDAP_SUCCESS ) {
262 if ( ldap_first_entry( ld, result ) != NULL ) {
265 ldap_msgfree( result );
272 if ( filter != NULL ) {
275 if ( mop_ndn != op_ndn->bv_val ) {
278 if ( mgr_ndn != gr_ndn->bv_val ) {