int backsql_operational( Operation *op, SlapReply *rs ) { backsql_info *bi = (backsql_info*)op->o_bd->be_private; SQLHDBC dbh = SQL_NULL_HDBC; int rc = 0; Attribute **ap; enum { BACKSQL_OP_HASSUBORDINATES = 0, BACKSQL_OP_ENTRYUUID, BACKSQL_OP_ENTRYCSN, BACKSQL_OP_LAST }; int get_conn = BACKSQL_OP_LAST, got[ BACKSQL_OP_LAST ] = { 0 }; Debug( LDAP_DEBUG_TRACE, "==>backsql_operational(): entry \"%s\"\n", rs->sr_entry->e_nname.bv_val, 0, 0 ); for ( ap = &rs->sr_entry->e_attrs; *ap; ap = &(*ap)->a_next ) { if ( (*ap)->a_desc == slap_schema.si_ad_hasSubordinates ) { get_conn--; got[ BACKSQL_OP_HASSUBORDINATES ] = 1; } else if ( (*ap)->a_desc == slap_schema.si_ad_entryUUID ) { get_conn--; got[ BACKSQL_OP_ENTRYUUID ] = 1; } else if ( (*ap)->a_desc == slap_schema.si_ad_entryCSN ) { get_conn--; got[ BACKSQL_OP_ENTRYCSN ] = 1; } } for ( ap = &rs->sr_operational_attrs; *ap; ap = &(*ap)->a_next ) { if ( !got[ BACKSQL_OP_HASSUBORDINATES ] && (*ap)->a_desc == slap_schema.si_ad_hasSubordinates ) { get_conn--; got[ BACKSQL_OP_HASSUBORDINATES ] = 1; } else if ( !got[ BACKSQL_OP_ENTRYUUID ] && (*ap)->a_desc == slap_schema.si_ad_entryUUID ) { get_conn--; got[ BACKSQL_OP_ENTRYUUID ] = 1; } else if ( !got[ BACKSQL_OP_ENTRYCSN ] && (*ap)->a_desc == slap_schema.si_ad_entryCSN ) { get_conn--; got[ BACKSQL_OP_ENTRYCSN ] = 1; } } if ( !get_conn ) { return 0; } rc = backsql_get_db_conn( op, &dbh ); if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_operational(): " "could not get connection handle - exiting\n", 0, 0, 0 ); return 1; } if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_hasSubordinates, rs->sr_attrs ) ) && !got[ BACKSQL_OP_HASSUBORDINATES ] && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_hasSubordinates ) == NULL ) { rc = backsql_has_children( op, dbh, &rs->sr_entry->e_nname ); switch( rc ) { case LDAP_COMPARE_TRUE: case LDAP_COMPARE_FALSE: *ap = slap_operational_hasSubordinate( rc == LDAP_COMPARE_TRUE ); assert( *ap != NULL ); ap = &(*ap)->a_next; rc = 0; break; default: Debug( LDAP_DEBUG_TRACE, "backsql_operational(): " "has_children failed( %d)\n", rc, 0, 0 ); return 1; } } if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_entryUUID, rs->sr_attrs ) ) && !got[ BACKSQL_OP_ENTRYUUID ] && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryUUID ) == NULL ) { backsql_srch_info bsi = { 0 }; rc = backsql_init_search( &bsi, &rs->sr_entry->e_nname, LDAP_SCOPE_BASE, (time_t)(-1), NULL, dbh, op, rs, NULL, BACKSQL_ISF_GET_ID ); if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_operational(): " "could not retrieve entry ID - no such entry\n", 0, 0, 0 ); return 1; } *ap = backsql_operational_entryUUID( bi, &bsi.bsi_base_id ); (void)backsql_free_entryID( &bsi.bsi_base_id, 0, op->o_tmpmemctx ); if ( bsi.bsi_attrs != NULL ) { op->o_tmpfree( bsi.bsi_attrs, op->o_tmpmemctx ); } if ( *ap == NULL ) { Debug( LDAP_DEBUG_TRACE, "backsql_operational(): " "could not retrieve entryUUID\n", 0, 0, 0 ); return 1; } ap = &(*ap)->a_next; } if ( ( SLAP_OPATTRS( rs->sr_attr_flags ) || ad_inlist( slap_schema.si_ad_entryCSN, rs->sr_attrs ) ) && !got[ BACKSQL_OP_ENTRYCSN ] && attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryCSN ) == NULL ) { *ap = backsql_operational_entryCSN( op ); if ( *ap == NULL ) { Debug( LDAP_DEBUG_TRACE, "backsql_operational(): " "could not retrieve entryCSN\n", 0, 0, 0 ); return 1; } ap = &(*ap)->a_next; } Debug( LDAP_DEBUG_TRACE, "<==backsql_operational(%d)\n", rc, 0, 0); return rc; }
int backsql_id2entry( backsql_srch_info *bsi, backsql_entryID *eid ) { Operation *op = bsi->bsi_op; backsql_info *bi = (backsql_info *)op->o_bd->be_private; int i; int rc; Debug( LDAP_DEBUG_TRACE, "==>backsql_id2entry()\n", 0, 0, 0 ); assert( bsi->bsi_e != NULL ); memset( bsi->bsi_e, 0, sizeof( Entry ) ); if ( bi->sql_baseObject && BACKSQL_IS_BASEOBJECT_ID( &eid->eid_id ) ) { Entry *e; e = entry_dup( bi->sql_baseObject ); if ( e == NULL ) { return LDAP_NO_MEMORY; } *bsi->bsi_e = *e; free( e ); goto done; } ber_dupbv_x( &bsi->bsi_e->e_name, &eid->eid_dn, op->o_tmpmemctx ); ber_dupbv_x( &bsi->bsi_e->e_nname, &eid->eid_ndn, op->o_tmpmemctx ); bsi->bsi_e->e_attrs = NULL; bsi->bsi_e->e_private = NULL; if ( eid->eid_oc == NULL ) { eid->eid_oc = backsql_id2oc( bsi->bsi_op->o_bd->be_private, eid->eid_oc_id ); } bsi->bsi_oc = eid->eid_oc; bsi->bsi_c_eid = eid; #ifndef BACKSQL_ARBITRARY_KEY /* FIXME: unused */ bsi->bsi_e->e_id = eid->eid_id; #endif /* ! BACKSQL_ARBITRARY_KEY */ rc = attr_merge_normalize_one( bsi->bsi_e, slap_schema.si_ad_objectClass, &bsi->bsi_oc->bom_oc->soc_cname, bsi->bsi_op->o_tmpmemctx ); if ( rc != LDAP_SUCCESS ) { backsql_entry_clean( op, bsi->bsi_e ); return rc; } if ( bsi->bsi_attrs == NULL || ( bsi->bsi_flags & BSQL_SF_ALL_USER ) ) { Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): " "retrieving all attributes\n", 0, 0, 0 ); avl_apply( bsi->bsi_oc->bom_attrs, backsql_get_attr_vals, bsi, 0, AVL_INORDER ); } else { Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): " "custom attribute list\n", 0, 0, 0 ); for ( i = 0; !BER_BVISNULL( &bsi->bsi_attrs[ i ].an_name ); i++ ) { backsql_at_map_rec **vat; AttributeName *an = &bsi->bsi_attrs[ i ]; int j; /* if one of the attributes listed here is * a subtype of another, it must be ignored, * because subtypes are already dealt with * by backsql_supad2at() */ for ( j = 0; !BER_BVISNULL( &bsi->bsi_attrs[ j ].an_name ); j++ ) { /* skip self */ if ( j == i ) { continue; } /* skip subtypes */ if ( is_at_subtype( an->an_desc->ad_type, bsi->bsi_attrs[ j ].an_desc->ad_type ) ) { goto next; } } rc = backsql_supad2at( bsi->bsi_oc, an->an_desc, &vat ); if ( rc != 0 || vat == NULL ) { Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(): " "attribute \"%s\" is not defined " "for objectlass \"%s\"\n", an->an_name.bv_val, BACKSQL_OC_NAME( bsi->bsi_oc ), 0 ); continue; } for ( j = 0; vat[j]; j++ ) { backsql_get_attr_vals( vat[j], bsi ); } ch_free( vat ); next:; } } if ( bsi->bsi_flags & BSQL_SF_RETURN_ENTRYUUID ) { Attribute *a_entryUUID, **ap; a_entryUUID = backsql_operational_entryUUID( bi, eid ); if ( a_entryUUID != NULL ) { for ( ap = &bsi->bsi_e->e_attrs; *ap; ap = &(*ap)->a_next ); *ap = a_entryUUID; } } if ( ( bsi->bsi_flags & BSQL_SF_ALL_OPER ) || an_find( bsi->bsi_attrs, slap_bv_all_operational_attrs ) || an_find( bsi->bsi_attrs, &slap_schema.si_ad_structuralObjectClass->ad_cname ) ) { ObjectClass *soc = NULL; if ( BACKSQL_CHECK_SCHEMA( bi ) ) { Attribute *a; const char *text = NULL; char textbuf[ 1024 ]; size_t textlen = sizeof( textbuf ); struct berval bv[ 2 ], *nvals; int rc = LDAP_SUCCESS; a = attr_find( bsi->bsi_e->e_attrs, slap_schema.si_ad_objectClass ); if ( a != NULL ) { nvals = a->a_nvals; } else { bv[ 0 ] = bsi->bsi_oc->bom_oc->soc_cname; BER_BVZERO( &bv[ 1 ] ); nvals = bv; } rc = structural_class( nvals, &soc, NULL, &text, textbuf, textlen, op->o_tmpmemctx ); if ( rc != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): " "structural_class() failed %d (%s)\n", bsi->bsi_e->e_name.bv_val, rc, text ? text : "" ); backsql_entry_clean( op, bsi->bsi_e ); return rc; } if ( !bvmatch( &soc->soc_cname, &bsi->bsi_oc->bom_oc->soc_cname ) ) { if ( !is_object_subclass( bsi->bsi_oc->bom_oc, soc ) ) { Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): " "computed structuralObjectClass %s " "does not match objectClass %s associated " "to entry\n", bsi->bsi_e->e_name.bv_val, soc->soc_cname.bv_val, bsi->bsi_oc->bom_oc->soc_cname.bv_val ); backsql_entry_clean( op, bsi->bsi_e ); return rc; } Debug( LDAP_DEBUG_TRACE, "backsql_id2entry(%s): " "computed structuralObjectClass %s " "is subclass of objectClass %s associated " "to entry\n", bsi->bsi_e->e_name.bv_val, soc->soc_cname.bv_val, bsi->bsi_oc->bom_oc->soc_cname.bv_val ); } } else { soc = bsi->bsi_oc->bom_oc; } rc = attr_merge_normalize_one( bsi->bsi_e, slap_schema.si_ad_structuralObjectClass, &soc->soc_cname, bsi->bsi_op->o_tmpmemctx ); if ( rc != LDAP_SUCCESS ) { backsql_entry_clean( op, bsi->bsi_e ); return rc; } } done:; Debug( LDAP_DEBUG_TRACE, "<==backsql_id2entry()\n", 0, 0, 0 ); return LDAP_SUCCESS; }