static int create_baseObject( BackendDB *be, const char *fname, int lineno ) { backsql_info *bi = (backsql_info *)be->be_private; LDAPRDN rdn; char *p; int rc, iAVA; char buf[1024]; snprintf( buf, sizeof(buf), "dn: %s\n" "objectClass: extensibleObject\n" "description: builtin baseObject for back-sql\n" "description: all entries mapped " "in table \"ldap_entries\" " "must have " "\"" BACKSQL_BASEOBJECT_IDSTR "\" " "in the \"parent\" column", be->be_suffix[0].bv_val ); bi->sql_baseObject = str2entry( buf ); if ( bi->sql_baseObject == NULL ) { Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config (%s line %d): " "unable to parse baseObject entry\n", fname, lineno, 0 ); return 1; } if ( BER_BVISEMPTY( &be->be_suffix[ 0 ] ) ) { return 0; } rc = ldap_bv2rdn( &be->be_suffix[ 0 ], &rdn, (char **)&p, LDAP_DN_FORMAT_LDAP ); if ( rc != LDAP_SUCCESS ) { snprintf( buf, sizeof(buf), "unable to extract RDN " "from baseObject DN \"%s\" (%d: %s)", be->be_suffix[ 0 ].bv_val, rc, ldap_err2string( rc ) ); Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config (%s line %d): %s\n", fname, lineno, buf ); return 1; } for ( iAVA = 0; rdn[ iAVA ]; iAVA++ ) { LDAPAVA *ava = rdn[ iAVA ]; AttributeDescription *ad = NULL; slap_syntax_transform_func *transf = NULL; struct berval bv = BER_BVNULL; const char *text = NULL; assert( ava != NULL ); rc = slap_bv2ad( &ava->la_attr, &ad, &text ); if ( rc != LDAP_SUCCESS ) { snprintf( buf, sizeof(buf), "AttributeDescription of naming " "attribute #%d from baseObject " "DN \"%s\": %d: %s", iAVA, be->be_suffix[ 0 ].bv_val, rc, ldap_err2string( rc ) ); Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config (%s line %d): %s\n", fname, lineno, buf ); return 1; } transf = ad->ad_type->sat_syntax->ssyn_pretty; if ( transf ) { /* * transform value by pretty function * if value is empty, use empty_bv */ rc = ( *transf )( ad->ad_type->sat_syntax, ava->la_value.bv_len ? &ava->la_value : (struct berval *) &slap_empty_bv, &bv, NULL ); if ( rc != LDAP_SUCCESS ) { snprintf( buf, sizeof(buf), "prettying of attribute #%d " "from baseObject " "DN \"%s\" failed: %d: %s", iAVA, be->be_suffix[ 0 ].bv_val, rc, ldap_err2string( rc ) ); Debug( LDAP_DEBUG_TRACE, "<==backsql_db_config (%s line %d): " "%s\n", fname, lineno, buf ); return 1; } } if ( !BER_BVISNULL( &bv ) ) { if ( ava->la_flags & LDAP_AVA_FREE_VALUE ) { ber_memfree( ava->la_value.bv_val ); } ava->la_value = bv; ava->la_flags |= LDAP_AVA_FREE_VALUE; } attr_merge_normalize_one( bi->sql_baseObject, ad, &ava->la_value, NULL ); } ldap_rdnfree( rdn ); return 0; }
int read_and_send_results( Operation *op, SlapReply *rs, FILE *fp ) { int bsize, len; char *buf, *bp; char line[BUFSIZ]; char ebuf[128]; /* read in the result and send it along */ buf = (char *) ch_malloc( BUFSIZ ); buf[0] = '\0'; bsize = BUFSIZ; bp = buf; while ( !feof(fp) ) { errno = 0; if ( fgets( line, sizeof(line), fp ) == NULL ) { if ( errno == EINTR ) continue; Debug( LDAP_DEBUG_ANY, "shell: fgets failed: %s (%d)\n", AC_STRERROR_R(errno, ebuf, sizeof ebuf), errno, 0 ); break; } Debug( LDAP_DEBUG_SHELL, "shell search reading line (%s)\n", line, 0, 0 ); /* ignore lines beginning with # (LDIFv1 comments) */ if ( *line == '#' ) { continue; } /* ignore lines beginning with DEBUG: */ if ( strncasecmp( line, "DEBUG:", 6 ) == 0 ) { continue; } len = strlen( line ); while ( bp + len + 1 - buf > bsize ) { size_t offset = bp - buf; bsize += BUFSIZ; buf = (char *) ch_realloc( buf, bsize ); bp = &buf[offset]; } strcpy( bp, line ); bp += len; /* line marked the end of an entry or result */ if ( *line == '\n' ) { if ( strncasecmp( buf, "RESULT", 6 ) == 0 ) { break; } if ( (rs->sr_entry = str2entry( buf )) == NULL ) { Debug( LDAP_DEBUG_ANY, "str2entry(%s) failed\n", buf, 0, 0 ); } else { rs->sr_attrs = op->oq_search.rs_attrs; rs->sr_flags = REP_ENTRY_MODIFIABLE; send_search_entry( op, rs ); entry_free( rs->sr_entry ); rs->sr_attrs = NULL; } bp = buf; } } (void) str2result( buf, &rs->sr_err, (char **)&rs->sr_matched, (char **)&rs->sr_text ); /* otherwise, front end will send this result */ if ( rs->sr_err != 0 || op->o_tag != LDAP_REQ_BIND ) { send_ldap_result( op, rs ); } free( buf ); return( rs->sr_err ); }
/* * Read the entries specified in fname and merge the attributes * to the user defined baseObject entry. Note that if we find any errors * what so ever, we will discard the entire entries, print an * error message and return. */ static int read_baseObject( BackendDB *be, const char *fname ) { backsql_info *bi = (backsql_info *)be->be_private; LDIFFP *fp; int rc = 0, lineno = 0, lmax = 0; char *buf = NULL; assert( fname != NULL ); fp = ldif_open( fname, "r" ); if ( fp == NULL ) { Debug( LDAP_DEBUG_ANY, "could not open back-sql baseObject " "attr file \"%s\" - absolute path?\n", fname, 0, 0 ); perror( fname ); return LDAP_OTHER; } bi->sql_baseObject = entry_alloc(); if ( bi->sql_baseObject == NULL ) { Debug( LDAP_DEBUG_ANY, "read_baseObject_file: entry_alloc failed", 0, 0, 0 ); ldif_close( fp ); return LDAP_NO_MEMORY; } bi->sql_baseObject->e_name = be->be_suffix[0]; bi->sql_baseObject->e_nname = be->be_nsuffix[0]; bi->sql_baseObject->e_attrs = NULL; while ( ldif_read_record( fp, &lineno, &buf, &lmax ) ) { Entry *e = str2entry( buf ); Attribute *a; if( e == NULL ) { fprintf( stderr, "back-sql baseObject: " "could not parse entry (line=%d)\n", lineno ); rc = LDAP_OTHER; break; } /* make sure the DN is the database's suffix */ if ( !be_issuffix( be, &e->e_nname ) ) { fprintf( stderr, "back-sql: invalid baseObject - " "dn=\"%s\" (line=%d)\n", e->e_name.bv_val, lineno ); entry_free( e ); rc = EXIT_FAILURE; break; } /* * we found a valid entry, so walk thru all the attributes in the * entry, and add each attribute type and description to baseObject */ for ( a = e->e_attrs; a != NULL; a = a->a_next ) { if ( attr_merge( bi->sql_baseObject, a->a_desc, a->a_vals, ( a->a_nvals == a->a_vals ) ? NULL : a->a_nvals ) ) { rc = LDAP_OTHER; break; } } entry_free( e ); if ( rc ) { break; } } if ( rc ) { entry_free( bi->sql_baseObject ); bi->sql_baseObject = NULL; } ch_free( buf ); ldif_close( fp ); Debug( LDAP_DEBUG_CONFIG, "back-sql baseObject file \"%s\" read.\n", fname, 0, 0 ); return rc; }
/* * call from within ldap_back_db_open() */ int ldap_back_monitor_db_open( BackendDB *be ) { ldapinfo_t *li = (ldapinfo_t *) be->be_private; char buf[ BACKMONITOR_BUFSIZE ]; Entry *e = NULL; monitor_callback_t *cb = NULL; struct berval suffix, *filter, *base; char *ptr; time_t now; char timebuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; struct berval timestamp; int rc = 0; BackendInfo *mi; monitor_extra_t *mbe; if ( !SLAP_DBMONITORING( be ) ) { return 0; } /* check if monitor is configured and usable */ mi = backend_info( "monitor" ); if ( !mi || !mi->bi_extra ) { SLAP_DBFLAGS( be ) ^= SLAP_DBFLAG_MONITORING; return 0; } mbe = mi->bi_extra; /* don't bother if monitor is not configured */ if ( !mbe->is_configured() ) { static int warning = 0; if ( warning++ == 0 ) { Debug( LDAP_DEBUG_ANY, "ldap_back_monitor_db_open: " "monitoring disabled; " "configure monitor database to enable\n", 0, 0, 0 ); } return 0; } /* set up the fake subsystem that is used to create * the volatile connection entries */ li->li_monitor_info.lmi_mss.mss_name = "back-ldap"; li->li_monitor_info.lmi_mss.mss_flags = MONITOR_F_VOLATILE_CH; li->li_monitor_info.lmi_mss.mss_create = ldap_back_monitor_conn_create; li->li_monitor_info.lmi_li = li; li->li_monitor_info.lmi_scope = LDAP_SCOPE_SUBORDINATE; base = &li->li_monitor_info.lmi_base; BER_BVSTR( base, "cn=databases,cn=monitor" ); filter = &li->li_monitor_info.lmi_filter; BER_BVZERO( filter ); suffix.bv_len = ldap_bv2escaped_filter_value_len( &be->be_nsuffix[ 0 ] ); if ( suffix.bv_len == be->be_nsuffix[ 0 ].bv_len ) { suffix = be->be_nsuffix[ 0 ]; } else { ldap_bv2escaped_filter_value( &be->be_nsuffix[ 0 ], &suffix ); } filter->bv_len = STRLENOF( "(&" ) + li->li_monitor_info.lmi_more_filter.bv_len + STRLENOF( "(monitoredInfo=" ) + strlen( be->bd_info->bi_type ) + STRLENOF( ")(!(monitorOverlay=" ) + strlen( be->bd_info->bi_type ) + STRLENOF( "))(namingContexts:distinguishedNameMatch:=" ) + suffix.bv_len + STRLENOF( "))" ); ptr = filter->bv_val = ch_malloc( filter->bv_len + 1 ); ptr = lutil_strcopy( ptr, "(&" ); ptr = lutil_strncopy( ptr, li->li_monitor_info.lmi_more_filter.bv_val, li->li_monitor_info.lmi_more_filter.bv_len ); ptr = lutil_strcopy( ptr, "(monitoredInfo=" ); ptr = lutil_strcopy( ptr, be->bd_info->bi_type ); ptr = lutil_strcopy( ptr, ")(!(monitorOverlay=" ); ptr = lutil_strcopy( ptr, be->bd_info->bi_type ); ptr = lutil_strcopy( ptr, "))(namingContexts:distinguishedNameMatch:=" ); ptr = lutil_strncopy( ptr, suffix.bv_val, suffix.bv_len ); ptr = lutil_strcopy( ptr, "))" ); ptr[ 0 ] = '\0'; assert( ptr == &filter->bv_val[ filter->bv_len ] ); if ( suffix.bv_val != be->be_nsuffix[ 0 ].bv_val ) { ch_free( suffix.bv_val ); } now = slap_get_time(); timestamp.bv_val = timebuf; timestamp.bv_len = sizeof( timebuf ); slap_timestamp( &now, ×tamp ); /* caller (e.g. an overlay based on back-ldap) may want to use * a different RDN... */ if ( BER_BVISNULL( &li->li_monitor_info.lmi_rdn ) ) { ber_str2bv( "cn=Connections", 0, 1, &li->li_monitor_info.lmi_rdn ); } ptr = ber_bvchr( &li->li_monitor_info.lmi_rdn, '=' ); assert( ptr != NULL ); ptr[ 0 ] = '\0'; ptr++; snprintf( buf, sizeof( buf ), "dn: %s=%s\n" "objectClass: monitorContainer\n" "%s: %s\n" "creatorsName: %s\n" "createTimestamp: %s\n" "modifiersName: %s\n" "modifyTimestamp: %s\n", li->li_monitor_info.lmi_rdn.bv_val, ptr, li->li_monitor_info.lmi_rdn.bv_val, ptr, BER_BVISNULL( &be->be_rootdn ) ? SLAPD_ANONYMOUS : be->be_rootdn.bv_val, timestamp.bv_val, BER_BVISNULL( &be->be_rootdn ) ? SLAPD_ANONYMOUS : be->be_rootdn.bv_val, timestamp.bv_val ); e = str2entry( buf ); if ( e == NULL ) { rc = -1; goto cleanup; } ptr[ -1 ] = '='; /* add labeledURI and special, modifiable URI value */ if ( li->li_uri != NULL ) { struct berval bv; LDAPURLDesc *ludlist = NULL; int rc; rc = ldap_url_parselist_ext( &ludlist, li->li_uri, NULL, LDAP_PVT_URL_PARSE_NOEMPTY_HOST | LDAP_PVT_URL_PARSE_DEF_PORT ); if ( rc != LDAP_URL_SUCCESS ) { Debug( LDAP_DEBUG_ANY, "ldap_back_monitor_db_open: " "unable to parse URI list (ignored)\n", 0, 0, 0 ); } else { for ( ; ludlist != NULL; ) { LDAPURLDesc *next = ludlist->lud_next; bv.bv_val = ldap_url_desc2str( ludlist ); assert( bv.bv_val != NULL ); ldap_free_urldesc( ludlist ); bv.bv_len = strlen( bv.bv_val ); attr_merge_normalize_one( e, slap_schema.si_ad_labeledURI, &bv, NULL ); ch_free( bv.bv_val ); ludlist = next; } } ber_str2bv( li->li_uri, 0, 0, &bv ); attr_merge_normalize_one( e, ad_olmDbURIList, &bv, NULL ); } ber_dupbv( &li->li_monitor_info.lmi_nrdn, &e->e_nname ); cb = ch_calloc( sizeof( monitor_callback_t ), 1 ); cb->mc_update = ldap_back_monitor_update; cb->mc_modify = ldap_back_monitor_modify; cb->mc_free = ldap_back_monitor_free; cb->mc_private = (void *)li; rc = mbe->register_entry_parent( e, cb, (monitor_subsys_t *)&li->li_monitor_info, MONITOR_F_VOLATILE_CH, base, LDAP_SCOPE_SUBORDINATE, filter ); cleanup:; if ( rc != 0 ) { if ( cb != NULL ) { ch_free( cb ); cb = NULL; } if ( e != NULL ) { entry_free( e ); e = NULL; } if ( !BER_BVISNULL( filter ) ) { ch_free( filter->bv_val ); BER_BVZERO( filter ); } } /* store for cleanup */ li->li_monitor_info.lmi_cb = (void *)cb; if ( e != NULL ) { entry_free( e ); } return rc; }
int monitor_subsys_database_init( BackendDB *be ) { struct monitorinfo *mi; Entry *e, *e_database, *e_tmp; int i; struct monitorentrypriv *mp; AttributeDescription *ad_nc = slap_schema.si_ad_namingContexts; AttributeDescription *ad_mc = slap_schema.si_ad_monitorContext; AttributeDescription *ad_seeAlso = NULL; const char *text = NULL; assert( be != NULL ); assert( monitor_ad_desc != NULL ); mi = ( struct monitorinfo * )be->be_private; if ( monitor_cache_get( mi, &monitor_subsys[SLAPD_MONITOR_DATABASE].mss_ndn, &e_database ) ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_database_init: " "unable to get entry '%s'\n", monitor_subsys[SLAPD_MONITOR_DATABASE].mss_ndn.bv_val, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_database_init: " "unable to get entry '%s'\n%s%s", monitor_subsys[SLAPD_MONITOR_DATABASE].mss_ndn.bv_val, "", "" ); #endif return( -1 ); } if ( slap_str2ad( "seeAlso", &ad_seeAlso, &text ) != LDAP_SUCCESS ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_database_init: " "unable to find 'seeAlso' attribute description\n", 0, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_database_init: " "unable to find 'seeAlso' attribute description\n", 0, 0, 0 ); #endif return( -1 ); } e_tmp = NULL; for ( i = nBackendDB; i--; ) { char buf[1024]; int j; be = &backendDB[i]; /* Subordinates are not exposed as their own naming context */ if ( SLAP_GLUE_SUBORDINATE( be ) ) { continue; } snprintf( buf, sizeof( buf ), "dn: cn=Database %d,%s\n" SLAPD_MONITOR_OBJECTCLASSES "cn: Database %d\n" "description: %s", i, monitor_subsys[SLAPD_MONITOR_DATABASE].mss_dn.bv_val, i, be->bd_info->bi_type ); e = str2entry( buf ); if ( e == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_database_init: " "unable to create entry 'cn=Database %d,%s'\n", i, monitor_subsys[SLAPD_MONITOR_DATABASE].mss_ndn.bv_val, 0 ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_database_init: " "unable to create entry 'cn=Database %d,%s'\n%s", i, monitor_subsys[SLAPD_MONITOR_DATABASE].mss_ndn.bv_val, "" ); #endif return( -1 ); } if ( be->be_flags & SLAP_BFLAG_MONITOR ) { attr_merge( e, ad_mc, be->be_suffix ); attr_merge( e_database, ad_mc, be->be_suffix ); } else { attr_merge( e, ad_nc, be->be_suffix ); attr_merge( e_database, ad_nc, be->be_suffix ); } for ( j = nBackendInfo; j--; ) { if ( backendInfo[ j ].bi_type == be->bd_info->bi_type ) { struct berval bv; snprintf( buf, sizeof( buf ), "cn=Backend %d,%s", j, monitor_subsys[SLAPD_MONITOR_BACKEND].mss_dn.bv_val ); bv.bv_val = buf; bv.bv_len = strlen( buf ); attr_merge_one( e, ad_seeAlso, &bv ); break; } } /* we must find it! */ assert( j >= 0 ); mp = ( struct monitorentrypriv * )ch_calloc( sizeof( struct monitorentrypriv ), 1 ); e->e_private = ( void * )mp; mp->mp_next = e_tmp; mp->mp_children = NULL; mp->mp_info = &monitor_subsys[SLAPD_MONITOR_DATABASE]; mp->mp_flags = monitor_subsys[SLAPD_MONITOR_DATABASE].mss_flags | MONITOR_F_SUB; if ( monitor_cache_add( mi, e ) ) { #ifdef NEW_LOGGING LDAP_LOG( OPERATION, CRIT, "monitor_subsys_database_init: " "unable to add entry 'cn=Database %d,%s'\n", i, monitor_subsys[SLAPD_MONITOR_DATABASE].mss_ndn.bv_val, 0 ); #else Debug( LDAP_DEBUG_ANY, "monitor_subsys_database_init: " "unable to add entry 'cn=Database %d,%s'\n", i, monitor_subsys[SLAPD_MONITOR_DATABASE].mss_ndn.bv_val, 0 ); #endif return( -1 ); } #if defined(LDAP_SLAPI) monitor_back_add_plugin( be, e ); #endif /* defined(LDAP_SLAPI) */ e_tmp = e; } mp = ( struct monitorentrypriv * )e_database->e_private; mp->mp_children = e_tmp; monitor_cache_release( mi, e_database ); return( 0 ); }
/********************************************************** * * Search * **********************************************************/ int perl_back_search( Operation *op, SlapReply *rs ) { PerlBackend *perl_back = (PerlBackend *)op->o_bd->be_private; int count ; AttributeName *an; Entry *e; char *buf; int i; PERL_SET_CONTEXT( PERL_INTERPRETER ); ldap_pvt_thread_mutex_lock( &perl_interpreter_mutex ); { dSP; ENTER; SAVETMPS; PUSHMARK(sp) ; XPUSHs( perl_back->pb_obj_ref ); XPUSHs(sv_2mortal(newSVpv( op->o_req_ndn.bv_val , op->o_req_ndn.bv_len))); XPUSHs(sv_2mortal(newSViv( op->ors_scope ))); XPUSHs(sv_2mortal(newSViv( op->ors_deref ))); XPUSHs(sv_2mortal(newSViv( op->ors_slimit ))); XPUSHs(sv_2mortal(newSViv( op->ors_tlimit ))); XPUSHs(sv_2mortal(newSVpv( op->ors_filterstr.bv_val , op->ors_filterstr.bv_len))); XPUSHs(sv_2mortal(newSViv( op->ors_attrsonly ))); for ( an = op->ors_attrs; an && an->an_name.bv_val; an++ ) { XPUSHs(sv_2mortal(newSVpv( an->an_name.bv_val , an->an_name.bv_len))); } PUTBACK; count = call_method("search", G_ARRAY ); SPAGAIN; if (count < 1) { croak("Big trouble in back_search\n") ; } if ( count > 1 ) { for ( i = 1; i < count; i++ ) { buf = POPp; if ( (e = str2entry( buf )) == NULL ) { Debug( LDAP_DEBUG_ANY, "str2entry(%s) failed\n", buf, 0, 0 ); } else { int send_entry; if (perl_back->pb_filter_search_results) send_entry = (test_filter( op, e, op->ors_filter ) == LDAP_COMPARE_TRUE); else send_entry = 1; if (send_entry) { rs->sr_entry = e; rs->sr_attrs = op->ors_attrs; rs->sr_flags = REP_ENTRY_MODIFIABLE; rs->sr_err = LDAP_SUCCESS; rs->sr_err = send_search_entry( op, rs ); rs->sr_flags = 0; rs->sr_attrs = NULL; rs->sr_entry = NULL; if ( rs->sr_err == LDAP_SIZELIMIT_EXCEEDED || rs->sr_err == LDAP_BUSY ) { goto done; } } entry_free( e ); } } } /* * We grab the return code last because the stack comes * from perl in reverse order. * * ex perl: return ( 0, $res_1, $res_2 ); * * ex stack: <$res_2> <$res_1> <0> */ rs->sr_err = POPi; done:; PUTBACK; FREETMPS; LEAVE; } ldap_pvt_thread_mutex_unlock( &perl_interpreter_mutex ); send_ldap_result( op, rs ); return 0; }
/* returns entry with reader/writer lock */ Entry * id2entry_rw( Backend *be, ID id, int rw ) { struct ldbminfo *li = (struct ldbminfo *) be->be_private; DBCache *db; Datum key, data; Entry *e; #ifndef WORDS_BIGENDIAN ID id2; #endif ldbm_datum_init( key ); ldbm_datum_init( data ); #ifdef NEW_LOGGING LDAP_LOG( INDEX, ENTRY, "id2entry_rw: %s (%ld)\n", rw ? "write" : "read", id, 0 ); #else Debug( LDAP_DEBUG_TRACE, "=> id2entry_%s( %ld )\n", rw ? "w" : "r", id, 0 ); #endif if ( (e = cache_find_entry_id( &li->li_cache, id, rw )) != NULL ) { #ifdef NEW_LOGGING LDAP_LOG( INDEX, DETAIL1, "id2entry_rw: %s (%ld) 0x%lx (cache).\n", rw ? "write" : "read", id, (unsigned long)e ); #else Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) 0x%lx (cache)\n", rw ? "w" : "r", id, (unsigned long) e ); #endif return( e ); } if ( (db = ldbm_cache_open( be, "id2entry", LDBM_SUFFIX, LDBM_WRCREAT )) == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( INDEX, ERR, "id2entry_rw: could not open id2entry%s\n", LDBM_SUFFIX, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "Could not open id2entry%s\n", LDBM_SUFFIX, 0, 0 ); #endif return( NULL ); } #ifdef WORDS_BIGENDIAN key.dptr = (char *) &id; #else id2 = htonl(id); key.dptr = (char *) &id2; #endif key.dsize = sizeof(ID); data = ldbm_cache_fetch( db, key ); if ( data.dptr == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( INDEX, ERR, "id2entry_rw: (%ld) not found\n", id, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) not found\n", rw ? "w" : "r", id, 0 ); #endif ldbm_cache_close( be, db ); return( NULL ); } e = str2entry( data.dptr ); ldbm_datum_free( db->dbc_db, data ); ldbm_cache_close( be, db ); if ( e == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( INDEX, ERR, "id2entry_rw: %s of %ld failed\n", rw ? "write" : "read", id, 0); #else Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) (failed)\n", rw ? "w" : "r", id, 0 ); #endif return( NULL ); } e->e_id = id; if( cache_add_entry_rw( &li->li_cache, e, rw ) != 0 ) { entry_free( e ); /* XXX this is a kludge. * maybe the entry got added underneath us * There are many underlying race condtions in the cache/disk code. */ if ( (e = cache_find_entry_id( &li->li_cache, id, rw )) != NULL ) { #ifdef NEW_LOGGING LDAP_LOG( INDEX, DETAIL1, "id2entry_rw: %s of %ld 0x%lx (cache)\n", rw ? "write" : "read", id, (unsigned long)e ); #else Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) 0x%lx (cache)\n", rw ? "w" : "r", id, (unsigned long) e ); #endif return( e ); } #ifdef NEW_LOGGING LDAP_LOG( INDEX, ERR, "id2entry_rw: %s of %ld (cache add failed)\n", rw ? "write" : "read", id, 0 ); #else Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) (cache add failed)\n", rw ? "w" : "r", id, 0 ); #endif return NULL; } #ifdef NEW_LOGGING LDAP_LOG( INDEX, ENTRY, "id2entry_rw: %s of %ld 0x%lx (disk)\n", rw ? "write" : "read", id, (unsigned long)e ); #else Debug( LDAP_DEBUG_TRACE, "<= id2entry_%s( %ld ) 0x%lx (disk)\n", rw ? "w" : "r", id, (unsigned long) e ); #endif /* marks the entry as committed, so it will get added to the cache * when the lock is released */ cache_entry_commit( e ); return( e ); }