]> git.sur5r.net Git - openldap/blob - servers/slapd/back-meta/group.c
slight improvements; doesn't work yet
[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-2004 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 = { 0, NULL }, mgr_ndn = { 0, NULL };
60
61         struct berval group_oc_name = { 0, NULL };
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 == -1 ) {
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 #ifdef NEW_LOGGING
131                 LDAP_LOG( BACK_META, DETAIL1,
132                         "[rw] bindDn (op ndn in group): \"%s\" -> \"%s\"\n",
133                         op_ndn->bv_val, mop_ndn.bv_val, 0 );
134 #else /* !NEW_LOGGING */
135                 Debug( LDAP_DEBUG_ARGS,
136                                 "rw> bindDn (op ndn in group):"
137                                 " \"%s\" -> \"%s\"\n%s",
138                                 op_ndn->bv_val, mop_ndn.bv_val, "" );
139 #endif /* !NEW_LOGGING */
140                 break;
141                 
142         case REWRITE_REGEXEC_UNWILLING:
143                 /* continues to next case */
144                 
145         case REWRITE_REGEXEC_ERR:
146                 return 1;
147         }
148
149         /*
150          * Rewrite the gr ndn if needed
151          */
152         switch ( rewrite_session( li->targets[ candidate ]->rwinfo,
153                                 "searchBase",
154                                 gr_ndn->bv_val, conn, &mgr_ndn.bv_val ) ) {
155         case REWRITE_REGEXEC_OK:
156                 if ( mgr_ndn.bv_val != NULL && mgr_ndn.bv_val[ 0 ] != '\0' ) {
157                         mgr_ndn.bv_len = strlen( mgr_ndn.bv_val );
158                 } else {
159                         mgr_ndn = *gr_ndn;
160                 }
161 #ifdef NEW_LOGGING
162                 LDAP_LOG( BACK_META, DETAIL1,
163                         "[rw] searchBase (gr ndn in group): \"%s\" -> \"%s\"\n",
164                         gr_ndn->bv_val, mgr_ndn.bv_val, 0 );
165 #else /* !NEW_LOGGING */
166                 Debug( LDAP_DEBUG_ARGS,
167                                 "rw> searchBase (gr ndn in group):"
168                                 " \"%s\" -> \"%s\"\n%s",
169                                 gr_ndn->bv_val, mgr_ndn.bv_val, "" );
170 #endif /* !NEW_LOGGING */
171                 break;
172                 
173         case REWRITE_REGEXEC_UNWILLING:
174                 /* continues to next case */
175                 
176         case REWRITE_REGEXEC_ERR:
177                 goto cleanup;
178         }
179         
180         ldap_back_map( &li->targets[ candidate ]->oc_map,
181                         &group_oc_name, &group_oc_name, BACKLDAP_MAP );
182         if ( group_oc_name.bv_val == NULL || group_oc_name.bv_val[0] == '\0' ) {
183                 goto cleanup;
184         }
185         ldap_back_map( &li->targets[ candidate ]->at_map,
186                         &group_at_name, &group_at_name, BACKLDAP_MAP );
187         if ( group_at_name.bv_val == NULL || group_at_name.bv_val[0] == '\0' ) {
188                 goto cleanup;
189         }
190
191         filter = ch_malloc( sizeof( "(&(objectclass=)(=))" )
192                         + group_oc_name.bv_len
193                         + group_at_name.bv_len
194                         + mop_ndn.bv_len + 1 );
195         if ( filter == NULL ) {
196                 goto cleanup;
197         }
198
199         rc = ldap_initialize( &ld, li->targets[ candidate ]->uri );
200         if ( rc != LDAP_SUCCESS ) {
201                 goto cleanup;
202         }
203
204         rc = ldap_bind_s( ld, li->targets[ candidate ]->binddn.bv_val,
205                         li->targets[ candidate ]->bindpw.bv_val, 
206                         LDAP_AUTH_SIMPLE );
207         if ( rc != LDAP_SUCCESS ) {
208                 goto cleanup;
209         }
210
211         ptr = lutil_strcopy( filter, "(&(objectclass=" );
212         ptr = lutil_strcopy( ptr , group_oc_name.bv_val );
213         ptr = lutil_strcopy( ptr , ")(" );
214         ptr = lutil_strcopy( ptr , group_at_name.bv_val );
215         ptr = lutil_strcopy( ptr , "=" );
216         ptr = lutil_strcopy( ptr , mop_ndn.bv_val );
217         strcpy( ptr , "))" );
218
219         gattr[ 0 ] = "objectclass";
220         gattr[ 1 ] = NULL;
221         rc = 1;
222         if ( ldap_search_ext_s( ld, mgr_ndn.bv_val, LDAP_SCOPE_BASE, filter,
223                                 gattr, 0, NULL, NULL, LDAP_NO_LIMIT,
224                                 LDAP_NO_LIMIT, &result ) == LDAP_SUCCESS ) {
225                 if ( ldap_first_entry( ld, result ) != NULL ) {
226                         rc = 0;
227                 }
228                 ldap_msgfree( result );
229         }
230
231 cleanup:;
232         if ( ld != NULL ) {
233                 ldap_unbind( ld );
234         }
235         if ( filter != NULL ) {
236                 ch_free( filter );
237         }
238         if ( mop_ndn.bv_val != op_ndn->bv_val ) {
239                 free( mop_ndn.bv_val );
240         }
241         if ( mgr_ndn.bv_val != gr_ndn->bv_val ) {
242                 free( mgr_ndn.bv_val );
243         }
244
245         return rc;
246 }
247