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