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