int tester_ignore_str2errlist( const char *err ) { int i; char **errs = ldap_str2charray( err, "," ); for ( i = 0; errs[ i ] != NULL; i++ ) { /* TODO: allow <err>:<prog> to ignore <err> only when <prog> */ (void)tester_ignore_str2err( errs[ i ] ); } ldap_charray_free( errs ); return 0; }
void slapd_slp_init( const char* urls ) { int i; slapd_srvurls = ldap_str2charray( urls, " " ); if( slapd_srvurls == NULL ) return; /* find and expand INADDR_ANY URLs */ for( i=0; slapd_srvurls[i] != NULL; i++ ) { if( strcmp( slapd_srvurls[i], "ldap:///" ) == 0) { char *host = ldap_pvt_get_fqdn( NULL ); if ( host != NULL ) { slapd_srvurls[i] = (char *) ch_realloc( slapd_srvurls[i], strlen( host ) + sizeof( LDAP_SRVTYPE_PREFIX ) ); strcpy( lutil_strcopy(slapd_srvurls[i], LDAP_SRVTYPE_PREFIX ), host ); ch_free( host ); } } else if ( strcmp( slapd_srvurls[i], "ldaps:///" ) == 0) { char *host = ldap_pvt_get_fqdn( NULL ); if ( host != NULL ) { slapd_srvurls[i] = (char *) ch_realloc( slapd_srvurls[i], strlen( host ) + sizeof( LDAPS_SRVTYPE_PREFIX ) ); strcpy( lutil_strcopy(slapd_srvurls[i], LDAPS_SRVTYPE_PREFIX ), host ); ch_free( host ); } } } /* open the SLP handle */ SLPOpen( "en", 0, &slapd_hslp ); }
int dnssrv_back_search( Operation *op, SlapReply *rs ) { int i; int rc; char *domain = NULL; char *hostlist = NULL; char **hosts = NULL; char *refdn; struct berval nrefdn = BER_BVNULL; BerVarray urls = NULL; int manageDSAit; rs->sr_ref = NULL; if ( BER_BVISEMPTY( &op->o_req_ndn ) ) { /* FIXME: need some means to determine whether the database * is a glue instance; if we got here with empty DN, then * we passed this same test in dnssrv_back_referrals() */ if ( !SLAP_GLUE_INSTANCE( op->o_bd ) ) { rs->sr_err = LDAP_UNWILLING_TO_PERFORM; rs->sr_text = "DNS SRV operation upon null (empty) DN disallowed"; } else { rs->sr_err = LDAP_SUCCESS; } goto done; } manageDSAit = get_manageDSAit( op ); /* * FIXME: we may return a referral if manageDSAit is not set */ if ( !manageDSAit ) { send_ldap_error( op, rs, LDAP_UNWILLING_TO_PERFORM, "manageDSAit must be set" ); goto done; } if( ldap_dn2domain( op->o_req_dn.bv_val, &domain ) || domain == NULL ) { rs->sr_err = LDAP_REFERRAL; rs->sr_ref = default_referral; send_ldap_result( op, rs ); rs->sr_ref = NULL; goto done; } Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" -> domain=\"%s\"\n", op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "", domain ); if( ( rc = ldap_domain2hostlist( domain, &hostlist ) ) ) { Debug( LDAP_DEBUG_TRACE, "DNSSRV: domain2hostlist returned %d\n", rc ); send_ldap_error( op, rs, LDAP_NO_SUCH_OBJECT, "no DNS SRV RR available for DN" ); goto done; } hosts = ldap_str2charray( hostlist, " " ); if( hosts == NULL ) { Debug( LDAP_DEBUG_TRACE, "DNSSRV: str2charray error\n" ); send_ldap_error( op, rs, LDAP_OTHER, "problem processing DNS SRV records for DN" ); goto done; } for( i=0; hosts[i] != NULL; i++) { struct berval url; url.bv_len = STRLENOF( "ldap://" ) + strlen(hosts[i]); url.bv_val = ch_malloc( url.bv_len + 1 ); strcpy( url.bv_val, "ldap://" ); strcpy( &url.bv_val[STRLENOF( "ldap://" )], hosts[i] ); if( ber_bvarray_add( &urls, &url ) < 0 ) { free( url.bv_val ); send_ldap_error( op, rs, LDAP_OTHER, "problem processing DNS SRV records for DN" ); goto done; } } Debug( LDAP_DEBUG_STATS, "%s DNSSRV p=%d dn=\"%s\" url=\"%s\"\n", op->o_log_prefix, op->o_protocol, op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "", urls[0].bv_val ); Debug( LDAP_DEBUG_TRACE, "DNSSRV: ManageDSAit scope=%d dn=\"%s\" -> url=\"%s\"\n", op->oq_search.rs_scope, op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "", urls[0].bv_val ); rc = ldap_domain2dn(domain, &refdn); if( rc != LDAP_SUCCESS ) { send_ldap_error( op, rs, LDAP_OTHER, "DNS SRV problem processing manageDSAit control" ); goto done; } else { struct berval bv; bv.bv_val = refdn; bv.bv_len = strlen( refdn ); rc = dnNormalize( 0, NULL, NULL, &bv, &nrefdn, op->o_tmpmemctx ); if( rc != LDAP_SUCCESS ) { send_ldap_error( op, rs, LDAP_OTHER, "DNS SRV problem processing manageDSAit control" ); goto done; } } if( !dn_match( &nrefdn, &op->o_req_ndn ) ) { /* requested dn is subordinate */ Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" subordinate to refdn=\"%s\"\n", op->o_req_dn.bv_len ? op->o_req_dn.bv_val : "", refdn == NULL ? "" : refdn ); rs->sr_matched = refdn; rs->sr_err = LDAP_NO_SUCH_OBJECT; send_ldap_result( op, rs ); rs->sr_matched = NULL; } else if ( op->oq_search.rs_scope == LDAP_SCOPE_ONELEVEL ) { send_ldap_error( op, rs, LDAP_SUCCESS, NULL ); } else { Entry e = { 0 }; AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass; AttributeDescription *ad_ref = slap_schema.si_ad_ref; 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; e.e_attrs = NULL; e.e_private = NULL; attr_merge_one( &e, ad_objectClass, &slap_schema.si_oc_referral->soc_cname, NULL ); attr_merge_one( &e, ad_objectClass, &slap_schema.si_oc_extensibleObject->soc_cname, NULL ); if ( ad_dc ) { char *p; struct berval bv; bv.bv_val = domain; p = strchr( bv.bv_val, '.' ); if ( p == bv.bv_val ) { bv.bv_len = 1; } else if ( p != NULL ) { bv.bv_len = p - bv.bv_val; } else { bv.bv_len = strlen( bv.bv_val ); } attr_merge_normalize_one( &e, ad_dc, &bv, NULL ); } if ( ad_associatedDomain ) { struct berval bv; ber_str2bv( domain, 0, 0, &bv ); attr_merge_normalize_one( &e, ad_associatedDomain, &bv, NULL ); } attr_merge_normalize_one( &e, ad_ref, urls, NULL ); rc = test_filter( op, &e, op->oq_search.rs_filter ); if( rc == LDAP_COMPARE_TRUE ) { rs->sr_entry = &e; rs->sr_attrs = op->oq_search.rs_attrs; rs->sr_flags = REP_ENTRY_MODIFIABLE; send_search_entry( op, rs ); rs->sr_entry = NULL; rs->sr_attrs = NULL; rs->sr_flags = 0; } entry_clean( &e ); rs->sr_err = LDAP_SUCCESS; send_ldap_result( op, rs ); } free( refdn ); if ( nrefdn.bv_val ) free( nrefdn.bv_val ); done: if( domain != NULL ) ch_free( domain ); if( hostlist != NULL ) ch_free( hostlist ); if( hosts != NULL ) ldap_charray_free( hosts ); if( urls != NULL ) ber_bvarray_free( urls ); return 0; }
int dnssrv_back_referrals( Operation *op, SlapReply *rs ) { int i; int rc = LDAP_OTHER; char *domain = NULL; char *hostlist = NULL; char **hosts = NULL; BerVarray urls = NULL; if ( BER_BVISEMPTY( &op->o_req_dn ) ) { /* FIXME: need some means to determine whether the database * is a glue instance */ if ( SLAP_GLUE_INSTANCE( op->o_bd ) ) { return LDAP_SUCCESS; } rs->sr_text = "DNS SRV operation upon null (empty) DN disallowed"; return LDAP_UNWILLING_TO_PERFORM; } if( get_manageDSAit( op ) ) { if( op->o_tag == LDAP_REQ_SEARCH ) { return LDAP_SUCCESS; } rs->sr_text = "DNS SRV problem processing manageDSAit control"; return LDAP_OTHER; } if( ldap_dn2domain( op->o_req_dn.bv_val, &domain ) || domain == NULL ) { rs->sr_err = LDAP_REFERRAL; rs->sr_ref = default_referral; send_ldap_result( op, rs ); rs->sr_ref = NULL; return LDAP_REFERRAL; } Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" -> domain=\"%s\"\n", op->o_req_dn.bv_val, domain, 0 ); i = ldap_domain2hostlist( domain, &hostlist ); if ( i ) { Debug( LDAP_DEBUG_TRACE, "DNSSRV: domain2hostlist(%s) returned %d\n", domain, i, 0 ); rs->sr_text = "no DNS SRV RR available for DN"; rc = LDAP_NO_SUCH_OBJECT; goto done; } hosts = ldap_str2charray( hostlist, " " ); if( hosts == NULL ) { Debug( LDAP_DEBUG_TRACE, "DNSSRV: str2charrary error\n", 0, 0, 0 ); rs->sr_text = "problem processing DNS SRV records for DN"; goto done; } for( i=0; hosts[i] != NULL; i++) { struct berval url; url.bv_len = STRLENOF( "ldap://" ) + strlen( hosts[i] ); url.bv_val = ch_malloc( url.bv_len + 1 ); strcpy( url.bv_val, "ldap://" ); strcpy( &url.bv_val[STRLENOF( "ldap://" )], hosts[i] ); if ( ber_bvarray_add( &urls, &url ) < 0 ) { free( url.bv_val ); rs->sr_text = "problem processing DNS SRV records for DN"; goto done; } } Statslog( LDAP_DEBUG_STATS, "%s DNSSRV p=%d dn=\"%s\" url=\"%s\"\n", op->o_log_prefix, op->o_protocol, op->o_req_dn.bv_val, urls[0].bv_val, 0 ); Debug( LDAP_DEBUG_TRACE, "DNSSRV: dn=\"%s\" -> url=\"%s\"\n", op->o_req_dn.bv_val, urls[0].bv_val, 0 ); rs->sr_ref = urls; send_ldap_error( op, rs, LDAP_REFERRAL, "DNS SRV generated referrals" ); rs->sr_ref = NULL; rc = LDAP_REFERRAL; done: if( domain != NULL ) ch_free( domain ); if( hostlist != NULL ) ch_free( hostlist ); if( hosts != NULL ) ldap_charray_free( hosts ); ber_bvarray_free( urls ); return rc; }
static int rc_cf_gen( ConfigArgs *c ) { slap_overinst *on = (slap_overinst *)c->bi; retcode_t *rd = (retcode_t *)on->on_bi.bi_private; int rc = ARG_BAD_CONF; if ( c->op == SLAP_CONFIG_EMIT ) { switch( c->type ) { case RC_PARENT: if ( !BER_BVISEMPTY( &rd->rd_pdn )) { rc = value_add_one( &c->rvalue_vals, &rd->rd_pdn ); if ( rc == 0 ) { rc = value_add_one( &c->rvalue_nvals, &rd->rd_npdn ); } return rc; } rc = 0; break; case RC_ITEM: { retcode_item_t *rdi; int i; for ( rdi = rd->rd_item, i = 0; rdi; rdi = rdi->rdi_next, i++ ) { char buf[4096]; struct berval bv; char *ptr; bv.bv_len = snprintf( buf, sizeof( buf ), SLAP_X_ORDERED_FMT, i ); bv.bv_len += rdi->rdi_line.bv_len; ptr = bv.bv_val = ch_malloc( bv.bv_len + 1 ); ptr = lutil_strcopy( ptr, buf ); ptr = lutil_strncopy( ptr, rdi->rdi_line.bv_val, rdi->rdi_line.bv_len ); ber_bvarray_add( &c->rvalue_vals, &bv ); } rc = 0; } break; default: LDAP_BUG(); break; } return rc; } else if ( c->op == LDAP_MOD_DELETE ) { switch( c->type ) { case RC_PARENT: if ( rd->rd_pdn.bv_val ) { ber_memfree ( rd->rd_pdn.bv_val ); rc = 0; } if ( rd->rd_npdn.bv_val ) { ber_memfree ( rd->rd_npdn.bv_val ); } break; case RC_ITEM: if ( c->valx == -1 ) { retcode_item_t *rdi, *next; for ( rdi = rd->rd_item; rdi != NULL; rdi = next ) { next = rdi->rdi_next; retcode_item_destroy( rdi ); } } else { retcode_item_t **rdip, *rdi; int i; for ( rdip = &rd->rd_item, i = 0; i <= c->valx && *rdip; i++, rdip = &(*rdip)->rdi_next ) ; if ( *rdip == NULL ) { return 1; } rdi = *rdip; *rdip = rdi->rdi_next; retcode_item_destroy( rdi ); } rc = 0; break; default: LDAP_BUG(); break; } return rc; /* FIXME */ } switch( c->type ) { case RC_PARENT: if ( rd->rd_pdn.bv_val ) { ber_memfree ( rd->rd_pdn.bv_val ); } if ( rd->rd_npdn.bv_val ) { ber_memfree ( rd->rd_npdn.bv_val ); } rd->rd_pdn = c->value_dn; rd->rd_npdn = c->value_ndn; rc = 0; break; case RC_ITEM: { retcode_item_t rdi = { BER_BVNULL }, **rdip; struct berval bv, rdn, nrdn; char *next = NULL; int i; if ( c->argc < 3 ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "\"retcode-item <RDN> <retcode> [<text>]\": " "missing args" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } ber_str2bv( c->argv[ 1 ], 0, 0, &bv ); rc = dnPrettyNormal( NULL, &bv, &rdn, &nrdn, NULL ); if ( rc != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "unable to normalize RDN \"%s\": %d", c->argv[ 1 ], rc ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } if ( !dnIsOneLevelRDN( &nrdn ) ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "value \"%s\" is not a RDN", c->argv[ 1 ] ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } if ( BER_BVISNULL( &rd->rd_npdn ) ) { /* FIXME: we use the database suffix */ if ( c->be->be_nsuffix == NULL ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "either \"retcode-parent\" " "or \"suffix\" must be defined" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } ber_dupbv( &rd->rd_pdn, &c->be->be_suffix[ 0 ] ); ber_dupbv( &rd->rd_npdn, &c->be->be_nsuffix[ 0 ] ); } build_new_dn( &rdi.rdi_dn, &rd->rd_pdn, &rdn, NULL ); build_new_dn( &rdi.rdi_ndn, &rd->rd_npdn, &nrdn, NULL ); ch_free( rdn.bv_val ); ch_free( nrdn.bv_val ); rdi.rdi_err = strtol( c->argv[ 2 ], &next, 0 ); if ( next == c->argv[ 2 ] || next[ 0 ] != '\0' ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "unable to parse return code \"%s\"", c->argv[ 2 ] ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } rdi.rdi_mask = SN_DG_OP_ALL; if ( c->argc > 3 ) { for ( i = 3; i < c->argc; i++ ) { if ( strncasecmp( c->argv[ i ], "op=", STRLENOF( "op=" ) ) == 0 ) { char **ops; int j; ops = ldap_str2charray( &c->argv[ i ][ STRLENOF( "op=" ) ], "," ); assert( ops != NULL ); rdi.rdi_mask = SN_DG_OP_NONE; for ( j = 0; ops[ j ] != NULL; j++ ) { if ( strcasecmp( ops[ j ], "add" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_ADD; } else if ( strcasecmp( ops[ j ], "bind" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_BIND; } else if ( strcasecmp( ops[ j ], "compare" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_COMPARE; } else if ( strcasecmp( ops[ j ], "delete" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_DELETE; } else if ( strcasecmp( ops[ j ], "modify" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_MODIFY; } else if ( strcasecmp( ops[ j ], "rename" ) == 0 || strcasecmp( ops[ j ], "modrdn" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_RENAME; } else if ( strcasecmp( ops[ j ], "search" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_SEARCH; } else if ( strcasecmp( ops[ j ], "extended" ) == 0 ) { rdi.rdi_mask |= SN_DG_EXTENDED; } else if ( strcasecmp( ops[ j ], "auth" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_AUTH; } else if ( strcasecmp( ops[ j ], "read" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_READ; } else if ( strcasecmp( ops[ j ], "write" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_WRITE; } else if ( strcasecmp( ops[ j ], "all" ) == 0 ) { rdi.rdi_mask |= SN_DG_OP_ALL; } else { snprintf( c->cr_msg, sizeof(c->cr_msg), "unknown op \"%s\"", ops[ j ] ); ldap_charray_free( ops ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } } ldap_charray_free( ops ); } else if ( strncasecmp( c->argv[ i ], "text=", STRLENOF( "text=" ) ) == 0 ) { if ( !BER_BVISNULL( &rdi.rdi_text ) ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "\"text\" already provided" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } ber_str2bv( &c->argv[ i ][ STRLENOF( "text=" ) ], 0, 1, &rdi.rdi_text ); } else if ( strncasecmp( c->argv[ i ], "matched=", STRLENOF( "matched=" ) ) == 0 ) { struct berval dn; if ( !BER_BVISNULL( &rdi.rdi_matched ) ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "\"matched\" already provided" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } ber_str2bv( &c->argv[ i ][ STRLENOF( "matched=" ) ], 0, 0, &dn ); if ( dnPretty( NULL, &dn, &rdi.rdi_matched, NULL ) != LDAP_SUCCESS ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "unable to prettify matched DN \"%s\"", &c->argv[ i ][ STRLENOF( "matched=" ) ] ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } } else if ( strncasecmp( c->argv[ i ], "ref=", STRLENOF( "ref=" ) ) == 0 ) { char **refs; int j; if ( rdi.rdi_ref != NULL ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "\"ref\" already provided" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } if ( rdi.rdi_err != LDAP_REFERRAL ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "providing \"ref\" " "along with a non-referral " "resultCode may cause slapd failures " "related to internal checks" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); } refs = ldap_str2charray( &c->argv[ i ][ STRLENOF( "ref=" ) ], " " ); assert( refs != NULL ); for ( j = 0; refs[ j ] != NULL; j++ ) { struct berval bv; ber_str2bv( refs[ j ], 0, 1, &bv ); ber_bvarray_add( &rdi.rdi_ref, &bv ); } ldap_charray_free( refs ); } else if ( strncasecmp( c->argv[ i ], "sleeptime=", STRLENOF( "sleeptime=" ) ) == 0 ) { if ( rdi.rdi_sleeptime != 0 ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "\"sleeptime\" already provided" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } if ( lutil_atoi( &rdi.rdi_sleeptime, &c->argv[ i ][ STRLENOF( "sleeptime=" ) ] ) ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "unable to parse \"sleeptime=%s\"", &c->argv[ i ][ STRLENOF( "sleeptime=" ) ] ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } } else if ( strncasecmp( c->argv[ i ], "unsolicited=", STRLENOF( "unsolicited=" ) ) == 0 ) { char *data; if ( !BER_BVISNULL( &rdi.rdi_unsolicited_oid ) ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "\"unsolicited\" already provided" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } data = strchr( &c->argv[ i ][ STRLENOF( "unsolicited=" ) ], ':' ); if ( data != NULL ) { struct berval oid; if ( ldif_parse_line2( &c->argv[ i ][ STRLENOF( "unsolicited=" ) ], &oid, &rdi.rdi_unsolicited_data, NULL ) ) { snprintf( c->cr_msg, sizeof(c->cr_msg), "unable to parse \"unsolicited\"" ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } ber_dupbv( &rdi.rdi_unsolicited_oid, &oid ); } else { ber_str2bv( &c->argv[ i ][ STRLENOF( "unsolicited=" ) ], 0, 1, &rdi.rdi_unsolicited_oid ); } } else if ( strncasecmp( c->argv[ i ], "flags=", STRLENOF( "flags=" ) ) == 0 ) { char *arg = &c->argv[ i ][ STRLENOF( "flags=" ) ]; if ( strcasecmp( arg, "disconnect" ) == 0 ) { rdi.rdi_flags |= RDI_PRE_DISCONNECT; } else if ( strcasecmp( arg, "pre-disconnect" ) == 0 ) { rdi.rdi_flags |= RDI_PRE_DISCONNECT; } else if ( strcasecmp( arg, "post-disconnect" ) == 0 ) { rdi.rdi_flags |= RDI_POST_DISCONNECT; } else { snprintf( c->cr_msg, sizeof(c->cr_msg), "unknown flag \"%s\"", arg ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } } else { snprintf( c->cr_msg, sizeof(c->cr_msg), "unknown option \"%s\"", c->argv[ i ] ); Debug( LDAP_DEBUG_CONFIG, "%s: retcode: %s\n", c->log, c->cr_msg ); return ARG_BAD_CONF; } } } rdi.rdi_line.bv_len = 2*(c->argc - 1) + c->argc - 2; for ( i = 1; i < c->argc; i++ ) { rdi.rdi_line.bv_len += strlen( c->argv[ i ] ); } next = rdi.rdi_line.bv_val = ch_malloc( rdi.rdi_line.bv_len + 1 ); for ( i = 1; i < c->argc; i++ ) { *next++ = '"'; next = lutil_strcopy( next, c->argv[ i ] ); *next++ = '"'; *next++ = ' '; } *--next = '\0'; for ( rdip = &rd->rd_item; *rdip; rdip = &(*rdip)->rdi_next ) /* go to last */ ; *rdip = ( retcode_item_t * )ch_malloc( sizeof( retcode_item_t ) ); *(*rdip) = rdi; rc = 0; } break; default: rc = SLAP_CONF_UNKNOWN; break; } return rc; }
int main( int argc, char *argv[]) { LDAPURLDesc lud = { 0 }; char *uri = NULL; int gotlud = 0; int nexts = 0; lud.lud_port = -1; lud.lud_scope = -1; while ( 1 ) { int opt = getopt( argc, argv, "S:h:p:b:a:s:f:E:H:" ); if ( opt == EOF ) { break; } if ( opt == 'H' ) { if ( gotlud ) { fprintf( stderr, "option -H incompatible with previous options\n" ); usage(); } if ( uri != NULL ) { fprintf( stderr, "URI already provided\n" ); usage(); } uri = optarg; continue; } switch ( opt ) { case 'S': case 'h': case 'p': case 'b': case 'a': case 's': case 'f': case 'E': if ( uri != NULL ) { fprintf( stderr, "option -%c incompatible with -H\n", opt ); usage(); } gotlud++; } switch ( opt ) { case 'S': if ( lud.lud_scheme != NULL ) { fprintf( stderr, "scheme already provided\n" ); usage(); } lud.lud_scheme = optarg; break; case 'h': if ( lud.lud_host != NULL ) { fprintf( stderr, "host already provided\n" ); usage(); } lud.lud_host = optarg; break; case 'p': if ( lud.lud_port != -1 ) { fprintf( stderr, "port already provided\n" ); usage(); } if ( lutil_atoi( &lud.lud_port, optarg ) ) { fprintf( stderr, "unable to parse port \"%s\"\n", optarg ); usage(); } break; case 'b': if ( lud.lud_dn != NULL ) { fprintf( stderr, "base already provided\n" ); usage(); } lud.lud_dn = optarg; break; case 'a': if ( lud.lud_attrs != NULL ) { fprintf( stderr, "attrs already provided\n" ); usage(); } lud.lud_attrs = ldap_str2charray( optarg, "," ); if ( lud.lud_attrs == NULL ) { fprintf( stderr, "unable to parse attrs list \"%s\"\n", optarg ); usage(); } break; case 's': if ( lud.lud_scope != -1 ) { fprintf( stderr, "scope already provided\n" ); usage(); } lud.lud_scope = ldap_pvt_str2scope( optarg ); if ( lud.lud_scope == -1 ) { fprintf( stderr, "unable to parse scope \"%s\"\n", optarg ); usage(); } break; case 'f': if ( lud.lud_filter != NULL ) { fprintf( stderr, "filter already provided\n" ); usage(); } lud.lud_filter = optarg; break; case 'E': lud.lud_exts = (char **)realloc( lud.lud_exts, sizeof( char * ) * ( nexts + 2 ) ); lud.lud_exts[ nexts++ ] = optarg; lud.lud_exts[ nexts ] = NULL; break; default: assert( opt != 'H' ); usage(); } } if ( uri != NULL ) { return do_uri_explode( uri ); } return do_uri_create( &lud ); }
static int bdb_cf_gen( ConfigArgs *c ) { struct bdb_info *bdb = c->be->be_private; int rc; if ( c->op == SLAP_CONFIG_EMIT ) { rc = 0; switch( c->type ) { case BDB_MODE: { char buf[64]; struct berval bv; bv.bv_len = snprintf( buf, sizeof(buf), "0%o", bdb->bi_dbenv_mode ); if ( bv.bv_len > 0 && bv.bv_len < sizeof(buf) ) { bv.bv_val = buf; value_add_one( &c->rvalue_vals, &bv ); } else { rc = 1; } } break; case BDB_CHKPT: if ( bdb->bi_txn_cp ) { char buf[64]; struct berval bv; bv.bv_len = snprintf( buf, sizeof(buf), "%d %d", bdb->bi_txn_cp_kbyte, bdb->bi_txn_cp_min ); if ( bv.bv_len > 0 && bv.bv_len < sizeof(buf) ) { bv.bv_val = buf; value_add_one( &c->rvalue_vals, &bv ); } else { rc = 1; } } else { rc = 1; } break; case BDB_CRYPTFILE: if ( bdb->bi_db_crypt_file ) { c->value_string = ch_strdup( bdb->bi_db_crypt_file ); } else { rc = 1; } break; /* If a crypt file has been set, its contents are copied here. * But we don't want the key to be incorporated here. */ case BDB_CRYPTKEY: if ( !bdb->bi_db_crypt_file && !BER_BVISNULL( &bdb->bi_db_crypt_key )) { value_add_one( &c->rvalue_vals, &bdb->bi_db_crypt_key ); } else { rc = 1; } break; case BDB_DIRECTORY: if ( bdb->bi_dbenv_home ) { c->value_string = ch_strdup( bdb->bi_dbenv_home ); } else { rc = 1; } break; case BDB_CONFIG: if ( !( bdb->bi_flags & BDB_IS_OPEN ) && !bdb->bi_db_config ) { char buf[SLAP_TEXT_BUFLEN]; FILE *f = fopen( bdb->bi_db_config_path, "r" ); struct berval bv; if ( f ) { bdb->bi_flags |= BDB_HAS_CONFIG; while ( fgets( buf, sizeof(buf), f )) { ber_str2bv( buf, 0, 1, &bv ); if ( bv.bv_len > 0 && bv.bv_val[bv.bv_len-1] == '\n' ) { bv.bv_len--; bv.bv_val[bv.bv_len] = '\0'; } /* shouldn't need this, but ... */ if ( bv.bv_len > 0 && bv.bv_val[bv.bv_len-1] == '\r' ) { bv.bv_len--; bv.bv_val[bv.bv_len] = '\0'; } ber_bvarray_add( &bdb->bi_db_config, &bv ); } fclose( f ); } } if ( bdb->bi_db_config ) { int i; struct berval bv; bv.bv_val = c->log; for (i=0; !BER_BVISNULL(&bdb->bi_db_config[i]); i++) { bv.bv_len = sprintf( bv.bv_val, "{%d}%s", i, bdb->bi_db_config[i].bv_val ); value_add_one( &c->rvalue_vals, &bv ); } } if ( !c->rvalue_vals ) rc = 1; break; case BDB_NOSYNC: if ( bdb->bi_dbenv_xflags & DB_TXN_NOSYNC ) c->value_int = 1; break; case BDB_CHECKSUM: if ( bdb->bi_flags & BDB_CHKSUM ) c->value_int = 1; break; case BDB_INDEX: bdb_attr_index_unparse( bdb, &c->rvalue_vals ); if ( !c->rvalue_vals ) rc = 1; break; case BDB_LOCKD: rc = 1; if ( bdb->bi_lock_detect != DB_LOCK_DEFAULT ) { int i; for (i=0; !BER_BVISNULL(&bdb_lockd[i].word); i++) { if ( bdb->bi_lock_detect == (u_int32_t)bdb_lockd[i].mask ) { value_add_one( &c->rvalue_vals, &bdb_lockd[i].word ); rc = 0; break; } } } break; case BDB_SSTACK: c->value_int = bdb->bi_search_stack_depth; break; case BDB_PGSIZE: { struct bdb_db_pgsize *ps; char buf[SLAP_TEXT_BUFLEN]; struct berval bv; int rc = 1; bv.bv_val = buf; for ( ps = bdb->bi_pagesizes; ps; ps = ps->bdp_next ) { bv.bv_len = sprintf( buf, "%s %d", ps->bdp_name.bv_val, ps->bdp_size / 1024 ); value_add_one( &c->rvalue_vals, &bv ); rc = 0; } break; } } return rc; } else if ( c->op == LDAP_MOD_DELETE ) { rc = 0; switch( c->type ) { case BDB_MODE: #if 0 /* FIXME: does it make any sense to change the mode, * if we don't exec a chmod()? */ bdb->bi_dbenv_mode = SLAPD_DEFAULT_DB_MODE; break; #endif /* single-valued no-ops */ case BDB_LOCKD: case BDB_SSTACK: break; case BDB_CHKPT: if ( bdb->bi_txn_cp_task ) { struct re_s *re = bdb->bi_txn_cp_task; bdb->bi_txn_cp_task = NULL; ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ) ) ldap_pvt_runqueue_stoptask( &slapd_rq, re ); ldap_pvt_runqueue_remove( &slapd_rq, re ); ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); } bdb->bi_txn_cp = 0; break; case BDB_CONFIG: if ( c->valx < 0 ) { ber_bvarray_free( bdb->bi_db_config ); bdb->bi_db_config = NULL; } else { int i = c->valx; ch_free( bdb->bi_db_config[i].bv_val ); for (; bdb->bi_db_config[i].bv_val; i++) bdb->bi_db_config[i] = bdb->bi_db_config[i+1]; } bdb->bi_flags |= BDB_UPD_CONFIG; c->cleanup = bdb_cf_cleanup; break; /* Doesn't really make sense to change these on the fly; * the entire DB must be dumped and reloaded */ case BDB_CRYPTFILE: if ( bdb->bi_db_crypt_file ) { ch_free( bdb->bi_db_crypt_file ); bdb->bi_db_crypt_file = NULL; } /* FALLTHRU */ case BDB_CRYPTKEY: if ( !BER_BVISNULL( &bdb->bi_db_crypt_key )) { ch_free( bdb->bi_db_crypt_key.bv_val ); BER_BVZERO( &bdb->bi_db_crypt_key ); } break; case BDB_DIRECTORY: bdb->bi_flags |= BDB_RE_OPEN; bdb->bi_flags ^= BDB_HAS_CONFIG; ch_free( bdb->bi_dbenv_home ); bdb->bi_dbenv_home = NULL; ch_free( bdb->bi_db_config_path ); bdb->bi_db_config_path = NULL; c->cleanup = bdb_cf_cleanup; ldap_pvt_thread_pool_purgekey( bdb->bi_dbenv ); break; case BDB_NOSYNC: bdb->bi_dbenv->set_flags( bdb->bi_dbenv, DB_TXN_NOSYNC, 0 ); break; case BDB_CHECKSUM: bdb->bi_flags &= ~BDB_CHKSUM; break; case BDB_INDEX: if ( c->valx == -1 ) { int i; /* delete all (FIXME) */ for ( i = 0; i < bdb->bi_nattrs; i++ ) { bdb->bi_attrs[i]->ai_indexmask |= BDB_INDEX_DELETING; } bdb->bi_flags |= BDB_DEL_INDEX; c->cleanup = bdb_cf_cleanup; } else { struct berval bv, def = BER_BVC("default"); char *ptr; for (ptr = c->line; !isspace( (unsigned char) *ptr ); ptr++); bv.bv_val = c->line; bv.bv_len = ptr - bv.bv_val; if ( bvmatch( &bv, &def )) { bdb->bi_defaultmask = 0; } else { int i; char **attrs; char sep; sep = bv.bv_val[ bv.bv_len ]; bv.bv_val[ bv.bv_len ] = '\0'; attrs = ldap_str2charray( bv.bv_val, "," ); for ( i = 0; attrs[ i ]; i++ ) { AttributeDescription *ad = NULL; const char *text; AttrInfo *ai; slap_str2ad( attrs[ i ], &ad, &text ); /* if we got here... */ assert( ad != NULL ); ai = bdb_attr_mask( bdb, ad ); /* if we got here... */ assert( ai != NULL ); ai->ai_indexmask |= BDB_INDEX_DELETING; bdb->bi_flags |= BDB_DEL_INDEX; c->cleanup = bdb_cf_cleanup; } bv.bv_val[ bv.bv_len ] = sep; ldap_charray_free( attrs ); } } break; /* doesn't make sense on the fly; the DB file must be * recreated */ case BDB_PGSIZE: { struct bdb_db_pgsize *ps, **prev; int i; for ( i = 0, prev = &bdb->bi_pagesizes, ps = *prev; ps; prev = &ps->bdp_next, ps = ps->bdp_next, i++ ) { if ( c->valx == -1 || i == c->valx ) { *prev = ps->bdp_next; ch_free( ps ); ps = *prev; if ( i == c->valx ) break; } } } break; } return rc; } switch( c->type ) { case BDB_MODE: if ( ASCII_DIGIT( c->argv[1][0] ) ) { long mode; char *next; errno = 0; mode = strtol( c->argv[1], &next, 0 ); if ( errno != 0 || next == c->argv[1] || next[0] != '\0' ) { fprintf( stderr, "%s: " "unable to parse mode=\"%s\".\n", c->log, c->argv[1] ); return 1; } bdb->bi_dbenv_mode = mode; } else { char *m = c->argv[1]; int who, what, mode = 0; if ( strlen( m ) != STRLENOF("-rwxrwxrwx") ) { return 1; } if ( m[0] != '-' ) { return 1; } m++; for ( who = 0; who < 3; who++ ) { for ( what = 0; what < 3; what++, m++ ) { if ( m[0] == '-' ) { continue; } else if ( m[0] != "rwx"[what] ) { return 1; } mode += ((1 << (2 - what)) << 3*(2 - who)); } } bdb->bi_dbenv_mode = mode; } break; case BDB_CHKPT: { long l; bdb->bi_txn_cp = 1; if ( lutil_atolx( &l, c->argv[1], 0 ) != 0 ) { fprintf( stderr, "%s: " "invalid kbyte \"%s\" in \"checkpoint\".\n", c->log, c->argv[1] ); return 1; } bdb->bi_txn_cp_kbyte = l; if ( lutil_atolx( &l, c->argv[2], 0 ) != 0 ) { fprintf( stderr, "%s: " "invalid minutes \"%s\" in \"checkpoint\".\n", c->log, c->argv[2] ); return 1; } bdb->bi_txn_cp_min = l; /* If we're in server mode and time-based checkpointing is enabled, * submit a task to perform periodic checkpoints. */ if ((slapMode & SLAP_SERVER_MODE) && bdb->bi_txn_cp_min ) { struct re_s *re = bdb->bi_txn_cp_task; if ( re ) { re->interval.tv_sec = bdb->bi_txn_cp_min * 60; } else { if ( c->be->be_suffix == NULL || BER_BVISNULL( &c->be->be_suffix[0] ) ) { fprintf( stderr, "%s: " "\"checkpoint\" must occur after \"suffix\".\n", c->log ); return 1; } ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); bdb->bi_txn_cp_task = ldap_pvt_runqueue_insert( &slapd_rq, bdb->bi_txn_cp_min * 60, bdb_checkpoint, bdb, LDAP_XSTRING(bdb_checkpoint), c->be->be_suffix[0].bv_val ); ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); } } } break; case BDB_CONFIG: { char *ptr = c->line; struct berval bv; if ( c->op == SLAP_CONFIG_ADD ) { ptr += STRLENOF("dbconfig"); while (!isspace((unsigned char)*ptr)) ptr++; while (isspace((unsigned char)*ptr)) ptr++; } if ( bdb->bi_flags & BDB_IS_OPEN ) { bdb->bi_flags |= BDB_UPD_CONFIG; c->cleanup = bdb_cf_cleanup; } else { /* If we're just starting up... */ FILE *f; /* If a DB_CONFIG file exists, or we don't know the path * to the DB_CONFIG file, ignore these directives */ if (( bdb->bi_flags & BDB_HAS_CONFIG ) || !bdb->bi_db_config_path ) break; f = fopen( bdb->bi_db_config_path, "a" ); if ( f ) { /* FIXME: EBCDIC probably needs special handling */ fprintf( f, "%s\n", ptr ); fclose( f ); } } ber_str2bv( ptr, 0, 1, &bv ); ber_bvarray_add( &bdb->bi_db_config, &bv ); } break; case BDB_CRYPTFILE: rc = lutil_get_filed_password( c->value_string, &bdb->bi_db_crypt_key ); if ( rc == 0 ) { bdb->bi_db_crypt_file = c->value_string; } break; /* Cannot set key if file was already set */ case BDB_CRYPTKEY: if ( bdb->bi_db_crypt_file ) { rc = 1; } else { bdb->bi_db_crypt_key = c->value_bv; } break; case BDB_DIRECTORY: { FILE *f; char *ptr, *testpath; int len; len = strlen( c->value_string ); testpath = ch_malloc( len + STRLENOF(LDAP_DIRSEP) + STRLENOF("DUMMY") + 1 ); ptr = lutil_strcopy( testpath, c->value_string ); *ptr++ = LDAP_DIRSEP[0]; strcpy( ptr, "DUMMY" ); f = fopen( testpath, "w" ); if ( f ) { fclose( f ); unlink( testpath ); } ch_free( testpath ); if ( !f ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid path: %s", c->log, strerror( errno )); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } if ( bdb->bi_dbenv_home ) ch_free( bdb->bi_dbenv_home ); bdb->bi_dbenv_home = c->value_string; /* See if a DB_CONFIG file already exists here */ if ( bdb->bi_db_config_path ) ch_free( bdb->bi_db_config_path ); bdb->bi_db_config_path = ch_malloc( len + STRLENOF(LDAP_DIRSEP) + STRLENOF("DB_CONFIG") + 1 ); ptr = lutil_strcopy( bdb->bi_db_config_path, bdb->bi_dbenv_home ); *ptr++ = LDAP_DIRSEP[0]; strcpy( ptr, "DB_CONFIG" ); f = fopen( bdb->bi_db_config_path, "r" ); if ( f ) { bdb->bi_flags |= BDB_HAS_CONFIG; fclose(f); } } break; case BDB_NOSYNC: if ( c->value_int ) bdb->bi_dbenv_xflags |= DB_TXN_NOSYNC; else bdb->bi_dbenv_xflags &= ~DB_TXN_NOSYNC; if ( bdb->bi_flags & BDB_IS_OPEN ) { bdb->bi_dbenv->set_flags( bdb->bi_dbenv, DB_TXN_NOSYNC, c->value_int ); } break; case BDB_CHECKSUM: if ( c->value_int ) bdb->bi_flags |= BDB_CHKSUM; else bdb->bi_flags &= ~BDB_CHKSUM; break; case BDB_INDEX: rc = bdb_attr_index_config( bdb, c->fname, c->lineno, c->argc - 1, &c->argv[1], &c->reply); if( rc != LDAP_SUCCESS ) return 1; if (( bdb->bi_flags & BDB_IS_OPEN ) && !bdb->bi_index_task ) { /* Start the task as soon as we finish here. Set a long * interval (10 hours) so that it only gets scheduled once. */ if ( c->be->be_suffix == NULL || BER_BVISNULL( &c->be->be_suffix[0] ) ) { fprintf( stderr, "%s: " "\"index\" must occur after \"suffix\".\n", c->log ); return 1; } ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); bdb->bi_index_task = ldap_pvt_runqueue_insert( &slapd_rq, 36000, bdb_online_index, c->be, LDAP_XSTRING(bdb_online_index), c->be->be_suffix[0].bv_val ); ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); } break; case BDB_LOCKD: rc = verb_to_mask( c->argv[1], bdb_lockd ); if ( BER_BVISNULL(&bdb_lockd[rc].word) ) { fprintf( stderr, "%s: " "bad policy (%s) in \"lockDetect <policy>\" line\n", c->log, c->argv[1] ); return 1; } bdb->bi_lock_detect = (u_int32_t)rc; break; case BDB_SSTACK: if ( c->value_int < MINIMUM_SEARCH_STACK_DEPTH ) { fprintf( stderr, "%s: depth %d too small, using %d\n", c->log, c->value_int, MINIMUM_SEARCH_STACK_DEPTH ); c->value_int = MINIMUM_SEARCH_STACK_DEPTH; } bdb->bi_search_stack_depth = c->value_int; break; case BDB_PGSIZE: { struct bdb_db_pgsize *ps, **prev; int i, s; s = atoi(c->argv[2]); if ( s < 1 || s > 64 ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: size must be > 0 and <= 64: %d", c->log, s ); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } i = strlen(c->argv[1]); ps = ch_malloc( sizeof(struct bdb_db_pgsize) + i + 1 ); ps->bdp_next = NULL; ps->bdp_name.bv_len = i; ps->bdp_name.bv_val = (char *)(ps+1); strcpy( ps->bdp_name.bv_val, c->argv[1] ); ps->bdp_size = s * 1024; for ( prev = &bdb->bi_pagesizes; *prev; prev = &(*prev)->bdp_next ) ; *prev = ps; } break; } return 0; }
int main( int argc, char **argv ) { int i, j; char *uri = NULL; char *host = "localhost"; char *port = NULL; char *manager = NULL; char *passwd = NULL; char *dirname = NULL; char *progdir = NULL; int loops = LOOPS; char *outerloops = OUTERLOOPS; char *retries = RETRIES; char *delay = "0"; DIR *datadir; struct dirent *file; int friendly = 0; int chaserefs = 0; int noattrs = 0; int nobind = 0; int noinit = 1; char *ignore = NULL; /* search */ char *sfile = NULL; char *sreqs[MAXREQS]; char *sattrs[MAXREQS]; char *sbase[MAXREQS]; LDAPURLDesc *slud[MAXREQS]; int snum = 0; char *sargs[MAXARGS]; int sanum; int sextra_args = 0; char scmd[MAXPATHLEN]; int swamp = 0; char swampopt[sizeof("-SSS")]; /* static so that its address can be used in initializer below. */ static char sloops[LDAP_PVT_INTTYPE_CHARS(unsigned long)]; /* read */ char *rfile = NULL; char *rreqs[MAXREQS]; int rnum = 0; char *rargs[MAXARGS]; char *rflts[MAXREQS]; int ranum; int rextra_args = 0; char rcmd[MAXPATHLEN]; static char rloops[LDAP_PVT_INTTYPE_CHARS(unsigned long)]; /* addel */ char *afiles[MAXREQS]; int anum = 0; char *aargs[MAXARGS]; int aanum; char acmd[MAXPATHLEN]; static char aloops[LDAP_PVT_INTTYPE_CHARS(unsigned long)]; /* modrdn */ char *nfile = NULL; char *nreqs[MAXREQS]; int nnum = 0; char *nargs[MAXARGS]; int nanum; char ncmd[MAXPATHLEN]; static char nloops[LDAP_PVT_INTTYPE_CHARS(unsigned long)]; /* modify */ char *mfile = NULL; char *mreqs[MAXREQS]; char *mdn[MAXREQS]; int mnum = 0; char *margs[MAXARGS]; int manum; char mcmd[MAXPATHLEN]; static char mloops[LDAP_PVT_INTTYPE_CHARS(unsigned long)]; /* bind */ char *bfile = NULL; char *breqs[MAXREQS]; char *bcreds[MAXREQS]; char *battrs[MAXREQS]; int bnum = 0; char *bargs[MAXARGS]; int banum; char bcmd[MAXPATHLEN]; static char bloops[LDAP_PVT_INTTYPE_CHARS(unsigned long)]; char **bargs_extra = NULL; char *friendlyOpt = NULL; int pw_ask = 0; char *pw_file = NULL; /* extra action to do after bind... */ typedef struct extra_t { char *action; struct extra_t *next; } extra_t; extra_t *extra = NULL; int nextra = 0; tester_init( "slapd-tester", TESTER_TESTER ); sloops[0] = '\0'; rloops[0] = '\0'; aloops[0] = '\0'; nloops[0] = '\0'; mloops[0] = '\0'; bloops[0] = '\0'; while ( ( i = getopt( argc, argv, "AB:CD:d:FH:h:Ii:j:L:l:NP:p:r:St:Ww:y:" ) ) != EOF ) { switch ( i ) { case 'A': noattrs++; break; case 'B': { char **p, **b = ldap_str2charray( optarg, "," ); extra_t **epp; for ( epp = &extra; *epp; epp = &(*epp)->next ) ; for ( p = b; p[0]; p++ ) { *epp = calloc( 1, sizeof( extra_t ) ); (*epp)->action = p[0]; epp = &(*epp)->next; nextra++; } ldap_memfree( b ); } break; case 'C': chaserefs++; break; case 'D': /* slapd manager */ manager = ArgDup( optarg ); break; case 'd': /* data directory */ dirname = strdup( optarg ); break; case 'F': friendly++; break; case 'H': /* slapd uri */ uri = strdup( optarg ); break; case 'h': /* slapd host */ host = strdup( optarg ); break; case 'I': noinit = 0; break; case 'i': ignore = optarg; break; case 'j': /* the number of parallel clients */ if ( lutil_atoi( &maxkids, optarg ) != 0 ) { usage( argv[0], 'j' ); } break; case 'l': /* the number of loops per client */ if ( !isdigit( (unsigned char) optarg[0] ) ) { char **p, **l = ldap_str2charray( optarg, "," ); for ( p = l; p[0]; p++) { struct { struct berval type; char *buf; } types[] = { { BER_BVC( "add=" ), aloops }, { BER_BVC( "bind=" ), bloops }, { BER_BVC( "modify=" ), mloops }, { BER_BVC( "modrdn=" ), nloops }, { BER_BVC( "read=" ), rloops }, { BER_BVC( "search=" ), sloops }, { BER_BVNULL, NULL } }; int c, n; for ( c = 0; types[c].type.bv_val; c++ ) { if ( strncasecmp( p[0], types[c].type.bv_val, types[c].type.bv_len ) == 0 ) { break; } } if ( types[c].type.bv_val == NULL ) { usage( argv[0], 'l' ); } if ( lutil_atoi( &n, &p[0][types[c].type.bv_len] ) != 0 ) { usage( argv[0], 'l' ); } snprintf( types[c].buf, sizeof( aloops ), "%d", n ); } ldap_charray_free( l ); } else if ( lutil_atoi( &loops, optarg ) != 0 ) { usage( argv[0], 'l' ); } break; case 'L': /* the number of outerloops per client */ outerloops = strdup( optarg ); break; case 'N': nobind++; break; case 'P': /* prog directory */ progdir = strdup( optarg ); break; case 'p': /* the servers port number */ port = strdup( optarg ); break; case 'r': /* the number of retries in case of error */ retries = strdup( optarg ); break; case 'S': swamp++; break; case 't': /* the delay in seconds between each retry */ delay = strdup( optarg ); break; case 'w': /* the managers passwd */ passwd = ArgDup( optarg ); memset( optarg, '*', strlen( optarg ) ); break; case 'W': pw_ask++; break; case 'y': pw_file = optarg; break; default: usage( argv[0], '\0' ); break; } } if (( dirname == NULL ) || ( port == NULL && uri == NULL ) || ( manager == NULL ) || ( passwd == NULL ) || ( progdir == NULL )) { usage( argv[0], '\0' ); } #ifdef HAVE_WINSOCK children = malloc( maxkids * sizeof(HANDLE) ); #endif /* get the file list */ if ( ( datadir = opendir( dirname )) == NULL ) { fprintf( stderr, "%s: couldn't open data directory \"%s\".\n", argv[0], dirname ); exit( EXIT_FAILURE ); } /* look for search, read, modrdn, and add/delete files */ for ( file = readdir( datadir ); file; file = readdir( datadir )) { if ( !strcasecmp( file->d_name, TSEARCHFILE )) { sfile = get_file_name( dirname, file->d_name ); continue; } else if ( !strcasecmp( file->d_name, TREADFILE )) { rfile = get_file_name( dirname, file->d_name ); continue; } else if ( !strcasecmp( file->d_name, TMODRDNFILE )) { nfile = get_file_name( dirname, file->d_name ); continue; } else if ( !strcasecmp( file->d_name, TMODIFYFILE )) { mfile = get_file_name( dirname, file->d_name ); continue; } else if ( !strncasecmp( file->d_name, TADDFILE, strlen( TADDFILE )) && ( anum < MAXREQS )) { afiles[anum++] = get_file_name( dirname, file->d_name ); continue; } else if ( !strcasecmp( file->d_name, TBINDFILE )) { bfile = get_file_name( dirname, file->d_name ); continue; } } closedir( datadir ); if ( pw_ask ) { passwd = getpassphrase( _("Enter LDAP Password: "******"no data files found.\n" ); exit( EXIT_FAILURE ); } /* look for search requests */ if ( sfile ) { snum = get_search_filters( sfile, sreqs, sattrs, sbase, slud ); if ( snum < 0 ) { fprintf( stderr, "unable to parse file \"%s\" line %d\n", sfile, -2*(snum + 1)); exit( EXIT_FAILURE ); } } /* look for read requests */ if ( rfile ) { rnum = get_read_entries( rfile, rreqs, rflts ); if ( rnum < 0 ) { fprintf( stderr, "unable to parse file \"%s\" line %d\n", rfile, -2*(rnum + 1) ); exit( EXIT_FAILURE ); } } /* look for modrdn requests */ if ( nfile ) { nnum = get_read_entries( nfile, nreqs, NULL ); if ( nnum < 0 ) { fprintf( stderr, "unable to parse file \"%s\" line %d\n", nfile, -2*(nnum + 1) ); exit( EXIT_FAILURE ); } } /* look for modify requests */ if ( mfile ) { mnum = get_search_filters( mfile, mreqs, NULL, mdn, NULL ); if ( mnum < 0 ) { fprintf( stderr, "unable to parse file \"%s\" line %d\n", mfile, -2*(mnum + 1) ); exit( EXIT_FAILURE ); } } /* look for bind requests */ if ( bfile ) { bnum = get_search_filters( bfile, bcreds, battrs, breqs, NULL ); if ( bnum < 0 ) { fprintf( stderr, "unable to parse file \"%s\" line %d\n", bfile, -2*(bnum + 1) ); exit( EXIT_FAILURE ); } } /* setup friendly option */ switch ( friendly ) { case 0: break; case 1: friendlyOpt = "-F"; break; default: /* NOTE: right now we don't need it more than twice */ case 2: friendlyOpt = "-FF"; break; } /* setup swamp option */ if ( swamp ) { swampopt[0] = '-'; if ( swamp > 3 ) swamp = 3; swampopt[swamp + 1] = '\0'; for ( ; swamp-- > 0; ) swampopt[swamp + 1] = 'S'; } /* setup loop options */ if ( sloops[0] == '\0' ) snprintf( sloops, sizeof( sloops ), "%d", 10 * loops ); if ( rloops[0] == '\0' ) snprintf( rloops, sizeof( rloops ), "%d", 20 * loops ); if ( aloops[0] == '\0' ) snprintf( aloops, sizeof( aloops ), "%d", loops ); if ( nloops[0] == '\0' ) snprintf( nloops, sizeof( nloops ), "%d", loops ); if ( mloops[0] == '\0' ) snprintf( mloops, sizeof( mloops ), "%d", loops ); if ( bloops[0] == '\0' ) snprintf( bloops, sizeof( bloops ), "%d", 20 * loops ); /* * generate the search clients */ sanum = 0; snprintf( scmd, sizeof scmd, "%s" LDAP_DIRSEP SEARCHCMD, progdir ); sargs[sanum++] = scmd; if ( uri ) { sargs[sanum++] = "-H"; sargs[sanum++] = uri; } else { sargs[sanum++] = "-h"; sargs[sanum++] = host; sargs[sanum++] = "-p"; sargs[sanum++] = port; } sargs[sanum++] = "-D"; sargs[sanum++] = manager; sargs[sanum++] = "-w"; sargs[sanum++] = passwd; sargs[sanum++] = "-l"; sargs[sanum++] = sloops; sargs[sanum++] = "-L"; sargs[sanum++] = outerloops; sargs[sanum++] = "-r"; sargs[sanum++] = retries; sargs[sanum++] = "-t"; sargs[sanum++] = delay; if ( friendly ) { sargs[sanum++] = friendlyOpt; } if ( chaserefs ) { sargs[sanum++] = "-C"; } if ( noattrs ) { sargs[sanum++] = "-A"; } if ( nobind ) { sargs[sanum++] = "-N"; } if ( ignore ) { sargs[sanum++] = "-i"; sargs[sanum++] = ignore; } if ( swamp ) { sargs[sanum++] = swampopt; } sargs[sanum++] = "-b"; sargs[sanum++] = NULL; /* will hold the search base */ sargs[sanum++] = "-s"; sargs[sanum++] = NULL; /* will hold the search scope */ sargs[sanum++] = "-f"; sargs[sanum++] = NULL; /* will hold the search request */ sargs[sanum++] = NULL; sargs[sanum++] = NULL; /* might hold the "attr" request */ sextra_args += 2; sargs[sanum] = NULL; /* * generate the read clients */ ranum = 0; snprintf( rcmd, sizeof rcmd, "%s" LDAP_DIRSEP READCMD, progdir ); rargs[ranum++] = rcmd; if ( uri ) { rargs[ranum++] = "-H"; rargs[ranum++] = uri; } else { rargs[ranum++] = "-h"; rargs[ranum++] = host; rargs[ranum++] = "-p"; rargs[ranum++] = port; } rargs[ranum++] = "-D"; rargs[ranum++] = manager; rargs[ranum++] = "-w"; rargs[ranum++] = passwd; rargs[ranum++] = "-l"; rargs[ranum++] = rloops; rargs[ranum++] = "-L"; rargs[ranum++] = outerloops; rargs[ranum++] = "-r"; rargs[ranum++] = retries; rargs[ranum++] = "-t"; rargs[ranum++] = delay; if ( friendly ) { rargs[ranum++] = friendlyOpt; } if ( chaserefs ) { rargs[ranum++] = "-C"; } if ( noattrs ) { rargs[ranum++] = "-A"; } if ( ignore ) { rargs[ranum++] = "-i"; rargs[ranum++] = ignore; } if ( swamp ) { rargs[ranum++] = swampopt; } rargs[ranum++] = "-e"; rargs[ranum++] = NULL; /* will hold the read entry */ rargs[ranum++] = NULL; rargs[ranum++] = NULL; /* might hold the filter arg */ rextra_args += 2; rargs[ranum] = NULL; /* * generate the modrdn clients */ nanum = 0; snprintf( ncmd, sizeof ncmd, "%s" LDAP_DIRSEP MODRDNCMD, progdir ); nargs[nanum++] = ncmd; if ( uri ) { nargs[nanum++] = "-H"; nargs[nanum++] = uri; } else { nargs[nanum++] = "-h"; nargs[nanum++] = host; nargs[nanum++] = "-p"; nargs[nanum++] = port; } nargs[nanum++] = "-D"; nargs[nanum++] = manager; nargs[nanum++] = "-w"; nargs[nanum++] = passwd; nargs[nanum++] = "-l"; nargs[nanum++] = nloops; nargs[nanum++] = "-L"; nargs[nanum++] = outerloops; nargs[nanum++] = "-r"; nargs[nanum++] = retries; nargs[nanum++] = "-t"; nargs[nanum++] = delay; if ( friendly ) { nargs[nanum++] = friendlyOpt; } if ( chaserefs ) { nargs[nanum++] = "-C"; } if ( ignore ) { nargs[nanum++] = "-i"; nargs[nanum++] = ignore; } nargs[nanum++] = "-e"; nargs[nanum++] = NULL; /* will hold the modrdn entry */ nargs[nanum] = NULL; /* * generate the modify clients */ manum = 0; snprintf( mcmd, sizeof mcmd, "%s" LDAP_DIRSEP MODIFYCMD, progdir ); margs[manum++] = mcmd; if ( uri ) { margs[manum++] = "-H"; margs[manum++] = uri; } else { margs[manum++] = "-h"; margs[manum++] = host; margs[manum++] = "-p"; margs[manum++] = port; } margs[manum++] = "-D"; margs[manum++] = manager; margs[manum++] = "-w"; margs[manum++] = passwd; margs[manum++] = "-l"; margs[manum++] = mloops; margs[manum++] = "-L"; margs[manum++] = outerloops; margs[manum++] = "-r"; margs[manum++] = retries; margs[manum++] = "-t"; margs[manum++] = delay; if ( friendly ) { margs[manum++] = friendlyOpt; } if ( chaserefs ) { margs[manum++] = "-C"; } if ( ignore ) { margs[manum++] = "-i"; margs[manum++] = ignore; } margs[manum++] = "-e"; margs[manum++] = NULL; /* will hold the modify entry */ margs[manum++] = "-a";; margs[manum++] = NULL; /* will hold the ava */ margs[manum] = NULL; /* * generate the add/delete clients */ aanum = 0; snprintf( acmd, sizeof acmd, "%s" LDAP_DIRSEP ADDCMD, progdir ); aargs[aanum++] = acmd; if ( uri ) { aargs[aanum++] = "-H"; aargs[aanum++] = uri; } else { aargs[aanum++] = "-h"; aargs[aanum++] = host; aargs[aanum++] = "-p"; aargs[aanum++] = port; } aargs[aanum++] = "-D"; aargs[aanum++] = manager; aargs[aanum++] = "-w"; aargs[aanum++] = passwd; aargs[aanum++] = "-l"; aargs[aanum++] = aloops; aargs[aanum++] = "-L"; aargs[aanum++] = outerloops; aargs[aanum++] = "-r"; aargs[aanum++] = retries; aargs[aanum++] = "-t"; aargs[aanum++] = delay; if ( friendly ) { aargs[aanum++] = friendlyOpt; } if ( chaserefs ) { aargs[aanum++] = "-C"; } if ( ignore ) { aargs[aanum++] = "-i"; aargs[aanum++] = ignore; } aargs[aanum++] = "-f"; aargs[aanum++] = NULL; /* will hold the add data file */ aargs[aanum] = NULL; /* * generate the bind clients */ banum = 0; snprintf( bcmd, sizeof bcmd, "%s" LDAP_DIRSEP BINDCMD, progdir ); bargs[banum++] = bcmd; if ( !noinit ) { bargs[banum++] = "-I"; /* init on each bind */ } if ( uri ) { bargs[banum++] = "-H"; bargs[banum++] = uri; } else { bargs[banum++] = "-h"; bargs[banum++] = host; bargs[banum++] = "-p"; bargs[banum++] = port; } bargs[banum++] = "-l"; bargs[banum++] = bloops; bargs[banum++] = "-L"; bargs[banum++] = outerloops; #if 0 bargs[banum++] = "-r"; bargs[banum++] = retries; bargs[banum++] = "-t"; bargs[banum++] = delay; #endif if ( friendly ) { bargs[banum++] = friendlyOpt; } if ( chaserefs ) { bargs[banum++] = "-C"; } if ( ignore ) { bargs[banum++] = "-i"; bargs[banum++] = ignore; } if ( nextra ) { bargs[banum++] = "-B"; bargs_extra = &bargs[banum++]; } bargs[banum++] = "-D"; bargs[banum++] = NULL; bargs[banum++] = "-w"; bargs[banum++] = NULL; bargs[banum] = NULL; #define DOREQ(n,j) ((n) && ((maxkids > (n)) ? ((j) < maxkids ) : ((j) < (n)))) for ( j = 0; j < MAXREQS; j++ ) { /* search */ if ( DOREQ( snum, j ) ) { int jj = j % snum; int x = sanum - sextra_args; /* base */ if ( sbase[jj] != NULL ) { sargs[sanum - 7] = sbase[jj]; } else { sargs[sanum - 7] = slud[jj]->lud_dn; } /* scope */ if ( slud[jj] != NULL ) { sargs[sanum - 5] = (char *)ldap_pvt_scope2str( slud[jj]->lud_scope ); } else { sargs[sanum - 5] = "sub"; } /* filter */ if ( sreqs[jj] != NULL ) { sargs[sanum - 3] = sreqs[jj]; } else if ( slud[jj]->lud_filter != NULL ) { sargs[sanum - 3] = slud[jj]->lud_filter; } else { sargs[sanum - 3] = "(objectClass=*)"; } /* extras */ sargs[x] = NULL; /* attr */ if ( sattrs[jj] != NULL ) { sargs[x++] = "-a"; sargs[x++] = sattrs[jj]; } /* attrs */ if ( slud[jj] != NULL && slud[jj]->lud_attrs != NULL ) { int i; for ( i = 0; slud[jj]->lud_attrs[ i ] != NULL && x + i < MAXARGS - 1; i++ ) { sargs[x + i] = slud[jj]->lud_attrs[ i ]; } sargs[x + i] = NULL; } fork_child( scmd, sargs ); } /* read */ if ( DOREQ( rnum, j ) ) { int jj = j % rnum; int x = ranum - rextra_args; rargs[ranum - 3] = rreqs[jj]; if ( rflts[jj] != NULL ) { rargs[x++] = "-f"; rargs[x++] = rflts[jj]; } rargs[x] = NULL; fork_child( rcmd, rargs ); } /* rename */ if ( j < nnum ) { nargs[nanum - 1] = nreqs[j]; fork_child( ncmd, nargs ); } /* modify */ if ( j < mnum ) { margs[manum - 3] = mdn[j]; margs[manum - 1] = mreqs[j]; fork_child( mcmd, margs ); } /* add/delete */ if ( j < anum ) { aargs[aanum - 1] = afiles[j]; fork_child( acmd, aargs ); } /* bind */ if ( DOREQ( bnum, j ) ) { int jj = j % bnum; if ( nextra ) { int n = ((double)nextra)*rand()/(RAND_MAX + 1.0); extra_t *e; for ( e = extra; n-- > 0; e = e->next ) ; *bargs_extra = e->action; } if ( battrs[jj] != NULL ) { bargs[banum - 3] = manager ? manager : ""; bargs[banum - 1] = passwd ? passwd : ""; bargs[banum + 0] = "-b"; bargs[banum + 1] = breqs[jj]; bargs[banum + 2] = "-f"; bargs[banum + 3] = bcreds[jj]; bargs[banum + 4] = "-a"; bargs[banum + 5] = battrs[jj]; bargs[banum + 6] = NULL; } else { bargs[banum - 3] = breqs[jj]; bargs[banum - 1] = bcreds[jj]; bargs[banum] = NULL; } fork_child( bcmd, bargs ); bargs[banum] = NULL; } } wait4kids( -1 ); exit( EXIT_SUCCESS ); }
int nsldapi_sasl_secprops( const char *in, sasl_security_properties_t *secprops ) { int i; char **props = NULL; char *inp; unsigned sflags = 0; sasl_ssf_t max_ssf = 0; sasl_ssf_t min_ssf = 0; unsigned maxbufsize = 0; int got_sflags = 0; int got_max_ssf = 0; int got_min_ssf = 0; int got_maxbufsize = 0; if (in == NULL) { return LDAP_PARAM_ERROR; } inp = nsldapi_strdup(in); if (inp == NULL) { return LDAP_PARAM_ERROR; } props = ldap_str2charray( inp, "," ); NSLDAPI_FREE( inp ); if( props == NULL || secprops == NULL ) { return LDAP_PARAM_ERROR; } for( i=0; props[i]; i++ ) { if( strcasecmp(props[i], "none") == 0 ) { got_sflags++; } else if( strcasecmp(props[i], "noactive") == 0 ) { got_sflags++; sflags |= SASL_SEC_NOACTIVE; } else if( strcasecmp(props[i], "noanonymous") == 0 ) { got_sflags++; sflags |= SASL_SEC_NOANONYMOUS; } else if( strcasecmp(props[i], "nodict") == 0 ) { got_sflags++; sflags |= SASL_SEC_NODICTIONARY; } else if( strcasecmp(props[i], "noplain") == 0 ) { got_sflags++; sflags |= SASL_SEC_NOPLAINTEXT; } else if( strcasecmp(props[i], "forwardsec") == 0 ) { got_sflags++; sflags |= SASL_SEC_FORWARD_SECRECY; } else if( strcasecmp(props[i], "passcred") == 0 ) { got_sflags++; sflags |= SASL_SEC_PASS_CREDENTIALS; } else if( strncasecmp(props[i], "minssf=", sizeof("minssf")) == 0 ) { if( isdigit( props[i][sizeof("minssf")] ) ) { got_min_ssf++; min_ssf = atoi( &props[i][sizeof("minssf")] ); } else { return LDAP_NOT_SUPPORTED; } } else if( strncasecmp(props[i], "maxssf=", sizeof("maxssf")) == 0 ) { if( isdigit( props[i][sizeof("maxssf")] ) ) { got_max_ssf++; max_ssf = atoi( &props[i][sizeof("maxssf")] ); } else { return LDAP_NOT_SUPPORTED; } } else if( strncasecmp(props[i], "maxbufsize=", sizeof("maxbufsize")) == 0 ) { if( isdigit( props[i][sizeof("maxbufsize")] ) ) { got_maxbufsize++; maxbufsize = atoi( &props[i][sizeof("maxbufsize")] ); if( maxbufsize && (( maxbufsize < SASL_MIN_BUFF_SIZE ) || (maxbufsize > SASL_MAX_BUFF_SIZE ))) { return( LDAP_PARAM_ERROR ); } } else { return( LDAP_NOT_SUPPORTED ); } } else { return( LDAP_NOT_SUPPORTED ); } } if(got_sflags) { secprops->security_flags = sflags; } if(got_min_ssf) { secprops->min_ssf = min_ssf; } if(got_max_ssf) { secprops->max_ssf = max_ssf; } if(got_maxbufsize) { secprops->maxbufsize = maxbufsize; } ldap_charray_free( props ); return( LDAP_SUCCESS ); }
int main( int argc, char **argv ) { int i; char *uri = NULL; char *host = "localhost"; int port = -1; char *manager = NULL; struct berval passwd = { 0, NULL }; char *sbase = NULL; int scope = LDAP_SCOPE_SUBTREE; char *filter = NULL; char *attr = NULL; char *srchattrs[] = { "cn", "sn", NULL }; char **attrs = srchattrs; int loops = LOOPS; int outerloops = 1; int retries = RETRIES; int delay = 0; int force = 0; int chaserefs = 0; int noattrs = 0; int nobind = 0; tester_init( "slapd-search", TESTER_SEARCH ); /* by default, tolerate referrals and no such object */ tester_ignore_str2errlist( "REFERRAL,NO_SUCH_OBJECT" ); while ( ( i = getopt( argc, argv, "Aa:b:CD:f:FH:h:i:l:L:Np:r:Ss:t:T:w:" ) ) != EOF ) { switch ( i ) { case 'A': noattrs++; break; case 'C': chaserefs++; break; case 'H': /* the server uri */ uri = strdup( optarg ); break; case 'h': /* the servers host */ host = strdup( optarg ); break; case 'i': tester_ignore_str2errlist( optarg ); break; case 'N': nobind++; break; case 'p': /* the servers port */ if ( lutil_atoi( &port, optarg ) != 0 ) { usage( argv[0], i ); } break; case 'D': /* the servers manager */ manager = strdup( optarg ); break; case 'w': /* the server managers password */ passwd.bv_val = strdup( optarg ); passwd.bv_len = strlen( optarg ); memset( optarg, '*', passwd.bv_len ); break; case 'a': attr = strdup( optarg ); break; case 'b': /* file with search base */ sbase = strdup( optarg ); break; case 'f': /* the search request */ filter = strdup( optarg ); break; case 'F': force++; break; case 'l': /* number of loops */ if ( lutil_atoi( &loops, optarg ) != 0 ) { usage( argv[0], i ); } break; case 'L': /* number of loops */ if ( lutil_atoi( &outerloops, optarg ) != 0 ) { usage( argv[0], i ); } break; case 'r': /* number of retries */ if ( lutil_atoi( &retries, optarg ) != 0 ) { usage( argv[0], i ); } break; case 't': /* delay in seconds */ if ( lutil_atoi( &delay, optarg ) != 0 ) { usage( argv[0], i ); } break; case 'T': attrs = ldap_str2charray( optarg, "," ); if ( attrs == NULL ) { usage( argv[0], i ); } break; case 'S': swamp++; break; case 's': scope = ldap_pvt_str2scope( optarg ); if ( scope == -1 ) { usage( argv[0], i ); } break; default: usage( argv[0], i ); break; } } if (( sbase == NULL ) || ( filter == NULL ) || ( port == -1 && uri == NULL )) usage( argv[0], '\0' ); if ( *filter == '\0' ) { fprintf( stderr, "%s: invalid EMPTY search filter.\n", argv[0] ); exit( EXIT_FAILURE ); } if ( argv[optind] != NULL ) { attrs = &argv[optind]; } uri = tester_uri( uri, host, port ); for ( i = 0; i < outerloops; i++ ) { if ( attr != NULL ) { do_random( uri, manager, &passwd, sbase, scope, filter, attr, attrs, noattrs, nobind, loops, retries, delay, force, chaserefs ); } else { do_search( uri, manager, &passwd, sbase, scope, filter, NULL, attrs, noattrs, nobind, loops, retries, delay, force, chaserefs ); } } exit( EXIT_SUCCESS ); }
static int constraint_cf_gen( ConfigArgs *c ) { slap_overinst *on = (slap_overinst *)(c->bi); constraint *cn = on->on_bi.bi_private, *cp; struct berval bv; int i, rc = 0; constraint ap = { NULL }; const char *text = NULL; switch ( c->op ) { case SLAP_CONFIG_EMIT: switch (c->type) { case CONSTRAINT_ATTRIBUTE: for (cp=cn; cp; cp=cp->ap_next) { char *s; char *tstr = NULL; int quotes = 0; int j; bv.bv_len = STRLENOF(" "); for (j = 0; cp->ap[j]; j++) { bv.bv_len += cp->ap[j]->ad_cname.bv_len; } /* room for commas */ bv.bv_len += j - 1; if (cp->re) { tstr = REGEX_STR; } else if (cp->lud) { tstr = URI_STR; quotes = 1; } else if (cp->set) { tstr = SET_STR; quotes = 1; } else if (cp->size) { tstr = SIZE_STR; } else if (cp->count) { tstr = COUNT_STR; } bv.bv_len += strlen(tstr); bv.bv_len += cp->val.bv_len + 2*quotes; if (cp->restrict_lud != NULL) { bv.bv_len += cp->restrict_val.bv_len + STRLENOF(" restrict=\"\""); } s = bv.bv_val = ch_malloc(bv.bv_len + 1); s = lutil_strncopy( s, cp->ap[0]->ad_cname.bv_val, cp->ap[0]->ad_cname.bv_len ); for (j = 1; cp->ap[j]; j++) { *s++ = ','; s = lutil_strncopy( s, cp->ap[j]->ad_cname.bv_val, cp->ap[j]->ad_cname.bv_len ); } *s++ = ' '; s = lutil_strcopy( s, tstr ); *s++ = ' '; if ( quotes ) *s++ = '"'; s = lutil_strncopy( s, cp->val.bv_val, cp->val.bv_len ); if ( quotes ) *s++ = '"'; if (cp->restrict_lud != NULL) { s = lutil_strcopy( s, " restrict=\"" ); s = lutil_strncopy( s, cp->restrict_val.bv_val, cp->restrict_val.bv_len ); *s++ = '"'; } *s = '\0'; rc = value_add_one( &c->rvalue_vals, &bv ); if (rc == LDAP_SUCCESS) rc = value_add_one( &c->rvalue_nvals, &bv ); ch_free(bv.bv_val); if (rc) return rc; } break; default: abort(); break; } break; case LDAP_MOD_DELETE: switch (c->type) { case CONSTRAINT_ATTRIBUTE: if (!cn) break; /* nothing to do */ if (c->valx < 0) { /* zap all constraints */ while (cn) { cp = cn->ap_next; constraint_free( cn, 1 ); cn = cp; } on->on_bi.bi_private = NULL; } else { constraint **cpp; /* zap constraint numbered 'valx' */ for(i=0, cp = cn, cpp = &cn; (cp) && (i<c->valx); i++, cpp = &cp->ap_next, cp = *cpp); if (cp) { /* zap cp, and join cpp to cp->ap_next */ *cpp = cp->ap_next; constraint_free( cp, 1 ); } on->on_bi.bi_private = cn; } break; default: abort(); break; } break; case SLAP_CONFIG_ADD: case LDAP_MOD_ADD: switch (c->type) { case CONSTRAINT_ATTRIBUTE: { int j; char **attrs = ldap_str2charray( c->argv[1], "," ); for ( j = 0; attrs[j]; j++) /* just count */ ; ap.ap = ch_calloc( sizeof(AttributeDescription*), j + 1 ); for ( j = 0; attrs[j]; j++) { if ( slap_str2ad( attrs[j], &ap.ap[j], &text ) ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s <%s>: %s\n", c->argv[0], attrs[j], text ); rc = ARG_BAD_CONF; goto done; } } if ( strcasecmp( c->argv[2], REGEX_STR ) == 0) { int err; ap.re = ch_malloc( sizeof(regex_t) ); if ((err = regcomp( ap.re, c->argv[3], REG_EXTENDED )) != 0) { char errmsg[1024]; regerror( err, ap.re, errmsg, sizeof(errmsg) ); ch_free(ap.re); snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: Illegal regular expression \"%s\": Error %s", c->argv[0], c->argv[1], c->argv[3], errmsg); ap.re = NULL; rc = ARG_BAD_CONF; goto done; } ber_str2bv( c->argv[3], 0, 1, &ap.val ); } else if ( strcasecmp( c->argv[2], SIZE_STR ) == 0 ) { size_t size; if ( ( size = atoi(c->argv[3]) ) != 0 ) ap.size = size; } else if ( strcasecmp( c->argv[2], COUNT_STR ) == 0 ) { size_t count; if ( ( count = atoi(c->argv[3]) ) != 0 ) ap.count = count; } else if ( strcasecmp( c->argv[2], URI_STR ) == 0 ) { int err; err = ldap_url_parse(c->argv[3], &ap.lud); if ( err != LDAP_URL_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: Invalid URI \"%s\"", c->argv[0], c->argv[1], c->argv[3]); rc = ARG_BAD_CONF; goto done; } if (ap.lud->lud_host != NULL) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: unsupported hostname in URI \"%s\"", c->argv[0], c->argv[1], c->argv[3]); ldap_free_urldesc(ap.lud); rc = ARG_BAD_CONF; goto done; } for ( i=0; ap.lud->lud_attrs[i]; i++); /* FIXME: This is worthless without at least one attr */ if ( i ) { ap.attrs = ch_malloc( (i+1)*sizeof(AttributeDescription *)); for ( i=0; ap.lud->lud_attrs[i]; i++) { ap.attrs[i] = NULL; if ( slap_str2ad( ap.lud->lud_attrs[i], &ap.attrs[i], &text ) ) { ch_free( ap.attrs ); snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s <%s>: %s\n", c->argv[0], ap.lud->lud_attrs[i], text ); rc = ARG_BAD_CONF; goto done; } } ap.attrs[i] = NULL; } if (ap.lud->lud_dn == NULL) { ap.lud->lud_dn = ch_strdup(""); } else { struct berval dn, ndn; ber_str2bv( ap.lud->lud_dn, 0, 0, &dn ); if (dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL ) ) { /* cleanup */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: URI %s DN normalization failed", c->argv[0], c->argv[1], c->argv[3] ); Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n", c->log, c->cr_msg, 0 ); rc = ARG_BAD_CONF; goto done; } ldap_memfree( ap.lud->lud_dn ); ap.lud->lud_dn = ndn.bv_val; } if (ap.lud->lud_filter == NULL) { ap.lud->lud_filter = ch_strdup("objectClass=*"); } else if ( ap.lud->lud_filter[0] == '(' ) { ber_len_t len = strlen( ap.lud->lud_filter ); if ( ap.lud->lud_filter[len - 1] != ')' ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: invalid URI filter: %s", c->argv[0], c->argv[1], ap.lud->lud_filter ); rc = ARG_BAD_CONF; goto done; } AC_MEMCPY( &ap.lud->lud_filter[0], &ap.lud->lud_filter[1], len - 2 ); ap.lud->lud_filter[len - 2] = '\0'; } ber_str2bv( c->argv[3], 0, 1, &ap.val ); } else if ( strcasecmp( c->argv[2], SET_STR ) == 0 ) { ap.set = 1; ber_str2bv( c->argv[3], 0, 1, &ap.val ); } else { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: Unknown constraint type: %s", c->argv[0], c->argv[1], c->argv[2] ); rc = ARG_BAD_CONF; goto done; } if ( c->argc > 4 ) { int argidx; for ( argidx = 4; argidx < c->argc; argidx++ ) { if ( strncasecmp( c->argv[argidx], "restrict=", STRLENOF("restrict=") ) == 0 ) { int err; char *arg = c->argv[argidx] + STRLENOF("restrict="); err = ldap_url_parse(arg, &ap.restrict_lud); if ( err != LDAP_URL_SUCCESS ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: Invalid restrict URI \"%s\"", c->argv[0], c->argv[1], arg); rc = ARG_BAD_CONF; goto done; } if (ap.restrict_lud->lud_host != NULL) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: unsupported hostname in restrict URI \"%s\"", c->argv[0], c->argv[1], arg); rc = ARG_BAD_CONF; goto done; } if ( ap.restrict_lud->lud_attrs != NULL ) { if ( ap.restrict_lud->lud_attrs[0] != '\0' ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: attrs not allowed in restrict URI %s\n", c->argv[0], c->argv[1], arg); rc = ARG_BAD_CONF; goto done; } ldap_memvfree((void *)ap.restrict_lud->lud_attrs); ap.restrict_lud->lud_attrs = NULL; } if (ap.restrict_lud->lud_dn != NULL) { if (ap.restrict_lud->lud_dn[0] == '\0') { ldap_memfree(ap.restrict_lud->lud_dn); ap.restrict_lud->lud_dn = NULL; } else { struct berval dn, ndn; int j; ber_str2bv(ap.restrict_lud->lud_dn, 0, 0, &dn); if (dnNormalize(0, NULL, NULL, &dn, &ndn, NULL)) { /* cleanup */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: restrict URI %s DN normalization failed", c->argv[0], c->argv[1], arg ); rc = ARG_BAD_CONF; goto done; } assert(c->be != NULL); if (c->be->be_nsuffix == NULL) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: restrict URI requires suffix", c->argv[0], c->argv[1] ); rc = ARG_BAD_CONF; goto done; } for ( j = 0; !BER_BVISNULL(&c->be->be_nsuffix[j]); j++) { if (dnIsSuffix(&ndn, &c->be->be_nsuffix[j])) break; } if (BER_BVISNULL(&c->be->be_nsuffix[j])) { /* error */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: restrict URI DN %s not within database naming context(s)", c->argv[0], c->argv[1], dn.bv_val ); rc = ARG_BAD_CONF; goto done; } ap.restrict_ndn = ndn; } } if (ap.restrict_lud->lud_filter != NULL) { ap.restrict_filter = str2filter(ap.restrict_lud->lud_filter); if (ap.restrict_filter == NULL) { /* error */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: restrict URI filter %s invalid", c->argv[0], c->argv[1], ap.restrict_lud->lud_filter ); rc = ARG_BAD_CONF; goto done; } } ber_str2bv(c->argv[argidx], 0, 1, &ap.restrict_val); } else { /* cleanup */ snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s %s: unrecognized arg #%d (%s)", c->argv[0], c->argv[1], argidx, c->argv[argidx] ); rc = ARG_BAD_CONF; goto done; } } } done:; if ( rc == LDAP_SUCCESS ) { constraint *a2 = ch_calloc( sizeof(constraint), 1 ); a2->ap_next = on->on_bi.bi_private; a2->ap = ap.ap; a2->re = ap.re; a2->val = ap.val; a2->lud = ap.lud; a2->set = ap.set; a2->size = ap.size; a2->count = ap.count; if ( a2->lud ) { ber_str2bv(a2->lud->lud_dn, 0, 0, &a2->dn); ber_str2bv(a2->lud->lud_filter, 0, 0, &a2->filter); } a2->attrs = ap.attrs; a2->restrict_lud = ap.restrict_lud; a2->restrict_ndn = ap.restrict_ndn; a2->restrict_filter = ap.restrict_filter; a2->restrict_val = ap.restrict_val; on->on_bi.bi_private = a2; } else { Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE, "%s: %s\n", c->log, c->cr_msg, 0 ); constraint_free( &ap, 0 ); } ldap_memvfree((void**)attrs); } break; default: abort(); break; } break; default: abort(); } return rc; }
int bdb_attr_index_config( struct bdb_info *bdb, const char *fname, int lineno, int argc, char **argv, struct config_reply_s *c_reply) { int rc = 0; int i; slap_mask_t mask; char **attrs; char **indexes = NULL; attrs = ldap_str2charray( argv[0], "," ); if( attrs == NULL ) { fprintf( stderr, "%s: line %d: " "no attributes specified: %s\n", fname, lineno, argv[0] ); return LDAP_PARAM_ERROR; } if ( argc > 1 ) { indexes = ldap_str2charray( argv[1], "," ); if( indexes == NULL ) { fprintf( stderr, "%s: line %d: " "no indexes specified: %s\n", fname, lineno, argv[1] ); rc = LDAP_PARAM_ERROR; goto done; } } if( indexes == NULL ) { mask = bdb->bi_defaultmask; } else { mask = 0; for ( i = 0; indexes[i] != NULL; i++ ) { slap_mask_t index; rc = slap_str2index( indexes[i], &index ); if( rc != LDAP_SUCCESS ) { if ( c_reply ) { snprintf(c_reply->msg, sizeof(c_reply->msg), "index type \"%s\" undefined", indexes[i] ); fprintf( stderr, "%s: line %d: %s\n", fname, lineno, c_reply->msg ); } rc = LDAP_PARAM_ERROR; goto done; } mask |= index; } } if( !mask ) { if ( c_reply ) { snprintf(c_reply->msg, sizeof(c_reply->msg), "no indexes selected" ); fprintf( stderr, "%s: line %d: %s\n", fname, lineno, c_reply->msg ); } rc = LDAP_PARAM_ERROR; goto done; } for ( i = 0; attrs[i] != NULL; i++ ) { AttrInfo *a; AttributeDescription *ad; const char *text; #ifdef LDAP_COMP_MATCH ComponentReference* cr = NULL; AttrInfo *a_cr = NULL; #endif if( strcasecmp( attrs[i], "default" ) == 0 ) { bdb->bi_defaultmask |= mask; continue; } #ifdef LDAP_COMP_MATCH if ( is_component_reference( attrs[i] ) ) { rc = extract_component_reference( attrs[i], &cr ); if ( rc != LDAP_SUCCESS ) { if ( c_reply ) { snprintf(c_reply->msg, sizeof(c_reply->msg), "index component reference\"%s\" undefined", attrs[i] ); fprintf( stderr, "%s: line %d: %s\n", fname, lineno, c_reply->msg ); } goto done; } cr->cr_indexmask = mask; /* * After extracting a component reference * only the name of a attribute will be remaining */ } else { cr = NULL; } #endif ad = NULL; rc = slap_str2ad( attrs[i], &ad, &text ); if( rc != LDAP_SUCCESS ) { if ( c_reply ) { snprintf(c_reply->msg, sizeof(c_reply->msg), "index attribute \"%s\" undefined", attrs[i] ); fprintf( stderr, "%s: line %d: %s\n", fname, lineno, c_reply->msg ); } goto done; } if( ad == slap_schema.si_ad_entryDN || slap_ad_is_binary( ad ) ) { if (c_reply) { snprintf(c_reply->msg, sizeof(c_reply->msg), "index of attribute \"%s\" disallowed", attrs[i] ); fprintf( stderr, "%s: line %d: %s\n", fname, lineno, c_reply->msg ); } rc = LDAP_UNWILLING_TO_PERFORM; goto done; } if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) && !( ad->ad_type->sat_approx && ad->ad_type->sat_approx->smr_indexer && ad->ad_type->sat_approx->smr_filter ) ) { if (c_reply) { snprintf(c_reply->msg, sizeof(c_reply->msg), "approx index of attribute \"%s\" disallowed", attrs[i] ); fprintf( stderr, "%s: line %d: %s\n", fname, lineno, c_reply->msg ); } rc = LDAP_INAPPROPRIATE_MATCHING; goto done; } if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) && !( ad->ad_type->sat_equality && ad->ad_type->sat_equality->smr_indexer && ad->ad_type->sat_equality->smr_filter ) ) { if (c_reply) { snprintf(c_reply->msg, sizeof(c_reply->msg), "equality index of attribute \"%s\" disallowed", attrs[i] ); fprintf( stderr, "%s: line %d: %s\n", fname, lineno, c_reply->msg ); } rc = LDAP_INAPPROPRIATE_MATCHING; goto done; } if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) && !( ad->ad_type->sat_substr && ad->ad_type->sat_substr->smr_indexer && ad->ad_type->sat_substr->smr_filter ) ) { if (c_reply) { snprintf(c_reply->msg, sizeof(c_reply->msg), "substr index of attribute \"%s\" disallowed", attrs[i] ); fprintf( stderr, "%s: line %d: %s\n", fname, lineno, c_reply->msg ); } rc = LDAP_INAPPROPRIATE_MATCHING; goto done; } Debug( LDAP_DEBUG_CONFIG, "index %s 0x%04lx\n", ad->ad_cname.bv_val, mask, 0 ); a = (AttrInfo *) ch_malloc( sizeof(AttrInfo) ); #ifdef LDAP_COMP_MATCH a->ai_cr = NULL; #endif a->ai_desc = ad; if ( bdb->bi_flags & BDB_IS_OPEN ) { a->ai_indexmask = 0; a->ai_newmask = mask; } else { a->ai_indexmask = mask; a->ai_newmask = 0; } #ifdef LDAP_COMP_MATCH if ( cr ) { a_cr = bdb_attr_mask( bdb, ad ); if ( a_cr ) { /* * AttrInfo is already in AVL * just add the extracted component reference * in the AttrInfo */ rc = insert_component_reference( cr, &a_cr->ai_cr ); if ( rc != LDAP_SUCCESS) { fprintf( stderr, " error during inserting component reference in %s ", attrs[i]); rc = LDAP_PARAM_ERROR; goto done; } continue; } else { rc = insert_component_reference( cr, &a->ai_cr ); if ( rc != LDAP_SUCCESS) { fprintf( stderr, " error during inserting component reference in %s ", attrs[i]); rc = LDAP_PARAM_ERROR; goto done; } } } #endif rc = ainfo_insert( bdb, a ); if( rc ) { if ( bdb->bi_flags & BDB_IS_OPEN ) { AttrInfo *b = bdb_attr_mask( bdb, ad ); /* If there is already an index defined for this attribute * it must be replaced. Otherwise we end up with multiple * olcIndex values for the same attribute */ if ( b->ai_indexmask & BDB_INDEX_DELETING ) { /* If we were editing this attr, reset it */ b->ai_indexmask &= ~BDB_INDEX_DELETING; /* If this is leftover from a previous add, commit it */ if ( b->ai_newmask ) b->ai_indexmask = b->ai_newmask; b->ai_newmask = a->ai_newmask; ch_free( a ); rc = 0; continue; } } if (c_reply) { snprintf(c_reply->msg, sizeof(c_reply->msg), "duplicate index definition for attr \"%s\"", attrs[i] ); fprintf( stderr, "%s: line %d: %s\n", fname, lineno, c_reply->msg ); } rc = LDAP_PARAM_ERROR; goto done; } } done: ldap_charray_free( attrs ); if ( indexes != NULL ) ldap_charray_free( indexes ); return rc; }
int main( int argc, char **argv ) { int i; char *uri = NULL; char *host = "localhost"; int port = -1; char *manager = NULL; struct berval passwd = { 0, NULL }; char *entry = NULL; char *filter = NULL; int loops = LOOPS; int outerloops = 1; int retries = RETRIES; int delay = 0; int force = 0; int chaserefs = 0; char *srchattrs[] = { "1.1", NULL }; char **attrs = srchattrs; int noattrs = 0; int nobind = 0; tester_init( "slapd-read", TESTER_READ ); /* by default, tolerate referrals and no such object */ tester_ignore_str2errlist( "REFERRAL,NO_SUCH_OBJECT" ); while ( (i = getopt( argc, argv, "ACD:e:Ff:H:h:i:L:l:p:r:St:T:w:" )) != EOF ) { switch ( i ) { case 'A': noattrs++; break; case 'C': chaserefs++; break; case 'H': /* the server uri */ uri = strdup( optarg ); break; case 'h': /* the servers host */ host = strdup( optarg ); break; case 'i': tester_ignore_str2errlist( optarg ); break; case 'N': nobind++; break; case 'p': /* the servers port */ if ( lutil_atoi( &port, optarg ) != 0 ) { usage( argv[0] ); } break; case 'D': /* the servers manager */ manager = strdup( optarg ); break; case 'w': /* the server managers password */ passwd.bv_val = strdup( optarg ); passwd.bv_len = strlen( optarg ); memset( optarg, '*', passwd.bv_len ); break; case 'e': /* DN to search for */ entry = strdup( optarg ); break; case 'f': /* the search request */ filter = strdup( optarg ); break; case 'F': force++; break; case 'l': /* the number of loops */ if ( lutil_atoi( &loops, optarg ) != 0 ) { usage( argv[0] ); } break; case 'L': /* the number of outerloops */ if ( lutil_atoi( &outerloops, optarg ) != 0 ) { usage( argv[0] ); } break; case 'r': /* the number of retries */ if ( lutil_atoi( &retries, optarg ) != 0 ) { usage( argv[0] ); } break; case 'S': swamp++; break; case 't': /* delay in seconds */ if ( lutil_atoi( &delay, optarg ) != 0 ) { usage( argv[0] ); } break; case 'T': attrs = ldap_str2charray( optarg, "," ); if ( attrs == NULL ) { usage( argv[0] ); } break; default: usage( argv[0] ); break; } } if (( entry == NULL ) || ( port == -1 && uri == NULL )) usage( argv[0] ); if ( *entry == '\0' ) { fprintf( stderr, "%s: invalid EMPTY entry DN.\n", argv[0] ); exit( EXIT_FAILURE ); } if ( argv[optind] != NULL ) { attrs = &argv[optind]; } uri = tester_uri( uri, host, port ); for ( i = 0; i < outerloops; i++ ) { if ( filter != NULL ) { do_random( uri, manager, &passwd, entry, filter, attrs, noattrs, nobind, loops, retries, delay, force, chaserefs ); } else { do_read( uri, manager, &passwd, entry, NULL, attrs, noattrs, nobind, loops, retries, delay, force, chaserefs ); } } exit( EXIT_SUCCESS ); }
int slapd_daemon_init( const char *urls ) { int i, j, n, rc; char **u; #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, ARGS, "slapd_daemon_init: %s\n", urls ? urls : "<null>", 0, 0 ); #else Debug( LDAP_DEBUG_ARGS, "daemon_init: %s\n", urls ? urls : "<null>", 0, 0 ); #endif if( (rc = sockinit()) != 0 ) { return rc; } #ifdef HAVE_SYSCONF dtblsize = sysconf( _SC_OPEN_MAX ); #elif HAVE_GETDTABLESIZE dtblsize = getdtablesize(); #else dtblsize = FD_SETSIZE; #endif #ifdef FD_SETSIZE if(dtblsize > FD_SETSIZE) { dtblsize = FD_SETSIZE; } #endif /* !FD_SETSIZE */ /* open a pipe (or something equivalent connected to itself). * we write a byte on this fd whenever we catch a signal. The main * loop will be select'ing on this socket, and will wake up when * this byte arrives. */ if( (rc = lutil_pair( wake_sds )) < 0 ) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, ERR, "slap_daemon_init: lutil_pair() failed rc=%d\n", rc, 0, 0); #else Debug( LDAP_DEBUG_ANY, "daemon: lutil_pair() failed rc=%d\n", rc, 0, 0 ); #endif return rc; } FD_ZERO( &slap_daemon.sd_readers ); FD_ZERO( &slap_daemon.sd_writers ); if( urls == NULL ) { urls = "ldap:///"; } u = ldap_str2charray( urls, " " ); if( u == NULL || u[0] == NULL ) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, ERR, "slap_daemon_init: no urls (%s) provided.\n", urls, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "daemon_init: no urls (%s) provided.\n", urls, 0, 0 ); #endif return -1; } for( i=0; u[i] != NULL; i++ ) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, DETAIL1, "slap_daemon_init: listen on %s\n.", u[i], 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "daemon_init: listen on %s\n", u[i], 0, 0 ); #endif } if( i == 0 ) { #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, INFO, "slap_daemon_init: no listeners to open (%s)\n", urls, 0, 0 ); #else Debug( LDAP_DEBUG_ANY, "daemon_init: no listeners to open (%s)\n", urls, 0, 0 ); #endif ldap_charray_free( u ); return -1; } #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, INFO, "slap_daemon_init: %d listeners to open...\n", i, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "daemon_init: %d listeners to open...\n", i, 0, 0 ); #endif slap_listeners = ch_malloc( (i+1)*sizeof(Listener *) ); for(n = 0, j = 0; u[n]; n++ ) { if ( slap_open_listener( u[n], &i, &j ) ) { ldap_charray_free( u ); return -1; } } slap_listeners[j] = NULL; #ifdef NEW_LOGGING LDAP_LOG( CONNECTION, DETAIL1, "slap_daemon_init: %d listeners opened\n", i, 0, 0 ); #else Debug( LDAP_DEBUG_TRACE, "daemon_init: %d listeners opened\n", i, 0, 0 ); #endif #ifdef HAVE_SLP slapd_slp_init( urls ); slapd_slp_reg(); #endif ldap_charray_free( u ); ldap_pvt_thread_mutex_init( &slap_daemon.sd_mutex ); return !i; }
static int mdb_cf_gen( ConfigArgs *c ) { struct mdb_info *mdb = c->be->be_private; int rc; if ( c->op == SLAP_CONFIG_EMIT ) { rc = 0; switch( c->type ) { case MDB_MODE: { char buf[64]; struct berval bv; bv.bv_len = snprintf( buf, sizeof(buf), "0%o", mdb->mi_dbenv_mode ); if ( bv.bv_len > 0 && bv.bv_len < sizeof(buf) ) { bv.bv_val = buf; value_add_one( &c->rvalue_vals, &bv ); } else { rc = 1; } } break; case MDB_CHKPT: if ( mdb->mi_txn_cp ) { char buf[64]; struct berval bv; bv.bv_len = snprintf( buf, sizeof(buf), "%ld %ld", (long) mdb->mi_txn_cp_kbyte, (long) mdb->mi_txn_cp_min ); if ( bv.bv_len > 0 && bv.bv_len < sizeof(buf) ) { bv.bv_val = buf; value_add_one( &c->rvalue_vals, &bv ); } else { rc = 1; } } else { rc = 1; } break; case MDB_DIRECTORY: if ( mdb->mi_dbenv_home ) { c->value_string = ch_strdup( mdb->mi_dbenv_home ); } else { rc = 1; } break; case MDB_DBNOSYNC: if ( mdb->mi_dbenv_flags & MDB_NOSYNC ) c->value_int = 1; break; case MDB_ENVFLAGS: if ( mdb->mi_dbenv_flags ) { mask_to_verbs( mdb_envflags, mdb->mi_dbenv_flags, &c->rvalue_vals ); } if ( !c->rvalue_vals ) rc = 1; break; case MDB_INDEX: mdb_attr_index_unparse( mdb, &c->rvalue_vals ); if ( !c->rvalue_vals ) rc = 1; break; case MDB_SSTACK: c->value_int = mdb->mi_search_stack_depth; break; case MDB_MAXREADERS: c->value_int = mdb->mi_readers; break; case MDB_MAXSIZE: c->value_ulong = mdb->mi_mapsize; break; } return rc; } else if ( c->op == LDAP_MOD_DELETE ) { rc = 0; switch( c->type ) { case MDB_MODE: #if 0 /* FIXME: does it make any sense to change the mode, * if we don't exec a chmod()? */ mdb->bi_dbenv_mode = SLAPD_DEFAULT_DB_MODE; break; #endif /* single-valued no-ops */ case MDB_SSTACK: case MDB_MAXREADERS: case MDB_MAXSIZE: break; case MDB_CHKPT: if ( mdb->mi_txn_cp_task ) { struct re_s *re = mdb->mi_txn_cp_task; mdb->mi_txn_cp_task = NULL; ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ) ) ldap_pvt_runqueue_stoptask( &slapd_rq, re ); ldap_pvt_runqueue_remove( &slapd_rq, re ); ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); } mdb->mi_txn_cp = 0; break; case MDB_DIRECTORY: mdb->mi_flags |= MDB_RE_OPEN; ch_free( mdb->mi_dbenv_home ); mdb->mi_dbenv_home = NULL; c->cleanup = mdb_cf_cleanup; ldap_pvt_thread_pool_purgekey( mdb->mi_dbenv ); break; case MDB_DBNOSYNC: mdb_env_set_flags( mdb->mi_dbenv, MDB_NOSYNC, 0 ); mdb->mi_dbenv_flags &= ~MDB_NOSYNC; break; case MDB_ENVFLAGS: if ( c->valx == -1 ) { int i; for ( i=0; mdb_envflags[i].mask; i++) { if ( mdb->mi_dbenv_flags & mdb_envflags[i].mask ) { /* not all flags are runtime resettable */ rc = mdb_env_set_flags( mdb->mi_dbenv, mdb_envflags[i].mask, 0 ); if ( rc ) { mdb->mi_flags |= MDB_RE_OPEN; c->cleanup = mdb_cf_cleanup; rc = 0; } mdb->mi_dbenv_flags ^= mdb_envflags[i].mask; } } } else { int i = verb_to_mask( c->line, mdb_envflags ); if ( mdb_envflags[i].mask & mdb->mi_dbenv_flags ) { rc = mdb_env_set_flags( mdb->mi_dbenv, mdb_envflags[i].mask, 0 ); if ( rc ) { mdb->mi_flags |= MDB_RE_OPEN; c->cleanup = mdb_cf_cleanup; rc = 0; } mdb->mi_dbenv_flags ^= mdb_envflags[i].mask; } else { /* unknown keyword */ rc = 1; } } break; case MDB_INDEX: if ( c->valx == -1 ) { int i; /* delete all (FIXME) */ for ( i = 0; i < mdb->mi_nattrs; i++ ) { mdb->mi_attrs[i]->ai_indexmask |= MDB_INDEX_DELETING; } mdb->mi_flags |= MDB_DEL_INDEX; c->cleanup = mdb_cf_cleanup; } else { struct berval bv, def = BER_BVC("default"); char *ptr; for (ptr = c->line; !isspace( (unsigned char) *ptr ); ptr++); bv.bv_val = c->line; bv.bv_len = ptr - bv.bv_val; if ( bvmatch( &bv, &def )) { mdb->mi_defaultmask = 0; } else { int i; char **attrs; char sep; sep = bv.bv_val[ bv.bv_len ]; bv.bv_val[ bv.bv_len ] = '\0'; attrs = ldap_str2charray( bv.bv_val, "," ); for ( i = 0; attrs[ i ]; i++ ) { AttributeDescription *ad = NULL; const char *text; AttrInfo *ai; slap_str2ad( attrs[ i ], &ad, &text ); /* if we got here... */ assert( ad != NULL ); ai = mdb_attr_mask( mdb, ad ); /* if we got here... */ assert( ai != NULL ); ai->ai_indexmask |= MDB_INDEX_DELETING; mdb->mi_flags |= MDB_DEL_INDEX; c->cleanup = mdb_cf_cleanup; } bv.bv_val[ bv.bv_len ] = sep; ldap_charray_free( attrs ); } } break; } return rc; } switch( c->type ) { case MDB_MODE: if ( ASCII_DIGIT( c->argv[1][0] ) ) { long mode; char *next; errno = 0; mode = strtol( c->argv[1], &next, 0 ); if ( errno != 0 || next == c->argv[1] || next[0] != '\0' ) { fprintf( stderr, "%s: " "unable to parse mode=\"%s\".\n", c->log, c->argv[1] ); return 1; } mdb->mi_dbenv_mode = mode; } else { char *m = c->argv[1]; int who, what, mode = 0; if ( strlen( m ) != STRLENOF("-rwxrwxrwx") ) { return 1; } if ( m[0] != '-' ) { return 1; } m++; for ( who = 0; who < 3; who++ ) { for ( what = 0; what < 3; what++, m++ ) { if ( m[0] == '-' ) { continue; } else if ( m[0] != "rwx"[what] ) { return 1; } mode += ((1 << (2 - what)) << 3*(2 - who)); } } mdb->mi_dbenv_mode = mode; } break; case MDB_CHKPT: { long l; mdb->mi_txn_cp = 1; if ( lutil_atolx( &l, c->argv[1], 0 ) != 0 ) { fprintf( stderr, "%s: " "invalid kbyte \"%s\" in \"checkpoint\".\n", c->log, c->argv[1] ); return 1; } mdb->mi_txn_cp_kbyte = l; if ( lutil_atolx( &l, c->argv[2], 0 ) != 0 ) { fprintf( stderr, "%s: " "invalid minutes \"%s\" in \"checkpoint\".\n", c->log, c->argv[2] ); return 1; } mdb->mi_txn_cp_min = l; /* If we're in server mode and time-based checkpointing is enabled, * submit a task to perform periodic checkpoints. */ if ((slapMode & SLAP_SERVER_MODE) && mdb->mi_txn_cp_min ) { struct re_s *re = mdb->mi_txn_cp_task; if ( re ) { re->interval.tv_sec = mdb->mi_txn_cp_min * 60; } else { if ( c->be->be_suffix == NULL || BER_BVISNULL( &c->be->be_suffix[0] ) ) { fprintf( stderr, "%s: " "\"checkpoint\" must occur after \"suffix\".\n", c->log ); return 1; } ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); mdb->mi_txn_cp_task = ldap_pvt_runqueue_insert( &slapd_rq, mdb->mi_txn_cp_min * 60, mdb_checkpoint, mdb, LDAP_XSTRING(mdb_checkpoint), c->be->be_suffix[0].bv_val ); ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); } } } break; case MDB_DIRECTORY: { FILE *f; char *ptr, *testpath; int len; len = strlen( c->value_string ); testpath = ch_malloc( len + STRLENOF(LDAP_DIRSEP) + STRLENOF("DUMMY") + 1 ); ptr = lutil_strcopy( testpath, c->value_string ); *ptr++ = LDAP_DIRSEP[0]; strcpy( ptr, "DUMMY" ); f = fopen( testpath, "w" ); if ( f ) { fclose( f ); unlink( testpath ); } ch_free( testpath ); if ( !f ) { snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid path: %s", c->log, strerror( errno )); Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 ); return -1; } if ( mdb->mi_dbenv_home ) ch_free( mdb->mi_dbenv_home ); mdb->mi_dbenv_home = c->value_string; } break; case MDB_DBNOSYNC: if ( c->value_int ) mdb->mi_dbenv_flags |= MDB_NOSYNC; else mdb->mi_dbenv_flags ^= MDB_NOSYNC; if ( mdb->mi_flags & MDB_IS_OPEN ) { mdb_env_set_flags( mdb->mi_dbenv, MDB_NOSYNC, c->value_int ); } break; case MDB_ENVFLAGS: { int i, j; for ( i=1; i<c->argc; i++ ) { j = verb_to_mask( c->argv[i], mdb_envflags ); if ( mdb_envflags[j].mask ) { if ( mdb->mi_flags & MDB_IS_OPEN ) rc = mdb_env_set_flags( mdb->mi_dbenv, mdb_envflags[j].mask, 1 ); else rc = 0; if ( rc ) { mdb->mi_flags |= MDB_RE_OPEN; c->cleanup = mdb_cf_cleanup; rc = 0; } mdb->mi_dbenv_flags |= mdb_envflags[j].mask; } else { /* unknown keyword */ rc = 1; } } } break; case MDB_INDEX: rc = mdb_attr_index_config( mdb, c->fname, c->lineno, c->argc - 1, &c->argv[1], &c->reply); if( rc != LDAP_SUCCESS ) return 1; c->cleanup = mdb_cf_cleanup; mdb->mi_flags |= MDB_OPEN_INDEX; if (( mdb->mi_flags & MDB_IS_OPEN ) && !mdb->mi_index_task ) { /* Start the task as soon as we finish here. Set a long * interval (10 hours) so that it only gets scheduled once. */ if ( c->be->be_suffix == NULL || BER_BVISNULL( &c->be->be_suffix[0] ) ) { fprintf( stderr, "%s: " "\"index\" must occur after \"suffix\".\n", c->log ); return 1; } ldap_pvt_thread_mutex_lock( &slapd_rq.rq_mutex ); mdb->mi_index_task = ldap_pvt_runqueue_insert( &slapd_rq, 36000, mdb_online_index, c->be, LDAP_XSTRING(mdb_online_index), c->be->be_suffix[0].bv_val ); ldap_pvt_thread_mutex_unlock( &slapd_rq.rq_mutex ); } break; case MDB_SSTACK: if ( c->value_int < MINIMUM_SEARCH_STACK_DEPTH ) { fprintf( stderr, "%s: depth %d too small, using %d\n", c->log, c->value_int, MINIMUM_SEARCH_STACK_DEPTH ); c->value_int = MINIMUM_SEARCH_STACK_DEPTH; } mdb->mi_search_stack_depth = c->value_int; break; case MDB_MAXREADERS: mdb->mi_readers = c->value_int; if ( mdb->mi_flags & MDB_IS_OPEN ) { mdb->mi_flags |= MDB_RE_OPEN; c->cleanup = mdb_cf_cleanup; } break; case MDB_MAXSIZE: mdb->mi_mapsize = c->value_ulong; if ( mdb->mi_flags & MDB_IS_OPEN ) { mdb->mi_flags |= MDB_RE_OPEN; c->cleanup = mdb_cf_cleanup; } break; } return 0; }
int main( int argc, char **argv ) { int i; char *uri = NULL; char *host = "localhost"; int port = -1; char *manager = NULL; struct berval passwd = { 0, NULL }; char outstr[BUFSIZ]; int ptpass; int testfail = 0; tester_init( "slapd-mtread", TESTER_READ ); /* by default, tolerate referrals and no such object */ tester_ignore_str2errlist( "REFERRAL,NO_SUCH_OBJECT" ); while ( (i = getopt( argc, argv, "ACc:D:e:Ff:H:h:i:L:l:M:m:p:r:t:T:w:v" )) != EOF ) { switch ( i ) { case 'A': noattrs++; break; case 'C': chaserefs++; break; case 'H': /* the server uri */ uri = strdup( optarg ); break; case 'h': /* the servers host */ host = strdup( optarg ); break; case 'i': tester_ignore_str2errlist( optarg ); break; case 'N': nobind++; break; case 'v': verbose++; break; case 'p': /* the servers port */ if ( lutil_atoi( &port, optarg ) != 0 ) { usage( argv[0] ); } break; case 'D': /* the servers manager */ manager = strdup( optarg ); break; case 'w': /* the server managers password */ passwd.bv_val = strdup( optarg ); passwd.bv_len = strlen( optarg ); memset( optarg, '*', passwd.bv_len ); break; case 'c': /* the number of connections */ if ( lutil_atoi( &noconns, optarg ) != 0 ) { usage( argv[0] ); } break; case 'e': /* DN to search for */ entry = strdup( optarg ); break; case 'f': /* the search request */ filter = strdup( optarg ); break; case 'F': force++; break; case 'l': /* the number of loops */ if ( lutil_atoi( &loops, optarg ) != 0 ) { usage( argv[0] ); } break; case 'L': /* the number of outerloops */ if ( lutil_atoi( &outerloops, optarg ) != 0 ) { usage( argv[0] ); } break; case 'M': /* the number of R/W threads */ if ( lutil_atoi( &rwthreads, optarg ) != 0 ) { usage( argv[0] ); } if (rwthreads > MAX_THREAD) rwthreads = MAX_THREAD; break; case 'm': /* the number of threads */ if ( lutil_atoi( &threads, optarg ) != 0 ) { usage( argv[0] ); } if (threads > MAX_THREAD) threads = MAX_THREAD; break; case 'r': /* the number of retries */ if ( lutil_atoi( &retries, optarg ) != 0 ) { usage( argv[0] ); } break; case 't': /* delay in seconds */ if ( lutil_atoi( &delay, optarg ) != 0 ) { usage( argv[0] ); } break; case 'T': attrs = ldap_str2charray( optarg, "," ); if ( attrs == NULL ) { usage( argv[0] ); } break; default: usage( argv[0] ); break; } } if (( entry == NULL ) || ( port == -1 && uri == NULL )) usage( argv[0] ); if ( *entry == '\0' ) { fprintf( stderr, "%s: invalid EMPTY entry DN.\n", argv[0] ); exit( EXIT_FAILURE ); } if ( argv[optind] != NULL ) { attrs = &argv[optind]; } if (noconns < 1) noconns = 1; if (noconns > MAXCONN) noconns = MAXCONN; lds = (LDAP **) calloc( sizeof(LDAP *), noconns); if (lds == NULL) { fprintf( stderr, "%s: Memory error: calloc noconns.\n", argv[0] ); exit( EXIT_FAILURE ); } uri = tester_uri( uri, host, port ); /* One connection and one connection only */ do_conn( uri, manager, &passwd, &ld, nobind, retries, 0 ); lds[0] = ld; for(i = 1; i < noconns; i++) { do_conn( uri, manager, &passwd, &lds[i], nobind, retries, i ); } ldap_pvt_thread_initialize(); snprintf(outstr, BUFSIZ, "MT Test Start: conns: %d (%s)", noconns, uri); tester_error(outstr); snprintf(outstr, BUFSIZ, "Threads: RO: %d RW: %d", threads, rwthreads); tester_error(outstr); /* Set up read only threads */ for ( i = 0; i < threads; i++ ) { ldap_pvt_thread_create( &rtid[i], 0, do_onethread, &rtid[i]); snprintf(outstr, BUFSIZ, "Created RO thread %d", i); thread_verbose(-1, outstr); } /* Set up read/write threads */ for ( i = 0; i < rwthreads; i++ ) { ldap_pvt_thread_create( &rwtid[i], 0, do_onerwthread, &rwtid[i]); snprintf(outstr, BUFSIZ, "Created RW thread %d", i + MAX_THREAD); thread_verbose(-1, outstr); } ptpass = outerloops * loops; /* wait for read only threads to complete */ for ( i = 0; i < threads; i++ ) ldap_pvt_thread_join(rtid[i], NULL); /* wait for read/write threads to complete */ for ( i = 0; i < rwthreads; i++ ) ldap_pvt_thread_join(rwtid[i], NULL); for(i = 0; i < noconns; i++) { if ( lds[i] != NULL ) { ldap_unbind_ext( lds[i], NULL, NULL ); } } free( lds ); for ( i = 0; i < threads; i++ ) { snprintf(outstr, BUFSIZ, "RO thread %d pass=%d fail=%d", i, rt_pass[i], rt_fail[i]); tester_error(outstr); if (rt_fail[i] != 0 || rt_pass[i] != ptpass) { snprintf(outstr, BUFSIZ, "FAIL RO thread %d", i); tester_error(outstr); testfail++; } } for ( i = 0; i < rwthreads; i++ ) { snprintf(outstr, BUFSIZ, "RW thread %d pass=%d fail=%d", i + MAX_THREAD, rwt_pass[i], rwt_fail[i]); tester_error(outstr); if (rwt_fail[i] != 0 || rwt_pass[i] != ptpass) { snprintf(outstr, BUFSIZ, "FAIL RW thread %d", i); tester_error(outstr); testfail++; } } snprintf(outstr, BUFSIZ, "MT Test complete" ); tester_error(outstr); if (testfail) exit( EXIT_FAILURE ); exit( EXIT_SUCCESS ); }