]> git.sur5r.net Git - openldap/blob - servers/slapd/back-sql/operational.c
minor cleanup
[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         slap_get_csn( op, csnbuf, sizeof(csnbuf), &entryCSN, 0 );
84         ber_dupbv( &a->a_vals[ 0 ], &entryCSN );
85
86         a->a_nvals = a->a_vals;
87
88         a->a_next = NULL;
89         a->a_flags = 0;
90
91         return a;
92 }
93
94 int
95 backsql_operational(
96         Operation       *op,
97         SlapReply       *rs )
98 {
99
100         backsql_info    *bi = (backsql_info*)op->o_bd->be_private;
101         SQLHDBC         dbh = SQL_NULL_HDBC;
102         int             rc = 0;
103         Attribute       **ap;
104         enum {
105                 BACKSQL_OP_HASSUBORDINATES = 0,
106                 BACKSQL_OP_ENTRYUUID,
107                 BACKSQL_OP_ENTRYCSN,
108
109                 BACKSQL_OP_LAST
110         };
111         int             get_conn = BACKSQL_OP_LAST,
112                         got[ BACKSQL_OP_LAST ] = { 0 };
113
114         Debug( LDAP_DEBUG_TRACE, "==>backsql_operational(): entry \"%s\"\n",
115                         rs->sr_entry->e_nname.bv_val, 0, 0 );
116
117         for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next ) {
118                 if ( (*ap)->a_desc == slap_schema.si_ad_hasSubordinates ) {
119                         get_conn--;
120                         got[ BACKSQL_OP_HASSUBORDINATES ] = 1;
121
122                 } else if ( (*ap)->a_desc == slap_schema.si_ad_entryUUID ) {
123                         get_conn--;
124                         got[ BACKSQL_OP_ENTRYUUID ] = 1;
125
126                 } else if ( (*ap)->a_desc == slap_schema.si_ad_entryCSN ) {
127                         get_conn--;
128                         got[ BACKSQL_OP_ENTRYCSN ] = 1;
129                 }
130         }
131
132         if ( !get_conn ) {
133                 return 0;
134         }
135
136         rc = backsql_get_db_conn( op, &dbh );
137         if ( rc != LDAP_SUCCESS ) {
138                 Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
139                         "could not get connection handle - exiting\n", 
140                         0, 0, 0 );
141                 return 1;
142         }
143
144         if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) ) 
145                         && !got[ BACKSQL_OP_HASSUBORDINATES ]
146                         && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL )
147         {
148                 rc = backsql_has_children( bi, dbh, &rs->sr_entry->e_nname );
149
150                 switch( rc ) {
151                 case LDAP_COMPARE_TRUE:
152                 case LDAP_COMPARE_FALSE:
153                         *ap = slap_operational_hasSubordinate( rc == LDAP_COMPARE_TRUE );
154                         assert( *ap );
155                         ap = &(*ap)->a_next;
156                         rc = 0;
157                         break;
158
159                 default:
160                         Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
161                                 "has_children failed( %d)\n", rc, 0, 0 );
162                         return 1;
163                 }
164         }
165
166         if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_entryUUID, rs->sr_attrs ) ) 
167                         && !got[ BACKSQL_OP_ENTRYUUID ]
168                         && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryUUID ) == NULL )
169         {
170                 struct berval           ndn;
171                 backsql_srch_info       bsi;
172
173                 ndn = rs->sr_entry->e_nname;
174                 if ( backsql_api_dn2odbc( op, rs, &ndn ) ) {
175                         Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
176                                 "backsql_api_dn2odbc failed\n", 
177                                 0, 0, 0 );
178                         return 1;
179                 }
180
181                 rc = backsql_init_search( &bsi, &ndn, LDAP_SCOPE_BASE, 
182                         -1, -1, -1, NULL, dbh, op, rs, NULL, 1 );
183                 if ( rc != LDAP_SUCCESS ) {
184                         Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
185                                 "could not retrieve entry ID - no such entry\n", 
186                                 0, 0, 0 );
187                         return 1;
188                 }
189
190                 *ap = backsql_operational_entryUUID( bi, &bsi.bsi_base_id );
191
192                 (void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
193
194                 if ( ndn.bv_val != rs->sr_entry->e_nname.bv_val ) {
195                         free( ndn.bv_val );
196                 }
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