operational.c revision 1.1.1.4
1/*	$NetBSD: operational.c,v 1.1.1.4 2014/05/28 09:58:51 tron Exp $	*/
2
3/* $OpenLDAP$ */
4/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 *
6 * Copyright 1999-2014 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 "portable.h"
26
27#include <stdio.h>
28#include <sys/types.h>
29
30#include "slap.h"
31#include "proto-sql.h"
32#include "lutil.h"
33
34/*
35 * sets the supported operational attributes (if required)
36 */
37
38Attribute *
39backsql_operational_entryUUID( backsql_info *bi, backsql_entryID *id )
40{
41	int			rc;
42	struct berval		val, nval;
43	AttributeDescription	*desc = slap_schema.si_ad_entryUUID;
44	Attribute		*a;
45
46	backsql_entryUUID( bi, id, &val, NULL );
47
48	rc = (*desc->ad_type->sat_equality->smr_normalize)(
49			SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
50			desc->ad_type->sat_syntax,
51			desc->ad_type->sat_equality,
52			&val, &nval, NULL );
53	if ( rc != LDAP_SUCCESS ) {
54		ber_memfree( val.bv_val );
55		return NULL;
56	}
57
58	a = attr_alloc( desc );
59
60	a->a_numvals = 1;
61	a->a_vals = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
62	a->a_vals[ 0 ] = val;
63	BER_BVZERO( &a->a_vals[ 1 ] );
64
65	a->a_nvals = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
66	a->a_nvals[ 0 ] = nval;
67	BER_BVZERO( &a->a_nvals[ 1 ] );
68
69	return a;
70}
71
72Attribute *
73backsql_operational_entryCSN( Operation *op )
74{
75	char		csnbuf[ LDAP_PVT_CSNSTR_BUFSIZE ];
76	struct berval	entryCSN;
77	Attribute	*a;
78
79	a = attr_alloc( slap_schema.si_ad_entryCSN );
80	a->a_numvals = 1;
81	a->a_vals = ch_malloc( 2 * sizeof( struct berval ) );
82	BER_BVZERO( &a->a_vals[ 1 ] );
83
84#ifdef BACKSQL_SYNCPROV
85	if ( op->o_sync && op->o_tag == LDAP_REQ_SEARCH && op->o_private != NULL ) {
86		assert( op->o_private != NULL );
87
88		entryCSN = *((struct berval *)op->o_private);
89
90	} else
91#endif /* BACKSQL_SYNCPROV */
92	{
93		entryCSN.bv_val = csnbuf;
94		entryCSN.bv_len = sizeof( csnbuf );
95		slap_get_csn( op, &entryCSN, 0 );
96	}
97
98	ber_dupbv( &a->a_vals[ 0 ], &entryCSN );
99
100	a->a_nvals = a->a_vals;
101
102	return a;
103}
104
105int
106backsql_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_entry->e_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	for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next ) {
144		if ( !got[ BACKSQL_OP_HASSUBORDINATES ] &&
145			(*ap)->a_desc == slap_schema.si_ad_hasSubordinates )
146		{
147			get_conn--;
148			got[ BACKSQL_OP_HASSUBORDINATES ] = 1;
149
150		} else if ( !got[ BACKSQL_OP_ENTRYUUID ] &&
151			(*ap)->a_desc == slap_schema.si_ad_entryUUID )
152		{
153			get_conn--;
154			got[ BACKSQL_OP_ENTRYUUID ] = 1;
155
156		} else if ( !got[ BACKSQL_OP_ENTRYCSN ] &&
157			(*ap)->a_desc == slap_schema.si_ad_entryCSN )
158		{
159			get_conn--;
160			got[ BACKSQL_OP_ENTRYCSN ] = 1;
161		}
162	}
163
164	if ( !get_conn ) {
165		return 0;
166	}
167
168	rc = backsql_get_db_conn( op, &dbh );
169	if ( rc != LDAP_SUCCESS ) {
170		Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
171			"could not get connection handle - exiting\n",
172			0, 0, 0 );
173		return 1;
174	}
175
176	if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) )
177			&& !got[ BACKSQL_OP_HASSUBORDINATES ]
178			&& attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL )
179	{
180		rc = backsql_has_children( op, dbh, &rs->sr_entry->e_nname );
181
182		switch( rc ) {
183		case LDAP_COMPARE_TRUE:
184		case LDAP_COMPARE_FALSE:
185			*ap = slap_operational_hasSubordinate( rc == LDAP_COMPARE_TRUE );
186			assert( *ap != NULL );
187			ap = &(*ap)->a_next;
188			rc = 0;
189			break;
190
191		default:
192			Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
193				"has_children failed( %d)\n", rc, 0, 0 );
194			return 1;
195		}
196	}
197
198	if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_entryUUID, rs->sr_attrs ) )
199			&& !got[ BACKSQL_OP_ENTRYUUID ]
200			&& attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryUUID ) == NULL )
201	{
202		backsql_srch_info	bsi = { 0 };
203
204		rc = backsql_init_search( &bsi, &rs->sr_entry->e_nname,
205				LDAP_SCOPE_BASE,
206				(time_t)(-1), NULL, dbh, op, rs, NULL,
207				BACKSQL_ISF_GET_ID );
208		if ( rc != LDAP_SUCCESS ) {
209			Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
210				"could not retrieve entry ID - no such entry\n",
211				0, 0, 0 );
212			return 1;
213		}
214
215		*ap = backsql_operational_entryUUID( bi, &bsi.bsi_base_id );
216
217		(void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx );
218
219		if ( bsi.bsi_attrs != NULL ) {
220			op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx );
221		}
222
223		if ( *ap == NULL ) {
224			Debug( LDAP_DEBUG_TRACE, "backsql_operational(): "
225				"could not retrieve entryUUID\n",
226				0, 0, 0 );
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				0, 0, 0 );
242			return 1;
243		}
244
245		ap = &(*ap)->a_next;
246	}
247
248	Debug( LDAP_DEBUG_TRACE, "<==backsql_operational(%d)\n", rc, 0, 0);
249
250	return rc;
251}
252
253