Commit 873a5b73 authored by Pierangelo Masarati's avatar Pierangelo Masarati
Browse files

first round at enabling back-sql as LDAPsync provider

parent fc57a3e3
......@@ -261,10 +261,12 @@ typedef struct backsql_srch_info {
Operation *bsi_op;
SlapReply *bsi_rs;
int bsi_flags;
#define BSQL_SF_ALL_OPER 0x0001
#define BSQL_SF_FILTER_HASSUBORDINATE 0x0002
#define BSQL_SF_FILTER_ENTRYUUID 0x0004
unsigned bsi_flags;
#define BSQL_SF_NONE 0x0000U
#define BSQL_SF_ALL_OPER 0x0001U
#define BSQL_SF_FILTER_HASSUBORDINATE 0x0002U
#define BSQL_SF_FILTER_ENTRYUUID 0x0004U
#define BSQL_SF_FILTER_ENTRYCSN 0x0008U
struct berval *bsi_base_ndn;
backsql_entryID bsi_base_id;
......
......@@ -65,6 +65,7 @@ sql_back_initialize(
bi->bi_chk_referrals = 0;
bi->bi_operational = backsql_operational;
bi->bi_entry_get_rw = backsql_entry_get;
bi->bi_connection_init = 0;
bi->bi_connection_destroy = backsql_connection_destroy;
......
......@@ -80,7 +80,15 @@ backsql_operational_entryCSN( Operation *op )
a->a_vals = ch_malloc( 2 * sizeof( struct berval ) );
BER_BVZERO( &a->a_vals[ 1 ] );
slap_get_csn( op, csnbuf, sizeof(csnbuf), &entryCSN, 0 );
if ( op->o_sync && op->o_tag == LDAP_REQ_SEARCH ) {
assert( op->o_private );
entryCSN = *((struct berval *)op->o_private);
} else {
slap_get_csn( op, csnbuf, sizeof(csnbuf), &entryCSN, 0 );
}
ber_dupbv( &a->a_vals[ 0 ], &entryCSN );
a->a_nvals = a->a_vals;
......
......@@ -279,6 +279,7 @@ extern BI_op_add backsql_add;
extern BI_op_delete backsql_delete;
extern BI_operational backsql_operational;
extern BI_entry_get_rw backsql_entry_get;
extern BI_connection_destroy backsql_connection_destroy;
......
......@@ -127,7 +127,7 @@ backsql_init_search(
bsi->bsi_dbh = dbh;
bsi->bsi_op = op;
bsi->bsi_rs = rs;
bsi->bsi_flags = 0;
bsi->bsi_flags = BSQL_SF_NONE;
/*
* handle "*"
......@@ -676,13 +676,25 @@ backsql_process_filter( backsql_srch_info *bsi, Filter *f )
* TODO: introduce appropriate entryCSN filtering
* to support syncrepl as producer...
*/
if ( bsi->bsi_op->o_sync ) {
if ( !bsi->bsi_op->o_sync ) {
/* unsupported at present... */
bsi->bsi_status = LDAP_OTHER;
rc = -1;
goto done;
}
/* if doing a syncrepl, try to return as much as possible,
* and always match the filter */
backsql_strfcat( &bsi->bsi_flt_where, "l",
(ber_len_t)STRLENOF( "1=1" ), "1=1" );
/* save for later use in operational attributes */
bsi->bsi_op->o_private = &f->f_av_value;
bsi->bsi_flags |= BSQL_SF_FILTER_ENTRYCSN;
bsi->bsi_status = LDAP_SUCCESS;
rc = 1;
goto done;
} else if ( ad == slap_schema.si_ad_hasSubordinates || ad == NULL ) {
/*
......@@ -1696,6 +1708,7 @@ backsql_search( Operation *op, SlapReply *rs )
int rc;
Attribute *a_hasSubordinate = NULL,
*a_entryUUID = NULL,
*a_entryCSN = NULL,
*a = NULL;
Entry *e = NULL;
......@@ -1878,26 +1891,19 @@ backsql_search( Operation *op, SlapReply *rs )
}
}
if ( test_filter( op, e, op->ors_filter ) == LDAP_COMPARE_TRUE )
{
#if 0
if ( a_hasSubordinate && !( bsi.bsi_flags & BSQL_SF_ALL_OPER )
&& !ad_inlist( slap_schema.si_ad_hasSubordinates, op->ors_attrs ) )
{
a->a_next = NULL;
attr_free( a_hasSubordinate );
a_hasSubordinate = NULL;
}
if ( bsi.bsi_flags & BSQL_SF_FILTER_ENTRYCSN ) {
a_entryCSN = backsql_operational_entryCSN( op );
if ( a_entryUUID != NULL ) {
for ( a = user_entry.e_attrs;
a && a->a_next;
a = a->a_next );
if ( a_entryUUID && !( bsi.bsi_flags & BSQL_SF_ALL_OPER )
&& !ad_inlist( slap_schema.si_ad_entryUUID, op->ors_attrs ) )
{
a->a_next = NULL;
attr_free( a_hasSubordinate );
a_hasSubordinate = NULL;
a->a_next = a_entryCSN;
}
#endif
}
if ( test_filter( op, e, op->ors_filter ) == LDAP_COMPARE_TRUE )
{
rs->sr_attrs = op->ors_attrs;
rs->sr_operational_attrs = NULL;
rs->sr_entry = e;
......@@ -1981,3 +1987,90 @@ done:;
return 0;
}
/* return LDAP_SUCCESS IFF we can retrieve the specified entry.
*/
int
backsql_entry_get(
Operation *op,
struct berval *ndn,
ObjectClass *oc,
AttributeDescription *at,
int rw,
Entry **ent )
{
backsql_srch_info bsi;
SQLHDBC dbh;
int rc;
SlapReply rs = { 0 };
AttributeName anlist[ 2 ];
rc = backsql_get_db_conn( op, &dbh );
if ( !dbh ) {
return LDAP_OTHER;
}
if ( at ) {
anlist[ 0 ].an_name = at->ad_cname;
anlist[ 0 ].an_desc = at;
BER_BVZERO( &anlist[ 1 ].an_name );
}
rc = backsql_init_search( &bsi,
ndn,
LDAP_SCOPE_BASE,
SLAP_NO_LIMIT, SLAP_NO_LIMIT, -1, NULL,
dbh, op, &rs, at ? anlist : NULL, 1 );
if ( rc != LDAP_SUCCESS ) {
return rc;
}
bsi.bsi_e = ch_malloc( sizeof( Entry ) );
rc = backsql_id2entry( &bsi, &bsi.bsi_base_id );
if ( !BER_BVISNULL( &bsi.bsi_base_id.eid_ndn ) ) {
(void)backsql_free_entryID( &bsi.bsi_base_id, 0 );
}
if ( rc == LDAP_SUCCESS ) {
#if 0 /* not supported at present */
/* find attribute values */
if ( is_entry_alias( bsi.bsi_e ) ) {
Debug( LDAP_DEBUG_ACL,
"<= backsql_entry_get: entry is an alias\n",
0, 0, 0 );
rc = LDAP_ALIAS_PROBLEM;
goto return_results;
}
#endif
if ( is_entry_referral( bsi.bsi_e ) ) {
Debug( LDAP_DEBUG_ACL,
"<= backsql_entry_get: entry is a referral\n",
0, 0, 0 );
rc = LDAP_REFERRAL;
goto return_results;
}
if ( oc && !is_entry_objectclass( bsi.bsi_e, oc, 0 ) ) {
Debug( LDAP_DEBUG_ACL,
"<= backsql_entry_get: "
"failed to find objectClass\n",
0, 0, 0 );
rc = LDAP_NO_SUCH_ATTRIBUTE;
goto return_results;
}
*ent = bsi.bsi_e;
}
return_results:;
if ( rc != LDAP_SUCCESS ) {
if ( bsi.bsi_e ) {
entry_free( bsi.bsi_e );
}
}
return rc;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment