static void pwdfile_search( struct ldop *op, FILE *ofp ) { struct passwd *pw; struct ldentry *entry; int oneentry; oneentry = ( strchr( op->ldop_dn, '@' ) != NULL ); for ( pw = getpwent(); pw != NULL; pw = getpwent()) { if (( entry = pw2entry( op, pw )) != NULL ) { if ( oneentry ) { if ( strcasecmp( op->ldop_dn, entry->lde_dn ) == 0 ) { write_entry( op, entry, ofp ); break; } } else if ( test_filter( op, entry ) == LDAP_COMPARE_TRUE ) { write_entry( op, entry, ofp ); } free_entry( entry ); } } endpwent(); write_result( ofp, LDAP_SUCCESS, NULL, NULL ); }
int passwd_back_search( Operation *op, SlapReply *rs ) { struct passwd *pw; time_t stoptime = (time_t)-1; LDAPRDN rdn = NULL; struct berval parent = BER_BVNULL; AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass; if ( op->ors_tlimit != SLAP_NO_LIMIT ) { stoptime = op->o_time + op->ors_tlimit; } /* Handle a query for the base of this backend */ if ( be_issuffix( op->o_bd, &op->o_req_ndn ) ) { struct berval val; rs->sr_matched = op->o_req_dn.bv_val; if( op->ors_scope != LDAP_SCOPE_ONELEVEL ) { AttributeDescription *desc = NULL; char *next; Entry e = { 0 }; /* Create an entry corresponding to the base DN */ e.e_name.bv_val = ch_strdup( op->o_req_dn.bv_val ); e.e_name.bv_len = op->o_req_dn.bv_len; e.e_nname.bv_val = ch_strdup( op->o_req_ndn.bv_val ); e.e_nname.bv_len = op->o_req_ndn.bv_len; /* Use the first attribute of the DN * as an attribute within the entry itself. */ if( ldap_bv2rdn( &op->o_req_dn, &rdn, &next, LDAP_DN_FORMAT_LDAP ) ) { rs->sr_err = LDAP_INVALID_DN_SYNTAX; goto done; } if( slap_bv2ad( &rdn[0]->la_attr, &desc, &rs->sr_text )) { rs->sr_err = LDAP_NO_SUCH_OBJECT; ldap_rdnfree(rdn); goto done; } attr_merge_normalize_one( &e, desc, &rdn[0]->la_value, NULL ); ldap_rdnfree(rdn); rdn = NULL; /* Every entry needs an objectclass. We don't really * know if our hardcoded choice here agrees with the * DN that was configured for this backend, but it's * better than nothing. * * should be a configuratable item */ BER_BVSTR( &val, "organizationalUnit" ); attr_merge_one( &e, ad_objectClass, &val, NULL ); if ( test_filter( op, &e, op->ors_filter ) == LDAP_COMPARE_TRUE ) { rs->sr_entry = &e; rs->sr_attrs = op->ors_attrs; rs->sr_flags = REP_ENTRY_MODIFIABLE; send_search_entry( op, rs ); rs->sr_flags = 0; rs->sr_attrs = NULL; } entry_clean( &e ); } if ( op->ors_scope != LDAP_SCOPE_BASE ) { /* check all our "children" */ ldap_pvt_thread_mutex_lock( &passwd_mutex ); pw_start( op->o_bd ); for ( pw = getpwent(); pw != NULL; pw = getpwent() ) { Entry e = { 0 }; /* check for abandon */ if ( op->o_abandon ) { endpwent(); ldap_pvt_thread_mutex_unlock( &passwd_mutex ); return( SLAPD_ABANDON ); } /* check time limit */ if ( op->ors_tlimit != SLAP_NO_LIMIT && slap_get_time() > stoptime ) { send_ldap_error( op, rs, LDAP_TIMELIMIT_EXCEEDED, NULL ); endpwent(); ldap_pvt_thread_mutex_unlock( &passwd_mutex ); return( 0 ); } if ( pw2entry( op->o_bd, pw, &e ) ) { rs->sr_err = LDAP_OTHER; endpwent(); ldap_pvt_thread_mutex_unlock( &passwd_mutex ); goto done; } if ( test_filter( op, &e, op->ors_filter ) == LDAP_COMPARE_TRUE ) { /* check size limit */ if ( --op->ors_slimit == -1 ) { send_ldap_error( op, rs, LDAP_SIZELIMIT_EXCEEDED, NULL ); endpwent(); ldap_pvt_thread_mutex_unlock( &passwd_mutex ); return( 0 ); } rs->sr_entry = &e; rs->sr_attrs = op->ors_attrs; rs->sr_flags = REP_ENTRY_MODIFIABLE; send_search_entry( op, rs ); rs->sr_flags = 0; rs->sr_entry = NULL; } entry_clean( &e ); } endpwent(); ldap_pvt_thread_mutex_unlock( &passwd_mutex ); } } else { char *next; Entry e = { 0 }; int rc; if (! be_issuffix( op->o_bd, &op->o_req_ndn ) ) { dnParent( &op->o_req_ndn, &parent ); } /* This backend is only one layer deep. Don't answer requests for * anything deeper than that. */ if( !be_issuffix( op->o_bd, &parent ) ) { int i; for( i=0; op->o_bd->be_nsuffix[i].bv_val != NULL; i++ ) { if( dnIsSuffix( &op->o_req_ndn, &op->o_bd->be_nsuffix[i] ) ) { rs->sr_matched = op->o_bd->be_suffix[i].bv_val; break; } } rs->sr_err = LDAP_NO_SUCH_OBJECT; goto done; } if( op->ors_scope == LDAP_SCOPE_ONELEVEL ) { goto done; } if ( ldap_bv2rdn( &op->o_req_dn, &rdn, &next, LDAP_DN_FORMAT_LDAP )) { rs->sr_err = LDAP_OTHER; goto done; } ldap_pvt_thread_mutex_lock( &passwd_mutex ); pw_start( op->o_bd ); pw = getpwnam( rdn[0]->la_value.bv_val ); if ( pw == NULL ) { rs->sr_matched = parent.bv_val; rs->sr_err = LDAP_NO_SUCH_OBJECT; ldap_pvt_thread_mutex_unlock( &passwd_mutex ); goto done; } rc = pw2entry( op->o_bd, pw, &e ); ldap_pvt_thread_mutex_unlock( &passwd_mutex ); if ( rc ) { rs->sr_err = LDAP_OTHER; goto done; } if ( test_filter( op, &e, op->ors_filter ) == LDAP_COMPARE_TRUE ) { rs->sr_entry = &e; rs->sr_attrs = op->ors_attrs; rs->sr_flags = REP_ENTRY_MODIFIABLE; send_search_entry( op, rs ); rs->sr_flags = 0; rs->sr_entry = NULL; rs->sr_attrs = NULL; } entry_clean( &e ); } done: if( rs->sr_err != LDAP_NO_SUCH_OBJECT ) rs->sr_matched = NULL; send_ldap_result( op, rs ); if( rdn != NULL ) ldap_rdnfree( rdn ); return( 0 ); }