📄 add.c
字号:
} if ( oc->bom_create_proc == NULL ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " "create procedure is not defined " "for structuralObjectClass \"%s\" - aborting\n", op->ora_e->e_name.bv_val, scname.bv_val, 0 ); rs->sr_err = LDAP_UNWILLING_TO_PERFORM; rs->sr_text = "operation not permitted within namingContext"; e = NULL; goto done; } else if ( BACKSQL_CREATE_NEEDS_SELECT( bi ) && oc->bom_create_keyval == NULL ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " "create procedure needs select procedure, " "but none is defined for structuralObjectClass \"%s\" " "- aborting\n", op->ora_e->e_name.bv_val, scname.bv_val, 0 ); rs->sr_err = LDAP_UNWILLING_TO_PERFORM; rs->sr_text = "operation not permitted within namingContext"; e = NULL; goto done; } /* check write access */ if ( !access_allowed_mask( op, op->ora_e, slap_schema.si_ad_entry, NULL, ACL_WADD, NULL, &mask ) ) { rs->sr_err = LDAP_INSUFFICIENT_ACCESS; e = op->ora_e; goto done; } rs->sr_err = backsql_get_db_conn( op, &dbh ); if ( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " "could not get connection handle - exiting\n", op->ora_e->e_name.bv_val, 0, 0 ); rs->sr_text = ( rs->sr_err == LDAP_OTHER ) ? "SQL-backend error" : NULL; e = NULL; goto done; } /* * Check if entry exists * * NOTE: backsql_api_dn2odbc() is called explicitly because * we need the mucked DN to pass it to the create procedure. */ realdn = op->ora_e->e_name; if ( backsql_api_dn2odbc( op, rs, &realdn ) ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " "backsql_api_dn2odbc(\"%s\") failed\n", op->ora_e->e_name.bv_val, realdn.bv_val, 0 ); rs->sr_err = LDAP_OTHER; rs->sr_text = "SQL-backend error"; e = NULL; goto done; } rs->sr_err = backsql_dn2id( op, rs, dbh, &realdn, NULL, 0, 0 ); if ( rs->sr_err == LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " "entry exists\n", op->ora_e->e_name.bv_val, 0, 0 ); rs->sr_err = LDAP_ALREADY_EXISTS; e = op->ora_e; goto done; } /* * Get the parent dn and see if the corresponding entry exists. */ if ( be_issuffix( op->o_bd, &op->ora_e->e_nname ) ) { pdn = slap_empty_bv; } else { dnParent( &op->ora_e->e_nname, &pdn ); /* * Get the parent */ bsi.bsi_e = &p; rs->sr_err = backsql_init_search( &bsi, &pdn, LDAP_SCOPE_BASE, (time_t)(-1), NULL, dbh, op, rs, slap_anlist_no_attrs, ( BACKSQL_ISF_MATCHED | BACKSQL_ISF_GET_ENTRY ) ); if ( rs->sr_err != LDAP_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, "backsql_add(): " "could not retrieve addDN parent " "\"%s\" ID - %s matched=\"%s\"\n", pdn.bv_val, rs->sr_err == LDAP_REFERRAL ? "referral" : "no such entry", rs->sr_matched ? rs->sr_matched : "(null)" ); e = &p; goto done; } /* check "children" pseudo-attribute access to parent */ if ( !access_allowed( op, &p, slap_schema.si_ad_children, NULL, ACL_WADD, NULL ) ) { rs->sr_err = LDAP_INSUFFICIENT_ACCESS; e = &p; 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 = backsql_Prepare( dbh, &sth, oc->bom_create_proc, 0 ); if ( rc != SQL_SUCCESS ) { rs->sr_err = LDAP_OTHER; rs->sr_text = "SQL-backend error"; e = NULL; goto done; } colnum = 1; if ( BACKSQL_IS_ADD( oc->bom_expect_return ) ) { rc = backsql_BindParamInt( sth, 1, SQL_PARAM_OUTPUT, &new_keyval ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " "error binding keyval parameter " "for objectClass %s\n", op->ora_e->e_name.bv_val, oc->bom_oc->soc_cname.bv_val, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); SQLFreeStmt( sth, SQL_DROP ); rs->sr_text = "SQL-backend error"; rs->sr_err = LDAP_OTHER; e = NULL; goto done; } colnum++; } if ( oc->bom_create_hint ) { at = attr_find( op->ora_e->e_attrs, oc->bom_create_hint ); if ( at && at->a_vals ) { backsql_BindParamStr( sth, colnum, SQL_PARAM_INPUT, at->a_vals[0].bv_val, at->a_vals[0].bv_len ); Debug( LDAP_DEBUG_TRACE, "backsql_add(): " "create_proc hint: param = '%s'\n", at->a_vals[0].bv_val, 0, 0 ); } else { backsql_BindParamStr( sth, colnum, SQL_PARAM_INPUT, "", 0 ); Debug( LDAP_DEBUG_TRACE, "backsql_add(): " "create_proc hint (%s) not avalable\n", oc->bom_create_hint->ad_cname.bv_val, 0, 0 ); } colnum++; } Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): executing \"%s\"\n", op->ora_e->e_name.bv_val, oc->bom_create_proc, 0 ); rc = SQLExecute( sth ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " "create_proc execution failed\n", op->ora_e->e_name.bv_val, 0, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc); SQLFreeStmt( sth, SQL_DROP ); rs->sr_err = LDAP_OTHER; rs->sr_text = "SQL-backend error"; e = NULL; goto done; } /* FIXME: after SQLExecute(), the row is already inserted * (at least with PostgreSQL and unixODBC); needs investigation */ if ( !BACKSQL_IS_ADD( oc->bom_expect_return ) ) { SWORD ncols; SQLINTEGER value_len; if ( BACKSQL_CREATE_NEEDS_SELECT( bi ) ) { SQLFreeStmt( sth, SQL_DROP ); rc = backsql_Prepare( dbh, &sth, oc->bom_create_keyval, 0 ); if ( rc != SQL_SUCCESS ) { rs->sr_err = LDAP_OTHER; rs->sr_text = "SQL-backend error"; e = NULL; goto done; } rc = SQLExecute( sth ); if ( rc != SQL_SUCCESS ) { rs->sr_err = LDAP_OTHER; rs->sr_text = "SQL-backend error"; e = NULL; goto done; } } /* * the query to know the id of the inserted entry * must be embedded in the create procedure */ rc = SQLNumResultCols( sth, &ncols ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " "create_proc result evaluation failed\n", op->ora_e->e_name.bv_val, 0, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc); SQLFreeStmt( sth, SQL_DROP ); rs->sr_err = LDAP_OTHER; rs->sr_text = "SQL-backend error"; e = NULL; goto done; } else if ( ncols != 1 ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " "create_proc result is bogus (ncols=%d)\n", op->ora_e->e_name.bv_val, ncols, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc); SQLFreeStmt( sth, SQL_DROP ); rs->sr_err = LDAP_OTHER; rs->sr_text = "SQL-backend error"; e = NULL; goto done; }#if 0 { SQLCHAR colname[ 64 ]; SQLSMALLINT name_len, col_type, col_scale, col_null; UDWORD col_prec; /* * FIXME: check whether col_type is compatible, * if it can be null and so on ... */ rc = SQLDescribeCol( sth, (SQLUSMALLINT)1, &colname[ 0 ], (SQLUINTEGER)( sizeof( colname ) - 1 ), &name_len, &col_type, &col_prec, &col_scale, &col_null ); }#endif rc = SQLBindCol( sth, (SQLUSMALLINT)1, SQL_C_ULONG, (SQLPOINTER)&new_keyval, (SQLINTEGER)sizeof( new_keyval ), &value_len ); rc = SQLFetch( sth ); if ( value_len <= 0 ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " "create_proc result is empty?\n", op->ora_e->e_name.bv_val, 0, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc); SQLFreeStmt( sth, SQL_DROP ); rs->sr_err = LDAP_OTHER; rs->sr_text = "SQL-backend error"; e = NULL; goto done; } } SQLFreeStmt( sth, SQL_DROP ); Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " "create_proc returned keyval=%ld\n", op->ora_e->e_name.bv_val, new_keyval, 0 ); rc = backsql_Prepare( dbh, &sth, bi->sql_insentry_stmt, 0 ); if ( rc != SQL_SUCCESS ) { rs->sr_err = LDAP_OTHER; rs->sr_text = "SQL-backend error"; e = NULL; goto done; } rc = backsql_BindParamBerVal( sth, 1, SQL_PARAM_INPUT, &realdn ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " "error binding DN parameter for objectClass %s\n", op->ora_e->e_name.bv_val, oc->bom_oc->soc_cname.bv_val, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); SQLFreeStmt( sth, SQL_DROP ); rs->sr_text = "SQL-backend error"; rs->sr_err = LDAP_OTHER; e = NULL; goto done; } rc = backsql_BindParamInt( sth, 2, SQL_PARAM_INPUT, &oc->bom_id ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " "error binding objectClass ID parameter " "for objectClass %s\n", op->ora_e->e_name.bv_val, oc->bom_oc->soc_cname.bv_val, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); SQLFreeStmt( sth, SQL_DROP ); rs->sr_text = "SQL-backend error"; rs->sr_err = LDAP_OTHER; e = NULL; goto done; } rc = backsql_BindParamID( sth, 3, SQL_PARAM_INPUT, &bsi.bsi_base_id.eid_id ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " "error binding parent ID parameter " "for objectClass %s\n", op->ora_e->e_name.bv_val, oc->bom_oc->soc_cname.bv_val, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); SQLFreeStmt( sth, SQL_DROP ); rs->sr_text = "SQL-backend error"; rs->sr_err = LDAP_OTHER; e = NULL; goto done; } rc = backsql_BindParamInt( sth, 4, SQL_PARAM_INPUT, &new_keyval ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " "error binding entry ID parameter " "for objectClass %s\n", op->ora_e->e_name.bv_val, oc->bom_oc->soc_cname.bv_val, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); SQLFreeStmt( sth, SQL_DROP ); rs->sr_text = "SQL-backend error"; rs->sr_err = LDAP_OTHER; e = NULL; goto done; } Debug( LDAP_DEBUG_TRACE, " backsql_add(): executing \"%s\" for dn \"%s\"\n", bi->sql_insentry_stmt, op->ora_e->e_name.bv_val, 0 );#ifdef BACKSQL_ARBITRARY_KEY Debug( LDAP_DEBUG_TRACE, " for oc_map_id=%ld, " "p_id=%s, keyval=%ld\n", oc->bom_id, bsi.bsi_base_id.eid_id.bv_val, new_keyval );#else /* ! BACKSQL_ARBITRARY_KEY */ Debug( LDAP_DEBUG_TRACE, " for oc_map_id=%ld, " "p_id=%ld, keyval=%ld\n", oc->bom_id, bsi.bsi_base_id.eid_id, new_keyval );#endif /* ! BACKSQL_ARBITRARY_KEY */ rc = SQLExecute( sth ); if ( rc != SQL_SUCCESS ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(\"%s\"): " "could not insert ldap_entries record\n", op->ora_e->e_name.bv_val, 0, 0 ); backsql_PrintErrors( bi->sql_db_env, dbh, sth, rc ); /* * execute delete_proc to delete data added !!! */ SQLFreeStmt( sth, SQL_DROP ); rs->sr_err = LDAP_OTHER; rs->sr_text = "SQL-backend error"; e = NULL; goto done; } SQLFreeStmt( sth, SQL_DROP ); for ( at = op->ora_e->e_attrs; at != NULL; at = at->a_next ) { Debug( LDAP_DEBUG_TRACE, " backsql_add(): " "adding attribute \"%s\"\n", at->a_desc->ad_cname.bv_val, 0, 0 ); /* * Skip: * - the first occurrence of objectClass, which is used * to determine how to build the SQL entry (FIXME ?!?) * - operational attributes * - empty attributes (FIXME ?!?) */ if ( backsql_attr_skip( at->a_desc, at->a_vals ) ) { continue; } if ( at->a_desc == slap_schema.si_ad_objectClass ) { at_objectClass = at; continue; } rs->sr_err = backsql_add_attr( op, rs, dbh, oc, at, new_keyval ); if ( rs->sr_err != LDAP_SUCCESS ) { e = op->ora_e; goto done; } } if ( at_objectClass ) { rs->sr_err = backsql_add_attr( op, rs, dbh, oc, at_objectClass, new_keyval ); if ( rs->sr_err != LDAP_SUCCESS ) { e = op->ora_e; goto done; } }done:; /* * Commit only if all operations succeed */ if ( sth != SQL_NULL_HSTMT ) { SQLUSMALLINT CompletionType = SQL_ROLLBACK; if ( rs->sr_err == LDAP_SUCCESS && !op->o_noop ) { assert( e == NULL ); CompletionType = SQL_COMMIT; } SQLTransact( SQL_NULL_HENV, dbh, CompletionType ); } /* * FIXME: NOOP does not work for add -- it works for all * the other operations, and I don't get the reason :( * * hint: there might be some autocommit in Postgres * so that when the unique id of the key table is * automatically increased, there's no rollback. * We might implement a "rollback" procedure consisting * in deleting that row. */#ifdef SLAP_ACL_HONOR_DISCLOSE if ( e != NULL ) { int disclose = 1; if ( e == op->ora_e && !ACL_GRANT( mask, ACL_DISCLOSE ) ) { /* mask already collected */ disclose = 0; } else if ( e == &p && !access_allowed( op, &p, slap_schema.si_ad_entry, NULL, ACL_DISCLOSE, NULL ) ) { disclose = 0; } if ( disclose == 0 ) { rs->sr_err = LDAP_NO_SUCH_OBJECT; rs->sr_text = NULL; rs->sr_matched = NULL; if ( rs->sr_ref ) { ber_bvarray_free( rs->sr_ref ); rs->sr_ref = NULL; } } }#endif /* SLAP_ACL_HONOR_DISCLOSE */ if ( op->o_noop && rs->sr_err == LDAP_SUCCESS ) { rs->sr_err = LDAP_X_NO_OPERATION; } send_ldap_result( op, rs ); slap_graduate_commit_csn( op ); if ( !BER_BVISNULL( &realdn ) && realdn.bv_val != op->ora_e->e_name.bv_val ) { ch_free( realdn.bv_val ); } if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) { (void)backsql_free_entryID( op, &bsi.bsi_base_id, 0 ); } if ( !BER_BVISNULL( &p.e_nname ) ) { backsql_entry_clean( op, &p ); } Debug( LDAP_DEBUG_TRACE, "<==backsql_add(\"%s\"): %d \"%s\"\n", op->ora_e->e_name.bv_val, rs->sr_err, rs->sr_text ? rs->sr_text : "" ); rs->sr_text = NULL; rs->sr_matched = NULL; if ( rs->sr_ref ) { ber_bvarray_free( rs->sr_ref ); rs->sr_ref = NULL; } return rs->sr_err;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -