1 /* $NetBSD: operational.c,v 1.1.1.3 2010/12/12 15:23:25 adam Exp $ */ 2 3 /* OpenLDAP: pkg/ldap/servers/slapd/back-sql/operational.c,v 1.21.2.8 2010/04/19 16:53:04 quanah Exp */ 4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 5 * 6 * Copyright 1999-2010 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_operational_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 if ( !get_conn ) { 144 return 0; 145 } 146 147 rc = backsql_get_db_conn( op, &dbh ); 148 if ( rc != LDAP_SUCCESS ) { 149 Debug( LDAP_DEBUG_TRACE, "backsql_operational(): " 150 "could not get connection handle - exiting\n", 151 0, 0, 0 ); 152 return 1; 153 } 154 155 if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) ) 156 && !got[ BACKSQL_OP_HASSUBORDINATES ] 157 && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL ) 158 { 159 rc = backsql_has_children( op, dbh, &rs->sr_entry->e_nname ); 160 161 switch( rc ) { 162 case LDAP_COMPARE_TRUE: 163 case LDAP_COMPARE_FALSE: 164 *ap = slap_operational_hasSubordinate( rc == LDAP_COMPARE_TRUE ); 165 assert( *ap != NULL ); 166 ap = &(*ap)->a_next; 167 rc = 0; 168 break; 169 170 default: 171 Debug( LDAP_DEBUG_TRACE, "backsql_operational(): " 172 "has_children failed( %d)\n", rc, 0, 0 ); 173 return 1; 174 } 175 } 176 177 if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_entryUUID, rs->sr_attrs ) ) 178 && !got[ BACKSQL_OP_ENTRYUUID ] 179 && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryUUID ) == NULL ) 180 { 181 backsql_srch_info bsi = { 0 }; 182 183 rc = backsql_init_search( &bsi, &rs->sr_entry->e_nname, 184 LDAP_SCOPE_BASE, 185 (time_t)(-1), NULL, dbh, op, rs, NULL, 186 BACKSQL_ISF_GET_ID ); 187 if ( rc != LDAP_SUCCESS ) { 188 Debug( LDAP_DEBUG_TRACE, "backsql_operational(): " 189 "could not retrieve entry ID - no such entry\n", 190 0, 0, 0 ); 191 return 1; 192 } 193 194 *ap = backsql_operational_entryUUID( bi, &bsi.bsi_base_id ); 195 196 (void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx ); 197 198 if ( bsi.bsi_attrs != NULL ) { 199 op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx ); 200 } 201 202 if ( *ap == NULL ) { 203 Debug( LDAP_DEBUG_TRACE, "backsql_operational(): " 204 "could not retrieve entryUUID\n", 205 0, 0, 0 ); 206 return 1; 207 } 208 209 ap = &(*ap)->a_next; 210 } 211 212 if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_entryCSN, rs->sr_attrs ) ) 213 && !got[ BACKSQL_OP_ENTRYCSN ] 214 && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryCSN ) == NULL ) 215 { 216 *ap = backsql_operational_entryCSN( op ); 217 if ( *ap == NULL ) { 218 Debug( LDAP_DEBUG_TRACE, "backsql_operational(): " 219 "could not retrieve entryCSN\n", 220 0, 0, 0 ); 221 return 1; 222 } 223 224 ap = &(*ap)->a_next; 225 } 226 227 Debug( LDAP_DEBUG_TRACE, "<==backsql_operational(%d)\n", rc, 0, 0); 228 229 return rc; 230 } 231 232