SQLUSMALLINT pno, po;
/* procedure return code */
int prc;
-
+
#ifdef BACKSQL_REALLOC_STMT
SQLAllocStmt( dbh, &sth );
#endif /* BACKSQL_REALLOC_STMT */
for ( i = 0, at_val = c_mod->sm_values;
at_val->bv_val != NULL;
i++, at_val++ ) {
+
+ rc = backsql_Prepare( dbh, &sth, at->bam_add_proc, 0 );
+ if ( rc != SQL_SUCCESS ) {
+ Debug( LDAP_DEBUG_TRACE,
+ " backsql_modify_internal(): "
+ "error preparing add query\n",
+ 0, 0, 0 );
+ backsql_PrintErrors( bi->db_env, dbh, sth, rc );
+
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "SQL-backend error";
+ goto done;
+ }
+
if ( BACKSQL_IS_ADD( at->bam_expect_return ) ) {
pno = 1;
SQLBindParameter( sth, 1,
" backsql_modify_internal(): "
"executing \"%s\"\n",
at->bam_add_proc, 0, 0 );
- rc = SQLExecDirect( sth, at->bam_add_proc,
- SQL_NTS );
+ rc = SQLExecute( sth );
if ( rc != SQL_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
" backsql_modify_internal(): "
SQLUSMALLINT pno, po;
/* procedure return code */
int prc;
- struct berval realdn, realpdn;
+ struct berval realdn = BER_BVNULL,
+ realpdn = BER_BVNULL;
Debug( LDAP_DEBUG_TRACE, "==>backsql_add(\"%s\")\n",
op->oq_add.rs_e->e_name.bv_val, 0, 0 );
}
/*
- * Check if parent exists
+ * Get the parent dn and see if the corresponding entry exists.
*/
- dnParent( &op->oq_add.rs_e->e_name, &pdn );
+ if ( be_issuffix( op->o_bd, &op->oq_add.rs_e->e_nname ) ) {
+ pdn = slap_empty_bv;
+ } else {
+ dnParent( &op->oq_add.rs_e->e_nname, &pdn );
+ }
+
realpdn = pdn;
if ( backsql_api_dn2odbc( op, rs, &realpdn ) ) {
Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): "
}
/*
- * Look for matched
+ * no parent!
+ * if not attempting to add entry at suffix or with parent ""
*/
- while ( 1 ) {
- struct berval dn;
- char *matched = NULL;
-
- if ( realpdn.bv_val != pdn.bv_val ) {
- ch_free( realpdn.bv_val );
- }
-
- dn = pdn;
- dnParent( &dn, &pdn );
-
+ if ( ( ( !be_isroot( op ) && !be_shadow_update( op ) )
+ || pdn.bv_len > 0 ) && !is_entry_glue( op->oq_add.rs_e ) )
+ {
+ Debug( LDAP_DEBUG_TRACE, " backsql_add: %s denied\n",
+ pdn.bv_len == 0 ? "suffix" : "entry at root",
+ 0, 0 );
/*
- * Empty DN ("") defaults to LDAP_SUCCESS
+ * Look for matched
*/
- realpdn = pdn;
- if ( backsql_api_dn2odbc( op, rs, &realpdn ) ) {
- Debug( LDAP_DEBUG_TRACE,
- " backsql_add(\"%s\"): "
- "backsql_api_dn2odbc failed\n",
- op->oq_add.rs_e->e_name.bv_val, 0, 0 );
- rs->sr_err = LDAP_OTHER;
- rs->sr_text = "SQL-backend error";
- goto done;
+ while ( 1 ) {
+ struct berval dn;
+ char *matched = NULL;
+
+ if ( realpdn.bv_val != pdn.bv_val ) {
+ ch_free( realpdn.bv_val );
+ }
+
+ dn = pdn;
+ dnParent( &dn, &pdn );
+
+ /*
+ * Empty DN ("") defaults to LDAP_SUCCESS
+ */
+ realpdn = pdn;
+ if ( backsql_api_dn2odbc( op, rs, &realpdn ) ) {
+ Debug( LDAP_DEBUG_TRACE,
+ " backsql_add(\"%s\"): "
+ "backsql_api_dn2odbc failed\n",
+ op->oq_add.rs_e->e_name.bv_val, 0, 0 );
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "SQL-backend error";
+ goto done;
+ }
+
+ rs->sr_err = backsql_dn2id( bi, NULL, dbh, &realpdn );
+ switch ( rs->sr_err ) {
+ case LDAP_NO_SUCH_OBJECT:
+ if ( pdn.bv_len > 0 ) {
+ break;
+ }
+ /* fail over to next case */
+
+ case LDAP_SUCCESS:
+ matched = pdn.bv_val;
+ /* fail over to next case */
+
+ default:
+ rs->sr_err = LDAP_NO_SUCH_OBJECT;
+ rs->sr_matched = matched;
+ goto done;
+ }
}
+ } else {
- rs->sr_err = backsql_dn2id( bi, NULL, dbh, &realpdn );
- switch ( rs->sr_err ) {
- case LDAP_NO_SUCH_OBJECT:
- if ( pdn.bv_len > 0 ) {
- break;
- }
- /* fail over to next case */
-
- case LDAP_SUCCESS:
- matched = pdn.bv_val;
- /* fail over to next case */
-
- default:
- rs->sr_err = LDAP_NO_SUCH_OBJECT;
- rs->sr_matched = matched;
- goto done;
- }
+#ifdef BACKSQL_ARBITRARY_KEY
+ ber_str2bv( "SUFFIX", 0, 1, &parent_id.eid_id );
+#else /* ! BACKSQL_ARBITRARY_KEY */
+ parent_id.eid_id = 0;
+#endif /* ! BACKSQL_ARBITRARY_KEY */
+ rs->sr_err = LDAP_SUCCESS;
}
}
- /*
- * create_proc is executed; if expect_return is set, then
- * an output parameter is bound, which should contain
- * the id of the added row; otherwise the procedure
- * is expected to return the id as the first column of a select
- */
-
+ /* check "children" pseudo-attribute access to parent */
p.e_attrs = NULL;
p.e_name = pdn;
dnParent( &op->oq_add.rs_e->e_nname, &p.e_nname );
goto done;
}
+ /*
+ * create_proc is executed; if expect_return is set, then
+ * an output parameter is bound, which should contain
+ * the id of the added row; otherwise the procedure
+ * is expected to return the id as the first column of a select
+ */
+
rc = SQLAllocStmt( dbh, &sth );
if ( rc != SQL_SUCCESS ) {
rs->sr_err = LDAP_OTHER;
continue;
}
+ for ( i = 0, at_val = &at->a_vals[ i ];
+ at_val->bv_val != NULL;
+ i++, at_val = &at->a_vals[ i ] )
+ {
+ char logbuf[] = "val[18446744073709551615UL], id=18446744073709551615UL";
+
#ifdef BACKSQL_REALLOC_STMT
- rc = backsql_Prepare( dbh, &sth, at_rec->bam_add_proc, 0 );
- if ( rc != SQL_SUCCESS ) {
+ rc = backsql_Prepare( dbh, &sth, at_rec->bam_add_proc, 0 );
+ if ( rc != SQL_SUCCESS ) {
- if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
- rs->sr_err = LDAP_OTHER;
- rs->sr_text = "SQL-backend error";
- goto done;
- }
+ if ( BACKSQL_FAIL_IF_NO_MAPPING( bi ) ) {
+ rs->sr_err = LDAP_OTHER;
+ rs->sr_text = "SQL-backend error";
+ goto done;
+ }
- continue;
- }
+ goto next_attr;
+ }
#endif /* BACKSQL_REALLOC_STMT */
- if ( BACKSQL_IS_ADD( at_rec->bam_expect_return ) ) {
- pno = 1;
- SQLBindParameter( sth, 1, SQL_PARAM_OUTPUT,
- SQL_C_ULONG, SQL_INTEGER,
- 0, 0, &prc, 0, 0 );
- } else {
- pno = 0;
- }
-
- po = ( BACKSQL_IS_ADD( at_rec->bam_param_order ) ) > 0;
- currpos = pno + 1 + po;
- SQLBindParameter( sth, currpos,
- SQL_PARAM_INPUT, SQL_C_ULONG,
- SQL_INTEGER, 0, 0, &new_keyval, 0, 0 );
- currpos = pno + 2 - po;
+ if ( BACKSQL_IS_ADD( at_rec->bam_expect_return ) ) {
+ pno = 1;
+ SQLBindParameter( sth, 1, SQL_PARAM_OUTPUT,
+ SQL_C_ULONG, SQL_INTEGER,
+ 0, 0, &prc, 0, 0 );
+ } else {
+ pno = 0;
+ }
- for ( i = 0, at_val = &at->a_vals[ i ];
- at_val->bv_val != NULL;
- i++, at_val = &at->a_vals[ i ] ) {
- char logbuf[] = "val[18446744073709551615UL], id=18446744073709551615UL";
+ po = ( BACKSQL_IS_ADD( at_rec->bam_param_order ) ) > 0;
+ currpos = pno + 1 + po;
+ SQLBindParameter( sth, currpos,
+ SQL_PARAM_INPUT, SQL_C_ULONG,
+ SQL_INTEGER, 0, 0, &new_keyval, 0, 0 );
+ currpos = pno + 2 - po;
/*
* Do not deal with the objectClass that is used
goto done;
}
}
- }
#ifndef BACKSQL_REALLOC_STMT
- SQLFreeStmt( sth, SQL_RESET_PARAMS );
+ SQLFreeStmt( sth, SQL_RESET_PARAMS );
#else /* BACKSQL_REALLOC_STMT */
- SQLFreeStmt( sth, SQL_DROP );
+ SQLFreeStmt( sth, SQL_DROP );
#endif /* BACKSQL_REALLOC_STMT */
+ }
+
+next_attr:;
}
#ifdef BACKSQL_REALLOC_STMT
}
#endif /* BACKSQL_REALLOC_STMT */
- backsql_BindParamStr( sth, 1, op->oq_add.rs_e->e_name.bv_val,
- BACKSQL_MAX_DN_LEN );
+ backsql_BindParamStr( sth, 1, realdn.bv_val, BACKSQL_MAX_DN_LEN );
SQLBindParameter( sth, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER,
0, 0, &oc->bom_id, 0, 0 );
#ifdef BACKSQL_ARBITRARY_KEY
done:;
send_ldap_result( op, rs );
- if ( realdn.bv_val != op->oq_add.rs_e->e_name.bv_val ) {
+ if ( !BER_BVISNULL( &realdn )
+ && realdn.bv_val != op->oq_add.rs_e->e_name.bv_val )
+ {
ch_free( realdn.bv_val );
}
- if ( realpdn.bv_val != pdn.bv_val ) {
+ if ( !BER_BVISNULL( &realpdn ) && realpdn.bv_val != pdn.bv_val ) {
ch_free( realpdn.bv_val );
}
- if ( parent_id.eid_dn.bv_val != NULL ) {
+ if ( !BER_BVISNULL( &parent_id.eid_dn ) ) {
backsql_free_entryID( &parent_id, 0 );
}
bsi->bsi_attrs = NULL;
} else {
+ int is_oc = 0;
+
bsi->bsi_attrs = (AttributeName *)ch_calloc( 1,
sizeof( AttributeName ) );
BER_BVZERO( &bsi->bsi_attrs[ 0 ].an_name );
} else if ( BACKSQL_NCMP( &p->an_name, &NoAttrs ) == 0 ) {
continue;
+ } else if ( p->an_desc == slap_schema.si_ad_objectClass ) {
+ is_oc = 1;
}
backsql_attrlist_add( bsi, p->an_desc );
}
+
+ if ( is_oc == 0 ) {
+ /* add objectClass if not present,
+ * because it is required to understand
+ * if an entry is a referral, an alias
+ * or so... */
+ backsql_attrlist_add( bsi, slap_schema.si_ad_objectClass );
+ }
}
bsi->bsi_abandon = 0;
bsi->bsi_id_list = NULL;
+ bsi->bsi_id_listtail = &bsi->bsi_id_list;
bsi->bsi_n_candidates = 0;
bsi->bsi_stoptime = stoptime;
BER_BVZERO( &bsi->bsi_sel.bb_val );
c_id->eid_dn = dn;
}
- c_id->eid_next = bsi->bsi_id_list;
- bsi->bsi_id_list = c_id;
- bsi->bsi_n_candidates--;
+ /* append at end of list ... */
+ c_id->eid_next = NULL;
+ *bsi->bsi_id_listtail = c_id;
+ bsi->bsi_id_listtail = &c_id->eid_next;
#ifdef BACKSQL_ARBITRARY_KEY
Debug( LDAP_DEBUG_TRACE, "backsql_oc_get_candidates(): "
c_id->eid_id, c_id->eid_keyval, row.cols[ 3 ] );
#endif /* ! BACKSQL_ARBITRARY_KEY */
+ /* count candidates, for unchecked limit */
+ bsi->bsi_n_candidates--;
if ( bsi->bsi_n_candidates == -1 ) {
break;
}
ber_dupbv( &matched_dn, &user_entry.e_name );
refs = get_entry_referrals( op, &user_entry );
+ if ( !refs ) {
+ backsql_srch_info srch_info2 = { 0 };
+ Entry user_entry2 = { 0 };
+
+ /* retry with the full entry... */
+ backsql_init_search( &srch_info2,
+ &user_entry.e_name,
+ LDAP_SCOPE_BASE,
+ -1, -1, -1, NULL,
+ dbh, op, rs, NULL );
+ srch_info2.bsi_e = &user_entry2;
+ rc = backsql_id2entry( &srch_info2, eid );
+ if ( rc == LDAP_SUCCESS ) {
+ if ( is_entry_referral( &user_entry2 ) )
+ {
+ refs = get_entry_referrals( op,
+ &user_entry2 );
+ } /* else: FIXME: inconsistency! */
+ entry_clean( &user_entry2 );
+ }
+ }
+
if ( refs ) {
rs->sr_ref = referral_rewrite( refs,
&matched_dn, &op->o_req_dn,
ber_memfree( matched_dn.bv_val );
rs->sr_matched = NULL;
- continue;
+ goto next_entry;
}
/*
"has_children failed( %d)\n",
rc, 0, 0 );
rc = 1;
- break;
- }
-
- if ( rc ) {
- continue;
+ goto next_entry;
}
}
hasSubordinate = NULL;
}
-#if 0 /* noop is masked SLAP_CTRL_UPDATE */
- if ( op->o_noop ) {
- sres = 0;
- } else
-#endif
- {
- rs->sr_attrs = op->ors_attrs;
- rs->sr_operational_attrs = NULL;
- rs->sr_entry = &user_entry;
- rs->sr_flags = REP_ENTRY_MODIFIABLE;
- sres = send_search_entry( op, rs );
- rs->sr_entry = NULL;
- rs->sr_attrs = NULL;
- rs->sr_operational_attrs = NULL;
- }
+ rs->sr_attrs = op->ors_attrs;
+ rs->sr_operational_attrs = NULL;
+ rs->sr_entry = &user_entry;
+ rs->sr_flags = REP_ENTRY_MODIFIABLE;
+ sres = send_search_entry( op, rs );
+ rs->sr_entry = NULL;
+ rs->sr_attrs = NULL;
+ rs->sr_operational_attrs = NULL;
switch ( sres ) {
case 0:
break;
- case -1:
- Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
- "connection lost\n", 0, 0, 0 );
- goto end_of_search;
-
default:
/*
* FIXME: send_search_entry failed;
* better stop
*/
- break;
+ case -1:
+ Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
+ "connection lost\n", 0, 0, 0 );
+ goto end_of_search;
}
}
+
+next_entry:;
entry_clean( &user_entry );
if ( op->ors_slimit != SLAP_NO_LIMIT