]> git.sur5r.net Git - openldap/blob - servers/slapd/back-meta/attribute.c
notices and acknowledges
[openldap] / servers / slapd / back-meta / attribute.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1999-2003 The OpenLDAP Foundation.
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted only as authorized by the OpenLDAP
9  * Public License.
10  *
11  * A copy of this license is available in the file LICENSE in the
12  * top-level directory of the distribution or, alternatively, at
13  * <http://www.OpenLDAP.org/license.html>.
14  */
15 /* ACKNOWLEDGEMENTS:
16  * This work was initially developed by the Howard Chu for inclusion
17  * in OpenLDAP Software and subsequently enhanced by Pierangelo
18  * Masarati.
19  */
20 /* This is an altered version */
21 /*
22  * Copyright 2001, Pierangelo Masarati, All rights reserved. <ando@sys-net.it>
23  *
24  * This work has been developed to fulfill the requirements
25  * of SysNet s.n.c. <http:www.sys-net.it> and it has been donated
26  * to the OpenLDAP Foundation in the hope that it may be useful
27  * to the Open Source community, but WITHOUT ANY WARRANTY.
28  *
29  * Permission is granted to anyone to use this software for any purpose
30  * on any computer system, and to alter it and redistribute it, subject
31  * to the following restrictions:
32  * 
33  * 1. The author and SysNet s.n.c. are not responsible for the consequences
34  *    of use of this software, no matter how awful, even if they arise from 
35  *    flaws in it.
36  *
37  * 2. The origin of this software must not be misrepresented, either by
38  *    explicit claim or by omission.  Since few users ever read sources,
39  *    credits should appear in the documentation.
40  *
41  * 3. Altered versions must be plainly marked as such, and must not be
42  *    misrepresented as being the original software.  Since few users
43  *    ever read sources, credits should appear in the documentation.
44  *    SysNet s.n.c. cannot be responsible for the consequences of the
45  *    alterations.
46  *
47  * 4. This notice may not be removed or altered.
48  * 
49  * 
50  * This software is based on the backend back-ldap, implemented
51  * by Howard Chu <hyc@highlandsun.com>, and modified by Mark Valence
52  * <kurash@sassafras.com>, Pierangelo Masarati <ando@sys-net.it> and other
53  * contributors. The contribution of the original software to the present
54  * implementation is acknowledged in this copyright statement.
55  * 
56  * A special acknowledgement goes to Howard for the overall architecture
57  * (and for borrowing large pieces of code), and to Mark, who implemented
58  * from scratch the attribute/objectclass mapping.
59  * 
60  * The original copyright statement follows.
61  *
62  * Copyright 1999, Howard Chu, All rights reserved. <hyc@highlandsun.com>
63  *
64  * Permission is granted to anyone to use this software for any purpose
65  * on any computer system, and to alter it and redistribute it, subject
66  * to the following restrictions:
67  *
68  * 1. The author is not responsible for the consequences of use of this
69  *    software, no matter how awful, even if they arise from flaws in it.
70  *
71  * 2. The origin of this software must not be misrepresented, either by
72  *    explicit claim or by omission.  Since few users ever read sources,
73  *    credits should appear in the documentation.
74  *
75  * 3. Altered versions must be plainly marked as such, and must not be
76  *    misrepresented as being the original software.  Since few users
77  *    ever read sources, credits should appear in the
78  *    documentation.
79  *
80  * 4. This notice may not be removed or altered.
81  *
82  */
83
84 #include "portable.h"
85
86 #include <stdio.h>
87
88 #include <ac/socket.h>
89 #include <ac/string.h>
90
91 #include "slap.h"
92 #include "../back-ldap/back-ldap.h"
93 #include "back-meta.h"
94
95
96 /* return 0 IFF we can retrieve the attributes
97  * of entry with e_ndn
98  */
99
100 /*
101  * FIXME: I never testd this function; I know it compiles ... :)
102  */
103 int
104 meta_back_attribute(
105                 Backend                 *be,
106                 Connection              *conn,
107                 Operation               *op,
108                 Entry                   *target,
109                 struct berval           *ndn,
110                 AttributeDescription    *entry_at,
111                 BerVarray                       *vals
112 )
113 {
114         struct metainfo *li = ( struct metainfo * )be->be_private;    
115         int rc = 1, i, j, count, is_oc, candidate;
116         Attribute *attr;
117         BerVarray abv, v;
118         char **vs; 
119         struct berval   mapped;
120         LDAPMessage     *result, *e;
121         char *gattr[ 2 ];
122         LDAP *ld;
123
124         *vals = NULL;
125         if ( target != NULL && dn_match( &target->e_nname, ndn ) ) {
126                 /* we already have a copy of the entry */
127                 /* attribute and objectclass mapping has already been done */
128                 attr = attr_find( target->e_attrs, entry_at );
129                 if ( attr == NULL ) {
130                         return 1;
131                 }
132
133                 for ( count = 0; attr->a_vals[ count ].bv_val != NULL; count++ )
134                         ;
135                 v = ( BerVarray )ch_calloc( ( count + 1 ), sizeof( struct berval ) );
136                 if ( v == NULL ) {
137                         return 1;
138                 }
139
140                 for ( j = 0, abv = attr->a_vals; --count >= 0; abv++ ) {
141                         if ( abv->bv_len > 0 ) {
142                                 ber_dupbv( &v[ j ], abv );
143                                 if ( v[ j ].bv_val == NULL ) {
144                                         break;
145                                 }
146                         }
147                 }
148                 v[ j ].bv_val = NULL;
149                 *vals = v;
150
151                 return 0;
152         } /* else */
153
154         candidate = meta_back_select_unique_candidate( li, ndn );
155         if ( candidate == -1 ) {
156                 return 1;
157         }
158
159         ldap_back_map( &li->targets[ candidate ]->at_map,
160                         &entry_at->ad_cname, &mapped, BACKLDAP_MAP );
161         if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' )
162                 return 1;
163
164         rc =  ldap_initialize( &ld, li->targets[ candidate ]->uri );
165         if ( rc != LDAP_SUCCESS ) {
166                 return 1;
167         }
168
169         rc = ldap_bind_s( ld, li->targets[ candidate ]->binddn.bv_val,
170                         li->targets[ candidate ]->bindpw.bv_val, LDAP_AUTH_SIMPLE );
171         if ( rc != LDAP_SUCCESS) {
172                 return 1;
173         }
174
175         gattr[ 0 ] = mapped.bv_val;
176         gattr[ 1 ] = NULL;
177         if ( ldap_search_ext_s( ld, ndn->bv_val, LDAP_SCOPE_BASE, 
178                                 "(objectClass=*)",
179                                 gattr, 0, NULL, NULL, LDAP_NO_LIMIT,
180                                 LDAP_NO_LIMIT, &result) == LDAP_SUCCESS) {
181                 if ( ( e = ldap_first_entry( ld, result ) ) != NULL ) {
182                         vs = ldap_get_values( ld, e, mapped.bv_val );
183                         if ( vs != NULL ) {
184                                 for ( count = 0; vs[ count ] != NULL;
185                                                 count++ ) { }
186                                 v = ( BerVarray )ch_calloc( ( count + 1 ),
187                                                 sizeof( struct berval ) );
188                                 if ( v == NULL ) {
189                                         ldap_value_free( vs );
190                                 } else {
191                                         is_oc = ( strcasecmp( "objectclass", mapped.bv_val ) == 0 );
192                                         for ( i = 0, j = 0; i < count; i++ ) {
193                                                 ber_str2bv( vs[ i ], 0, 0, &v[ j ] );
194                                                 if ( !is_oc ) {
195                                                         if ( v[ j ].bv_val == NULL ) {
196                                                                 ch_free( vs[ i ] );
197                                                         } else {
198                                                                 j++;
199                                                         }
200                                                 } else {
201                                                         ldap_back_map( &li->targets[ candidate ]->oc_map, &v[ j ], &mapped, BACKLDAP_REMAP );
202                                                         if ( mapped.bv_val && mapped.bv_val[0] != '\0' ) {
203                                                                 ber_dupbv( &v[ j ], &mapped );
204                                                                 if ( v[ j ].bv_val ) {
205                                                                         j++;
206                                                                 }
207                                                         }
208                                                         ch_free( vs[ i ] );
209                                                 }
210                                         }
211                                         v[ j ].bv_val = NULL;
212                                         *vals = v;
213                                         rc = 0;
214                                         ch_free( vs );
215                                 }
216                         }
217                 }
218                 ldap_msgfree( result );
219         }
220         ldap_unbind( ld );
221
222         return(rc);
223 }
224