xref: /netbsd-src/external/bsd/openldap/dist/servers/slapd/back-sql/operational.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
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 
38 Attribute *
39 backsql_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 
72 Attribute *
73 backsql_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 
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_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