static dynlist_info_t * dynlist_is_dynlist_next( Operation *op, SlapReply *rs, dynlist_info_t *old_dli ) { slap_overinst *on = (slap_overinst *)op->o_bd->bd_info; dynlist_info_t *dli; Attribute *a; if ( old_dli == NULL ) { dli = (dynlist_info_t *)on->on_bi.bi_private; } else { dli = old_dli->dli_next; } a = attrs_find( rs->sr_entry->e_attrs, slap_schema.si_ad_objectClass ); if ( a == NULL ) { /* FIXME: objectClass must be present; for non-storage * backends, like back-ldap, it needs to be added * to the requested attributes */ return NULL; } for ( ; dli; dli = dli->dli_next ) { if ( dli->dli_lud != NULL ) { /* check base and scope */ if ( !BER_BVISNULL( &dli->dli_uri_nbase ) && !dnIsSuffixScope( &rs->sr_entry->e_nname, &dli->dli_uri_nbase, dli->dli_lud->lud_scope ) ) { continue; } /* check filter */ if ( dli->dli_uri_filter && test_filter( op, rs->sr_entry, dli->dli_uri_filter ) != LDAP_COMPARE_TRUE ) { continue; } } if ( attr_valfind( a, SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH | SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH, &dli->dli_oc->soc_cname, NULL, op->o_tmpmemctx ) == 0 ) { return dli; } } return NULL; }
int slapschema( int argc, char **argv ) { ID id; int rc = EXIT_SUCCESS; const char *progname = "slapschema"; Connection conn = { 0 }; OperationBuffer opbuf; Operation *op = NULL; void *thrctx; int requestBSF = 0; int doBSF = 0; slap_tool_init( progname, SLAPCAT, argc, argv ); requestBSF = ( sub_ndn.bv_len || filter ); #ifdef SIGPIPE (void) SIGNAL( SIGPIPE, slapcat_sig ); #endif #ifdef SIGHUP (void) SIGNAL( SIGHUP, slapcat_sig ); #endif (void) SIGNAL( SIGINT, slapcat_sig ); (void) SIGNAL( SIGTERM, slapcat_sig ); if( !be->be_entry_open || !be->be_entry_close || !( be->be_entry_first || be->be_entry_first_x ) || !be->be_entry_next || !be->be_entry_get ) { fprintf( stderr, "%s: database doesn't support necessary operations.\n", progname ); exit( EXIT_FAILURE ); } if( be->be_entry_open( be, 0 ) != 0 ) { fprintf( stderr, "%s: could not open database.\n", progname ); exit( EXIT_FAILURE ); } thrctx = ldap_pvt_thread_pool_context(); connection_fake_init( &conn, &opbuf, thrctx ); op = &opbuf.ob_op; op->o_tmpmemctx = NULL; op->o_bd = be; if ( !requestBSF && be->be_entry_first ) { id = be->be_entry_first( be ); } else { if ( be->be_entry_first_x ) { id = be->be_entry_first_x( be, sub_ndn.bv_len ? &sub_ndn : NULL, scope, filter ); } else { assert( be->be_entry_first != NULL ); doBSF = 1; id = be->be_entry_first( be ); } } for ( ; id != NOID; id = be->be_entry_next( be ) ) { Entry* e; char textbuf[SLAP_TEXT_BUFLEN]; size_t textlen = sizeof(textbuf); const char *text = NULL; if ( gotsig ) break; e = be->be_entry_get( be, id ); if ( e == NULL ) { printf("# no data for entry id=%08lx\n\n", (long) id ); rc = EXIT_FAILURE; if( continuemode ) continue; break; } if ( doBSF ) { if ( sub_ndn.bv_len && !dnIsSuffixScope( &e->e_nname, &sub_ndn, scope ) ) { be_entry_release_r( op, e ); continue; } if ( filter != NULL ) { int rc = test_filter( NULL, e, filter ); if ( rc != LDAP_COMPARE_TRUE ) { be_entry_release_r( op, e ); continue; } } } if( verbose ) { printf( "# id=%08lx\n", (long) id ); } rc = entry_schema_check( op, e, NULL, 0, 0, NULL, &text, textbuf, textlen ); if ( rc != LDAP_SUCCESS ) { fprintf( ldiffp->fp, "# (%d) %s%s%s\n", rc, ldap_err2string( rc ), text ? ": " : "", text ? text : "" ); fprintf( ldiffp->fp, "dn: %s\n\n", e->e_name.bv_val ); } be_entry_release_r( op, e ); } be->be_entry_close( be ); if ( slap_tool_destroy() ) rc = EXIT_FAILURE; return rc; }
int slapcat( int argc, char **argv ) { ID id; int rc = EXIT_SUCCESS; Operation op = {0}; const char *progname = "slapcat"; int requestBSF; int doBSF = 0; slap_tool_init( progname, SLAPCAT, argc, argv ); requestBSF = ( sub_ndn.bv_len || filter ); #ifdef SIGPIPE (void) SIGNAL( SIGPIPE, slapcat_sig ); #endif #ifdef SIGHUP (void) SIGNAL( SIGHUP, slapcat_sig ); #endif (void) SIGNAL( SIGINT, slapcat_sig ); (void) SIGNAL( SIGTERM, slapcat_sig ); if( !be->be_entry_open || !be->be_entry_close || !( be->be_entry_first_x || be->be_entry_first ) || !be->be_entry_next || !be->be_entry_get ) { fprintf( stderr, "%s: database doesn't support necessary operations.\n", progname ); exit( EXIT_FAILURE ); } if( be->be_entry_open( be, 0 ) != 0 ) { fprintf( stderr, "%s: could not open database.\n", progname ); exit( EXIT_FAILURE ); } op.o_bd = be; if ( !requestBSF && be->be_entry_first ) { id = be->be_entry_first( be ); } else { if ( be->be_entry_first_x ) { id = be->be_entry_first_x( be, sub_ndn.bv_len ? &sub_ndn : NULL, scope, filter ); } else { assert( be->be_entry_first != NULL ); doBSF = 1; id = be->be_entry_first( be ); } } for ( ; id != NOID; id = be->be_entry_next( be ) ) { char *data; int len; Entry* e; if ( gotsig ) break; e = be->be_entry_get( be, id ); if ( e == NULL ) { printf("# no data for entry id=%08lx\n\n", (long) id ); rc = EXIT_FAILURE; if ( continuemode == 0 ) { break; } else if ( continuemode == 1 ) { continue; } /* this is a last resort: linearly scan all ids * trying to recover as much as possible (ITS#6482) */ while ( ++id != NOID ) { e = be->be_entry_get( be, id ); if ( e != NULL ) break; printf("# no data for entry id=%08lx\n\n", (long) id ); } if ( e == NULL ) break; } if ( doBSF ) { if ( sub_ndn.bv_len && !dnIsSuffixScope( &e->e_nname, &sub_ndn, scope ) ) { be_entry_release_r( &op, e ); continue; } if ( filter != NULL ) { int rc = test_filter( NULL, e, filter ); if ( rc != LDAP_COMPARE_TRUE ) { be_entry_release_r( &op, e ); continue; } } } if ( verbose ) { printf( "# id=%08lx\n", (long) id ); } data = entry2str( e, &len ); be_entry_release_r( &op, e ); if ( data == NULL ) { printf("# bad data for entry id=%08lx\n\n", (long) id ); rc = EXIT_FAILURE; if( continuemode ) continue; break; } if ( fputs( data, ldiffp->fp ) == EOF || fputs( "\n", ldiffp->fp ) == EOF ) { fprintf(stderr, "%s: error writing output.\n", progname); rc = EXIT_FAILURE; break; } } be->be_entry_close( be ); if ( slap_tool_destroy()) rc = EXIT_FAILURE; return rc; }
static int bdb_tool_entry_get_int( BackendDB *be, ID id, Entry **ep ) { Entry *e = NULL; char *dptr; int rc, eoff; assert( be != NULL ); assert( slapMode & SLAP_TOOL_MODE ); if ( ( tool_filter || tool_base ) && id == previd && tool_next_entry != NULL ) { *ep = tool_next_entry; tool_next_entry = NULL; return LDAP_SUCCESS; } if ( id != previd ) { data.ulen = data.dlen = sizeof( ehbuf ); data.data = ehbuf; data.flags |= DB_DBT_PARTIAL; BDB_ID2DISK( id, &nid ); rc = cursor->c_get( cursor, &key, &data, DB_SET ); if ( rc ) { rc = LDAP_OTHER; goto done; } } /* Get the header */ dptr = eh.bv.bv_val; eh.bv.bv_val = ehbuf; eh.bv.bv_len = data.size; rc = entry_header( &eh ); eoff = eh.data - eh.bv.bv_val; eh.bv.bv_val = dptr; if ( rc ) { rc = LDAP_OTHER; goto done; } /* Get the size */ data.flags &= ~DB_DBT_PARTIAL; data.ulen = 0; rc = cursor->c_get( cursor, &key, &data, DB_CURRENT ); if ( rc != DB_BUFFER_SMALL ) { rc = LDAP_OTHER; goto done; } /* Allocate a block and retrieve the data */ eh.bv.bv_len = eh.nvals * sizeof( struct berval ) + data.size; eh.bv.bv_val = ch_realloc( eh.bv.bv_val, eh.bv.bv_len ); eh.data = eh.bv.bv_val + eh.nvals * sizeof( struct berval ); data.data = eh.data; data.ulen = data.size; /* Skip past already parsed nattr/nvals */ eh.data += eoff; rc = cursor->c_get( cursor, &key, &data, DB_CURRENT ); if ( rc ) { rc = LDAP_OTHER; goto done; } #ifndef BDB_HIER /* TODO: handle BDB_HIER accordingly */ if ( tool_base != NULL ) { struct berval ndn; entry_decode_dn( &eh, NULL, &ndn ); if ( !dnIsSuffixScope( &ndn, tool_base, tool_scope ) ) { return LDAP_NO_SUCH_OBJECT; } } #endif #ifdef SLAP_ZONE_ALLOC /* FIXME: will add ctx later */ rc = entry_decode( &eh, &e, NULL ); #else rc = entry_decode( &eh, &e ); #endif if( rc == LDAP_SUCCESS ) { e->e_id = id; #ifdef BDB_HIER if ( slapMode & SLAP_TOOL_READONLY ) { struct bdb_info *bdb = (struct bdb_info *) be->be_private; EntryInfo *ei = NULL; Operation op = {0}; Opheader ohdr = {0}; op.o_hdr = &ohdr; op.o_bd = be; op.o_tmpmemctx = NULL; op.o_tmpmfuncs = &ch_mfuncs; rc = bdb_cache_find_parent( &op, bdb->bi_cache.c_txn, id, &ei ); if ( rc == LDAP_SUCCESS ) { bdb_cache_entryinfo_unlock( ei ); e->e_private = ei; ei->bei_e = e; bdb_fix_dn( e, 0 ); ei->bei_e = NULL; e->e_private = NULL; } } #endif } done: if ( e != NULL ) { *ep = e; } return rc; }
ID bdb_tool_entry_next( BackendDB *be ) { int rc; ID id; struct bdb_info *bdb; assert( be != NULL ); assert( slapMode & SLAP_TOOL_MODE ); bdb = (struct bdb_info *) be->be_private; assert( bdb != NULL ); next:; /* Get the header */ data.ulen = data.dlen = sizeof( ehbuf ); data.data = ehbuf; data.flags |= DB_DBT_PARTIAL; rc = cursor->c_get( cursor, &key, &data, DB_NEXT ); if( rc ) { /* If we're doing linear indexing and there are more attrs to * index, and we're at the end of the database, start over. */ if ( index_nattrs && rc == DB_NOTFOUND ) { /* optional - do a checkpoint here? */ bdb_attr_info_free( bdb->bi_attrs[0] ); bdb->bi_attrs[0] = bdb->bi_attrs[index_nattrs]; index_nattrs--; rc = cursor->c_get( cursor, &key, &data, DB_FIRST ); if ( rc ) { return NOID; } } else { return NOID; } } BDB_DISK2ID( key.data, &id ); previd = id; if ( tool_filter || tool_base ) { static Operation op = {0}; static Opheader ohdr = {0}; op.o_hdr = &ohdr; op.o_bd = be; op.o_tmpmemctx = NULL; op.o_tmpmfuncs = &ch_mfuncs; if ( tool_next_entry ) { bdb_entry_release( &op, tool_next_entry, 0 ); tool_next_entry = NULL; } rc = bdb_tool_entry_get_int( be, id, &tool_next_entry ); if ( rc == LDAP_NO_SUCH_OBJECT ) { goto next; } assert( tool_next_entry != NULL ); #ifdef BDB_HIER /* TODO: needed until BDB_HIER is handled accordingly * in bdb_tool_entry_get_int() */ if ( tool_base && !dnIsSuffixScope( &tool_next_entry->e_nname, tool_base, tool_scope ) ) { bdb_entry_release( &op, tool_next_entry, 0 ); tool_next_entry = NULL; goto next; } #endif if ( tool_filter && test_filter( NULL, tool_next_entry, tool_filter ) != LDAP_COMPARE_TRUE ) { bdb_entry_release( &op, tool_next_entry, 0 ); tool_next_entry = NULL; goto next; } } return id; }
static int mdb_tool_entry_get_int( BackendDB *be, ID id, Entry **ep ) { Operation op = {0}; Opheader ohdr = {0}; Entry *e = NULL; struct berval dn = BER_BVNULL, ndn = BER_BVNULL; int rc; assert( be != NULL ); assert( slapMode & SLAP_TOOL_MODE ); if ( ( tool_filter || tool_base ) && id == previd && tool_next_entry != NULL ) { *ep = tool_next_entry; tool_next_entry = NULL; return LDAP_SUCCESS; } if ( id != previd ) { key.mv_size = sizeof(ID); key.mv_data = &id; rc = mdb_cursor_get( cursor, &key, &data, MDB_SET ); if ( rc ) { rc = LDAP_OTHER; goto done; } } op.o_hdr = &ohdr; op.o_bd = be; op.o_tmpmemctx = NULL; op.o_tmpmfuncs = &ch_mfuncs; if ( slapMode & SLAP_TOOL_READONLY ) { rc = mdb_id2name( &op, txn, &idcursor, id, &dn, &ndn ); if ( rc ) { rc = LDAP_OTHER; if ( e ) { mdb_entry_return( &op, e ); e = NULL; } goto done; } if ( tool_base != NULL ) { if ( !dnIsSuffixScope( &ndn, tool_base, tool_scope ) ) { ch_free( dn.bv_val ); ch_free( ndn.bv_val ); rc = LDAP_NO_SUCH_OBJECT; } } } rc = mdb_entry_decode( &op, &data, &e ); e->e_id = id; if ( !BER_BVISNULL( &dn )) { e->e_name = dn; e->e_nname = ndn; } else { e->e_name.bv_val = NULL; e->e_nname.bv_val = NULL; } done: if ( e != NULL ) { *ep = e; } return rc; }