]> git.sur5r.net Git - openldap/blob - servers/slapd/back-sql/operational.c
c0c7ed2442f5012f84a023febd91ffc9a5841725
[openldap] / servers / slapd / back-sql / operational.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 1999 Dmitry Kovalev.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted only as authorized by the OpenLDAP
10  * Public License.
11  *
12  * A copy of this license is available in the file LICENSE in the
13  * top-level directory of the distribution or, alternatively, at
14  * <http://www.OpenLDAP.org/license.html>.
15  */
16 /* ACKNOWLEDGEMENTS:
17  * This work was initially developed by Dmitry Kovalev for inclusion
18  * by OpenLDAP Software.
19  */
20
21 #include "portable.h"
22
23 #include <stdio.h>
24 #include <sys/types.h>
25
26 #include "slap.h"
27 #include "proto-sql.h"
28 #include "lutil.h"
29
30 /*
31  * sets the supported operational attributes (if required)
32  */
33
34 Attribute *
35 backsql_operational_entryUUID( backsql_info *bi, backsql_entryID *id )
36 {
37         int                     rc;
38         struct berval           val, nval;
39         AttributeDescription    *desc = slap_schema.si_ad_entryUUID;
40         Attribute               *a;
41
42         backsql_entryUUID( bi, id, &val, NULL );
43
44         rc = (*desc->ad_type->sat_equality->smr_normalize)(
45                         SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
46                         desc->ad_type->sat_syntax,
47                         desc->ad_type->sat_equality,
48                         &val, &nval, NULL );
49         if ( rc != LDAP_SUCCESS ) {
50                 ber_memfree( val.bv_val );
51                 return NULL;
52         }
53
54         a = ch_malloc( sizeof( Attribute ) );
55         a->a_desc = desc;
56
57         a->a_vals = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
58         a->a_vals[ 0 ] = val;
59         BER_BVZERO( &a->a_vals[ 1 ] );
60
61         a->a_nvals = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
62         a->a_nvals[ 0 ] = nval;
63         BER_BVZERO( &a->a_nvals[ 1 ] );
64         
65         a->a_next = NULL;
66         a->a_flags = 0;
67
68         return a;
69 }
70
71 Attribute *
72 backsql_operational_entryCSN( Operation *op )
73 {
74         char            csnbuf[ LDAP_LUTIL_CSNSTR_BUFSIZE ];
75         struct berval   entryCSN;
76         Attribute       *a;
77
78         a = ch_malloc( sizeof( Attribute ) );
79         a->a_desc = slap_schema.si_ad_entryCSN;
80         a->a_vals = ch_malloc( 2 * sizeof( struct berval ) );
81         BER_BVZERO( &a->a_vals[ 1 ] );
82
83 #ifdef BACKSQL_SYNCPROV
84         if ( op->o_sync && op->o_tag == LDAP_REQ_SEARCH ) {
85                 assert( op->o_private );
86
87                 entryCSN = *((struct berval *)op->o_private);
88
89         } else
90 #endif /* BACKSQL_SYNCPROV */
91         {
92                 slap_get_csn( op, csnbuf, sizeof(csnbuf), &entryCSN, 0 );
93         }
94
95         ber_dupbv( &a->a_vals[ 0 ], &entryCSN );
96
97         a->a_nvals = a->a_vals;
98
99         a->a_next = NULL;
100         a->a_flags = 0;
101
102         return a;
103 }
104
105 int
106 backsql_operational(
107         Operation       *op,
108         SlapReply       *rs )
109 {
110
111         backsql_info    *bi = (backsql_info*)op->o_bd->be_private;
112         SQLHDBC         dbh = SQL_NULL_HDBC;
113         int             rc = 0;
114         Attribute       **ap;
115         enum {
116                 BACKSQL_OP_HASSUBORDINATES = 0,
117                 BACKSQL_OP_ENTRYUUID,
118                 BACKSQL_OP_ENTRYCSN,
119
120                 BACKSQL_OP_LAST
121         };
122         int             get_conn = BACKSQL_OP_LAST,
123                         got[ BACKSQL_OP_LAST ] = { 0 };
124
125         Debug( LDAP_DEBUG_TRACE, "==>backsql_operational(): entry \"%s\"\n",
126                         rs->sr_entry->e_nname.bv_val, 0, 0 );
127
128         for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next ) {
129                 if ( (*ap)->a_desc == slap_schema.si_ad_hasSubordinates ) {
130                         get_conn--;
131                         got[ BACKSQL_OP_HASSUBORDINATES ] = 1;
132
133                 } else if ( (*ap)->a_desc == slap_schema.si_ad_entryUUID ) {
134                         get_conn--;
135                         got[ BACKSQL_OP_ENTRYUUID ] = 1;
136
137                 } else if ( (*ap)->a_desc == slap_schema.si_ad_entryCSN ) {
138                         get_conn--;
139                         got[ BACKSQL_OP_ENTRYCSN ] = 1;
140                 }
141         }
142
143         if ( !get_conn ) {
144                 return 0;
145         }
146
147         rc = backsql_get_db_conn( op, &dbh );
148         if ( rc != LDAP_SUCCESS ) {
149                 Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
150                         "could not get connection handle - exiting\n", 
151                         0, 0, 0 );
152                 return 1;
153         }
154
155         if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) ) 
156                         && !got[ BACKSQL_OP_HASSUBORDINATES ]
157                         && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL )
158         {
159                 rc = backsql_has_children( bi, dbh, &rs->sr_entry->e_nname );
160
161                 switch( rc ) {
162                 case LDAP_COMPARE_TRUE:
163                 case LDAP_COMPARE_FALSE:
164                         *ap = slap_operational_hasSubordinate( rc == LDAP_COMPARE_TRUE );
165                         assert( *ap );
166                         ap = &(*ap)->a_next;
167                         rc = 0;
168                         break;
169
170                 default:
171                         Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
172                                 "has_children failed( %d)\n", rc, 0, 0 );
173                         return 1;
174                 }
175         }
176
177         if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_entryUUID, rs->sr_attrs ) ) 
178                         && !got[ BACKSQL_OP_ENTRYUUID ]
179                         && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryUUID ) == NULL )
180         {
181                 backsql_srch_info       bsi;
182
183                 rc = backsql_init_search( &bsi, &rs->sr_entry->e_nname,
184                                 LDAP_SCOPE_BASE, -1, -1, -1, NULL,
185                                 dbh, op, rs, NULL,
186                                 ( BACKSQL_ISF_GET_ID | BACKSQL_ISF_MUCK ) );
187                 if ( rc != LDAP_SUCCESS ) {
188                         Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
189                                 "could not retrieve entry ID - no such entry\n", 
190                                 0, 0, 0 );
191                         return 1;
192                 }
193
194                 *ap = backsql_operational_entryUUID( bi, &bsi.bsi_base_id );
195
196                 (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
197
198                 if ( *ap == NULL ) {
199                         Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
200                                 "could not retrieve entryUUID\n", 
201                                 0, 0, 0 );
202                         return 1;
203                 }
204
205                 ap = &(*ap)->a_next;
206         }
207
208         if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_entryCSN, rs->sr_attrs ) ) 
209                         && !got[ BACKSQL_OP_ENTRYCSN ]
210                         && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryCSN ) == NULL )
211         {
212                 *ap = backsql_operational_entryCSN( op );
213                 if ( *ap == NULL ) {
214                         Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
215                                 "could not retrieve entryCSN\n", 
216                                 0, 0, 0 );
217                         return 1;
218                 }
219
220                 ap = &(*ap)->a_next;
221         }
222
223         Debug( LDAP_DEBUG_TRACE, "<==backsql_operational(%d)\n", rc, 0, 0);
224
225         return rc;
226 }
227