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