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