]> git.sur5r.net Git - openldap/blob - servers/slapd/back-meta/group.c
Read config tree from back-ldif
[openldap] / servers / slapd / back-meta / group.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1999-2005 The OpenLDAP Foundation.
5  * Portions Copyright 2001-2003 Pierangelo Masarati.
6  * Portions Copyright 1999-2003 Howard Chu.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted only as authorized by the OpenLDAP
11  * Public License.
12  *
13  * A copy of this license is available in the file LICENSE in the
14  * top-level directory of the distribution or, alternatively, at
15  * <http://www.OpenLDAP.org/license.html>.
16  */
17 /* ACKNOWLEDGEMENTS:
18  * This work was initially developed by the Howard Chu for inclusion
19  * in OpenLDAP Software and subsequently enhanced by Pierangelo
20  * Masarati.
21  */
22
23 #include "portable.h"
24
25 #include <stdio.h>
26
27 #include <ac/socket.h>
28 #include <ac/string.h>
29
30 #include "slap.h"
31 #include "../back-ldap/back-ldap.h"
32 #include "back-meta.h"
33 #include "lutil.h"
34
35 /* return 0 IFF op_dn is a value in group_at (member) attribute
36  * of entry with gr_dn AND that entry has an objectClass
37  * value of group_oc (groupOfNames)
38  */
39 int
40 meta_back_group(
41                 Backend                 *be,
42                 Connection              *conn,
43                 Operation               *op,
44                 Entry                   *target,
45                 struct berval           *gr_ndn,
46                 struct berval           *op_ndn,
47                 ObjectClass             *group_oc,
48                 AttributeDescription    *group_at
49 )
50 {
51         struct metainfo *li = ( struct metainfo * )be->be_private;    
52         int rc = 1, candidate;
53         Attribute   *attr;
54         AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass;
55         LDAPMessage     *result;
56         char *gattr[ 2 ];
57         char *filter = NULL, *ptr;
58         LDAP *ld = NULL;
59         struct berval mop_ndn = BER_BVNULL, mgr_ndn = BER_BVNULL;
60
61         struct berval group_oc_name = BER_BVNULL;
62         struct berval group_at_name = group_at->ad_cname;
63
64         if ( group_oc->soc_names && group_oc->soc_names[ 0 ] ) {
65                 group_oc_name.bv_val = group_oc->soc_names[ 0 ];
66         } else {
67                 group_oc_name.bv_val = group_oc->soc_oid;
68         }
69
70         if ( group_oc_name.bv_val ) {
71                 group_oc_name.bv_len = strlen( group_oc_name.bv_val );
72         }
73
74         if ( target != NULL && dn_match( &target->e_nname, gr_ndn ) ) {
75                 /* we already have a copy of the entry */
76                 /* attribute and objectclass mapping has already been done */
77
78                 /*
79                  * first we need to check if the objectClass attribute
80                  * has been retrieved; otherwise we need to repeat the search
81                  */
82                 attr = attr_find( target->e_attrs, ad_objectClass );
83                 if ( attr != NULL ) {
84
85                         /*
86                          * Now we can check for the group objectClass value
87                          */
88                         if ( !is_entry_objectclass( target, group_oc, 0 ) ) {
89                                 return 1;
90                         }
91
92                         /*
93                          * This part has been reworked: the group attr compare
94                          * fails only if the attribute is PRESENT but the value
95                          * is NOT PRESENT; if the attribute is NOT PRESENT, the
96                          * search must be repeated as well.
97                          * This may happen if a search for an entry has already
98                          * been performed (target is not null) but the group
99                          * attribute has not been required
100                          */
101                         attr = attr_find( target->e_attrs, group_at );
102                         if ( attr != NULL ) {
103                                 rc = value_find_ex( group_at,
104                                         SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
105                                         attr->a_vals, op_ndn );
106                                 if ( rc != LDAP_SUCCESS ) {
107                                         return 1;
108                                 }
109                                 return 0;
110                         } /* else: repeat the search */
111                 } /* else: repeat the search */
112         } /* else: do the search */
113
114         candidate = meta_back_select_unique_candidate( li, gr_ndn );
115         if ( candidate == META_TARGET_NONE ) {
116                 goto cleanup;
117         }
118
119         /*
120          * Rewrite the op ndn if needed
121          */
122         switch ( rewrite_session( li->targets[ candidate ]->rwinfo, "bindDn",
123                                 op_ndn->bv_val, conn, &mop_ndn.bv_val ) ) {
124         case REWRITE_REGEXEC_OK:
125                 if ( mop_ndn.bv_val != NULL && mop_ndn.bv_val[ 0 ] != '\0' ) {
126                         mop_ndn.bv_len = strlen( mop_ndn.bv_val );
127                 } else {
128                         mop_ndn = *op_ndn;
129                 }
130                 Debug( LDAP_DEBUG_ARGS,
131                                 "rw> bindDn (op ndn in group):"
132                                 " \"%s\" -> \"%s\"\n%s",
133                                 op_ndn->bv_val, mop_ndn.bv_val, "" );
134                 break;
135                 
136         case REWRITE_REGEXEC_UNWILLING:
137                 /* continues to next case */
138                 
139         case REWRITE_REGEXEC_ERR:
140                 return 1;
141         }
142
143         /*
144          * Rewrite the gr ndn if needed
145          */
146         switch ( rewrite_session( li->targets[ candidate ]->rwinfo,
147                                 "searchBase",
148                                 gr_ndn->bv_val, conn, &mgr_ndn.bv_val ) ) {
149         case REWRITE_REGEXEC_OK:
150                 if ( mgr_ndn.bv_val != NULL && mgr_ndn.bv_val[ 0 ] != '\0' ) {
151                         mgr_ndn.bv_len = strlen( mgr_ndn.bv_val );
152                 } else {
153                         mgr_ndn = *gr_ndn;
154                 }
155                 Debug( LDAP_DEBUG_ARGS,
156                                 "rw> searchBase (gr ndn in group):"
157                                 " \"%s\" -> \"%s\"\n%s",
158                                 gr_ndn->bv_val, mgr_ndn.bv_val, "" );
159                 break;
160                 
161         case REWRITE_REGEXEC_UNWILLING:
162                 /* continues to next case */
163                 
164         case REWRITE_REGEXEC_ERR:
165                 goto cleanup;
166         }
167         
168         ldap_back_map( &li->targets[ candidate ]->oc_map,
169                         &group_oc_name, &group_oc_name, BACKLDAP_MAP );
170         if ( group_oc_name.bv_val == NULL || group_oc_name.bv_val[0] == '\0' ) {
171                 goto cleanup;
172         }
173         ldap_back_map( &li->targets[ candidate ]->at_map,
174                         &group_at_name, &group_at_name, BACKLDAP_MAP );
175         if ( group_at_name.bv_val == NULL || group_at_name.bv_val[0] == '\0' ) {
176                 goto cleanup;
177         }
178
179         filter = ch_malloc( sizeof( "(&(objectclass=)(=))" )
180                         + group_oc_name.bv_len
181                         + group_at_name.bv_len
182                         + mop_ndn.bv_len + 1 );
183         if ( filter == NULL ) {
184                 goto cleanup;
185         }
186
187         rc = ldap_initialize( &ld, li->targets[ candidate ]->uri );
188         if ( rc != LDAP_SUCCESS ) {
189                 goto cleanup;
190         }
191
192         rc = ldap_bind_s( ld, li->targets[ candidate ]->binddn.bv_val,
193                         li->targets[ candidate ]->bindpw.bv_val, 
194                         LDAP_AUTH_SIMPLE );
195         if ( rc != LDAP_SUCCESS ) {
196                 goto cleanup;
197         }
198
199         ptr = lutil_strcopy( filter, "(&(objectclass=" );
200         ptr = lutil_strcopy( ptr , group_oc_name.bv_val );
201         ptr = lutil_strcopy( ptr , ")(" );
202         ptr = lutil_strcopy( ptr , group_at_name.bv_val );
203         ptr = lutil_strcopy( ptr , "=" );
204         ptr = lutil_strcopy( ptr , mop_ndn.bv_val );
205         strcpy( ptr , "))" );
206
207         gattr[ 0 ] = "objectclass";
208         gattr[ 1 ] = NULL;
209         rc = 1;
210         if ( ldap_search_ext_s( ld, mgr_ndn.bv_val, LDAP_SCOPE_BASE, filter,
211                                 gattr, 0, NULL, NULL, LDAP_NO_LIMIT,
212                                 LDAP_NO_LIMIT, &result ) == LDAP_SUCCESS ) {
213                 if ( ldap_first_entry( ld, result ) != NULL ) {
214                         rc = 0;
215                 }
216                 ldap_msgfree( result );
217         }
218
219 cleanup:;
220         if ( ld != NULL ) {
221                 ldap_unbind( ld );
222         }
223         if ( filter != NULL ) {
224                 ch_free( filter );
225         }
226         if ( mop_ndn.bv_val != op_ndn->bv_val ) {
227                 free( mop_ndn.bv_val );
228         }
229         if ( mgr_ndn.bv_val != gr_ndn->bv_val ) {
230                 free( mgr_ndn.bv_val );
231         }
232
233         return rc;
234 }
235