Ejemplo n.º 1
0
static int
bdb_attr_index_unparser( void *v1, void *v2 )
{
	AttrInfo *ai = v1;
	BerVarray *bva = v2;
	struct berval bv;
	char *ptr;

	slap_index2bvlen( ai->ai_indexmask, &bv );
	if ( bv.bv_len ) {
		bv.bv_len += ai->ai_desc->ad_cname.bv_len + 1;
		ptr = ch_malloc( bv.bv_len+1 );
		bv.bv_val = lutil_strcopy( ptr, ai->ai_desc->ad_cname.bv_val );
		*bv.bv_val++ = ' ';
		slap_index2bv( ai->ai_indexmask, &bv );
		bv.bv_val = ptr;
		ber_bvarray_add( bva, &bv );
	}
	return 0;
}
Ejemplo n.º 2
0
static int
shell_cf( ConfigArgs *c )
{
	struct shellinfo	*si = (struct shellinfo *) c->be->be_private;
	char ***arr = &si->si_bind;

	if ( c->op == SLAP_CONFIG_EMIT ) {
		struct berval bv;
		if ( !arr[c->type] ) return 1;
		bv.bv_val = ldap_charray2str( arr[c->type], " " );
		bv.bv_len = strlen( bv.bv_val );
		ber_bvarray_add( &c->rvalue_vals, &bv );
	} else if ( c->op == LDAP_MOD_DELETE ) {
		ldap_charray_free( arr[c->type] );
		arr[c->type] = NULL;
	} else {
		arr[c->type] = ldap_charray_dup( &c->argv[1] );
	}
	return 0;
}
Ejemplo n.º 3
0
void
slapi_int_plugin_unparse(
	Backend *be,
	BerVarray *out
)
{
	Slapi_PBlock *pp;
	int i, j;
	char **argv, ibuf[32], *ptr;
	struct berval idx, bv;

	*out = NULL;
	idx.bv_val = ibuf;
	i = 0;

	for ( pp = SLAPI_BACKEND_PBLOCK( be );
	      pp != NULL;
	      slapi_pblock_get( pp, SLAPI_IBM_PBLOCK, &pp ) )
	{
		slapi_pblock_get( pp, SLAPI_X_CONFIG_ARGV, &argv );
		if ( argv == NULL ) /* could be dynamic plugin */
			continue;
		idx.bv_len = snprintf( idx.bv_val, sizeof( ibuf ), "{%d}", i );
		if ( idx.bv_len >= sizeof( ibuf ) ) {
			/* FIXME: just truncating by now */
			idx.bv_len = sizeof( ibuf ) - 1;
		}
		bv.bv_len = idx.bv_len;
		for (j=1; argv[j]; j++) {
			bv.bv_len += strlen(argv[j]);
			if ( j ) bv.bv_len++;
		}
		bv.bv_val = ch_malloc( bv.bv_len + 1 );
		ptr = lutil_strcopy( bv.bv_val, ibuf );
		for (j=1; argv[j]; j++) {
			if ( j ) *ptr++ = ' ';
			ptr = lutil_strcopy( ptr, argv[j] );
		}
		ber_bvarray_add( out, &bv );
	}
}
Ejemplo n.º 4
0
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;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
static int
sql_cf_gen( ConfigArgs *c )
{
	backsql_info 	*bi = (backsql_info *)c->be->be_private;
	int rc = 0;

	if ( c->op == SLAP_CONFIG_EMIT ) {
		switch( c->type ) {
		case BSQL_CONCAT_PATT:
			if ( bi->sql_concat_patt ) {
				c->value_string = ch_strdup( bi->sql_concat_patt );
			} else {
				rc = 1;
			}
			break;
		case BSQL_CREATE_NEEDS_SEL:
			if ( bi->sql_flags & BSQLF_CREATE_NEEDS_SELECT )
				c->value_int = 1;
			break;
		case BSQL_UPPER_NEEDS_CAST:
			if ( bi->sql_flags & BSQLF_UPPER_NEEDS_CAST )
				c->value_int = 1;
			break;
		case BSQL_HAS_LDAPINFO_DN_RU:
			if ( !(bi->sql_flags & BSQLF_DONTCHECK_LDAPINFO_DN_RU) )
				return 1;
			if ( bi->sql_flags & BSQLF_HAS_LDAPINFO_DN_RU )
				c->value_int = 1;
			break;
		case BSQL_FAIL_IF_NO_MAPPING:
			if ( bi->sql_flags & BSQLF_FAIL_IF_NO_MAPPING )
				c->value_int = 1;
			break;
		case BSQL_ALLOW_ORPHANS:
			if ( bi->sql_flags & BSQLF_ALLOW_ORPHANS )
				c->value_int = 1;
			break;
		case BSQL_SUBTREE_SHORTCUT:
			if ( bi->sql_flags & BSQLF_USE_SUBTREE_SHORTCUT )
				c->value_int = 1;
			break;
		case BSQL_FETCH_ALL_ATTRS:
			if ( bi->sql_flags & BSQLF_FETCH_ALL_ATTRS )
				c->value_int = 1;
			break;
		case BSQL_CHECK_SCHEMA:
			if ( bi->sql_flags & BSQLF_CHECK_SCHEMA )
				c->value_int = 1;
			break;
		case BSQL_AUTOCOMMIT:
			if ( bi->sql_flags & BSQLF_AUTOCOMMIT_ON )
				c->value_int = 1;
			break;
		case BSQL_BASE_OBJECT:
			if ( bi->sql_base_ob_file ) {
				c->value_string = ch_strdup( bi->sql_base_ob_file );
			} else if ( bi->sql_baseObject ) {
				c->value_string = ch_strdup( "TRUE" );
			} else {
				rc = 1;
			}
			break;
		case BSQL_LAYER:
			if ( bi->sql_api ) {
				backsql_api *ba;
				struct berval bv;
				char *ptr;
				int i;
				for ( ba = bi->sql_api; ba; ba = ba->ba_next ) {
					bv.bv_len = strlen( ba->ba_name );
					if ( ba->ba_argc ) {
						for ( i = 0; i<ba->ba_argc; i++ )
							bv.bv_len += strlen( ba->ba_argv[i] ) + 3;
					}
					bv.bv_val = ch_malloc( bv.bv_len + 1 );
					ptr = lutil_strcopy( bv.bv_val, ba->ba_name );
					if ( ba->ba_argc ) {
						for ( i = 0; i<ba->ba_argc; i++ ) {
							*ptr++ = ' ';
							*ptr++ = '"';
							ptr = lutil_strcopy( ptr, ba->ba_argv[i] );
							*ptr++ = '"';
						}
					}
					ber_bvarray_add( &c->rvalue_vals, &bv );
				}
			} else {
				rc = 1;
			}
			break;
		case BSQL_ALIASING_KEYWORD:
			if ( !BER_BVISNULL( &bi->sql_aliasing )) {
				struct berval bv;
				bv = bi->sql_aliasing;
				bv.bv_len--;
				value_add_one( &c->rvalue_vals, &bv );
			} else {
				rc = 1;
			}
			break;
		case BSQL_FETCH_ATTRS:
			if ( bi->sql_anlist ||
				( bi->sql_flags & (BSQLF_FETCH_ALL_USERATTRS|
								   BSQLF_FETCH_ALL_OPATTRS)))
			{
				char buf[BUFSIZ*2], *ptr;
				struct berval bv;
#   define WHATSLEFT    ((ber_len_t) (&buf[sizeof( buf )] - ptr))
				ptr = buf;
				if ( bi->sql_anlist ) {
					ptr = anlist_unparse( bi->sql_anlist, ptr, WHATSLEFT );
					if ( ptr == NULL )
						return 1;
				}
				if ( bi->sql_flags & BSQLF_FETCH_ALL_USERATTRS ) {
					if ( WHATSLEFT <= STRLENOF( ",*" )) return 1;
					if ( ptr != buf ) *ptr++ = ',';
					*ptr++ = '*';
				}
				if ( bi->sql_flags & BSQLF_FETCH_ALL_OPATTRS ) {
					if ( WHATSLEFT <= STRLENOF( ",+" )) return 1;
					if ( ptr != buf ) *ptr++ = ',';
					*ptr++ = '+';
				}
				bv.bv_val = buf;
				bv.bv_len = ptr - buf;
				value_add_one( &c->rvalue_vals, &bv );
			}
			break;
		}
		return rc;
	} else if ( c->op == LDAP_MOD_DELETE ) {	/* FIXME */
		return -1;
	}

	switch( c->type ) {
	case BSQL_CONCAT_PATT:
		if ( backsql_split_pattern( c->argv[ 1 ], &bi->sql_concat_func, 2 ) ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ),
				"%s: unable to parse pattern \"%s\"",
				c->log, c->argv[ 1 ] );
			Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
			return -1;
		}
		bi->sql_concat_patt = c->value_string;
		break;
	case BSQL_CREATE_NEEDS_SEL:
		if ( c->value_int )
			bi->sql_flags |= BSQLF_CREATE_NEEDS_SELECT;
		else
			bi->sql_flags &= ~BSQLF_CREATE_NEEDS_SELECT;
		break;
	case BSQL_UPPER_NEEDS_CAST:
		if ( c->value_int )
			bi->sql_flags |= BSQLF_UPPER_NEEDS_CAST;
		else
			bi->sql_flags &= ~BSQLF_UPPER_NEEDS_CAST;
		break;
	case BSQL_HAS_LDAPINFO_DN_RU:
		bi->sql_flags |= BSQLF_DONTCHECK_LDAPINFO_DN_RU;
		if ( c->value_int )
			bi->sql_flags |= BSQLF_HAS_LDAPINFO_DN_RU;
		else
			bi->sql_flags &= ~BSQLF_HAS_LDAPINFO_DN_RU;
		break;
	case BSQL_FAIL_IF_NO_MAPPING:
		if ( c->value_int )
			bi->sql_flags |= BSQLF_FAIL_IF_NO_MAPPING;
		else
			bi->sql_flags &= ~BSQLF_FAIL_IF_NO_MAPPING;
		break;
	case BSQL_ALLOW_ORPHANS:
		if ( c->value_int )
			bi->sql_flags |= BSQLF_ALLOW_ORPHANS;
		else
			bi->sql_flags &= ~BSQLF_ALLOW_ORPHANS;
		break;
	case BSQL_SUBTREE_SHORTCUT:
		if ( c->value_int )
			bi->sql_flags |= BSQLF_USE_SUBTREE_SHORTCUT;
		else
			bi->sql_flags &= ~BSQLF_USE_SUBTREE_SHORTCUT;
		break;
	case BSQL_FETCH_ALL_ATTRS:
		if ( c->value_int )
			bi->sql_flags |= BSQLF_FETCH_ALL_ATTRS;
		else
			bi->sql_flags &= ~BSQLF_FETCH_ALL_ATTRS;
		break;
	case BSQL_CHECK_SCHEMA:
		if ( c->value_int )
			bi->sql_flags |= BSQLF_CHECK_SCHEMA;
		else
			bi->sql_flags &= ~BSQLF_CHECK_SCHEMA;
		break;
	case BSQL_AUTOCOMMIT:
		if ( c->value_int )
			bi->sql_flags |= BSQLF_AUTOCOMMIT_ON;
		else
			bi->sql_flags &= ~BSQLF_AUTOCOMMIT_ON;
		break;
	case BSQL_BASE_OBJECT:
		if ( c->be->be_nsuffix == NULL ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ),
				"%s: suffix must be set", c->log );
			Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
			rc = ARG_BAD_CONF;
			break;
		}
		if ( bi->sql_baseObject ) {
			Debug( LDAP_DEBUG_CONFIG,
				"%s: "
				"\"baseObject\" already provided (will be overwritten)\n",
				c->log, 0, 0 );
			entry_free( bi->sql_baseObject );
		}
		if ( c->argc == 2 && !strcmp( c->argv[1], "TRUE" ))
			c->argc = 1;
		switch( c->argc ) {
		case 1:
			return create_baseObject( c->be, c->fname, c->lineno );

		case 2:
			rc = read_baseObject( c->be, c->argv[ 1 ] );
			if ( rc == 0 ) {
				ch_free( bi->sql_base_ob_file );
				bi->sql_base_ob_file = c->value_string;
			}
			return rc;

		default:
			snprintf( c->cr_msg, sizeof( c->cr_msg ),
				"%s: trailing values in directive", c->log );
			Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
			return 1;
		}
		break;
	case BSQL_LAYER:
		if ( backsql_api_config( bi, c->argv[ 1 ], c->argc - 2, &c->argv[ 2 ] ) )
		{
			snprintf( c->cr_msg, sizeof( c->cr_msg ),
				"%s: unable to load sql layer", c->log );
			Debug( LDAP_DEBUG_ANY, "%s \"%s\"\n",
				c->cr_msg, c->argv[1], 0 );
			return 1;
		}
		break;
	case BSQL_ALIASING_KEYWORD:
		if ( ! BER_BVISNULL( &bi->sql_aliasing ) ) {
			ch_free( bi->sql_aliasing.bv_val );
		}

		ber_str2bv( c->argv[ 1 ], strlen( c->argv[ 1 ] ) + 1, 1,
			&bi->sql_aliasing );
		/* add a trailing space... */
		bi->sql_aliasing.bv_val[ bi->sql_aliasing.bv_len - 1] = ' ';
		break;
	case BSQL_FETCH_ATTRS: {
		char		*str, *s, *next;
		const char	*delimstr = ",";

		str = ch_strdup( c->argv[ 1 ] );
		for ( s = ldap_pvt_strtok( str, delimstr, &next );
				s != NULL;
				s = ldap_pvt_strtok( NULL, delimstr, &next ) )
		{
			if ( strlen( s ) == 1 ) {
				if ( *s == '*' ) {
					bi->sql_flags |= BSQLF_FETCH_ALL_USERATTRS;
					c->argv[ 1 ][ s - str ] = ',';

				} else if ( *s == '+' ) {
					bi->sql_flags |= BSQLF_FETCH_ALL_OPATTRS;
					c->argv[ 1 ][ s - str ] = ',';
				}
			}
		}
		ch_free( str );
		bi->sql_anlist = str2anlist( bi->sql_anlist, c->argv[ 1 ], delimstr );
		if ( bi->sql_anlist == NULL ) {
			return -1;
		}
		}
		break;
	}
	return rc;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 8
0
int
backsql_split_pattern(
	const char	*_pattern,
	BerVarray	*split_pattern,
	int		expected )
{
	char		*pattern, *start, *end;
	struct berval	bv;
	int		rc = 0;

#define SPLIT_CHAR	'?'
	
	assert( _pattern != NULL );
	assert( split_pattern != NULL );

	pattern = ch_strdup( _pattern );

	start = pattern;
	end = strchr( start, SPLIT_CHAR );
	for ( ; start; expected-- ) {
		char		*real_end = end;
		ber_len_t	real_len;
		
		if ( real_end == NULL ) {
			real_end = start + strlen( start );

		} else if ( real_end[ 1 ] == SPLIT_CHAR ) {
			expected++;
			AC_MEMCPY( real_end, real_end + 1, strlen( real_end ) );
			end = strchr( real_end + 1, SPLIT_CHAR );
			continue;
		}

		real_len = real_end - start;
		if ( real_len == 0 ) {
			ber_str2bv( "", 0, 1, &bv );
		} else {
			ber_str2bv( start, real_len, 1, &bv );
		}

		ber_bvarray_add( split_pattern, &bv );

		if ( expected == 0 ) {
			if ( end != NULL ) {
				rc = -1;
				goto done;
			}
			break;
		}

		if ( end != NULL ) {
			start = end + 1;
			end = strchr( start, SPLIT_CHAR );
		}
	}

done:;

     	ch_free( pattern );

	return rc;
}
Ejemplo n.º 9
0
static int dgroup_cf( ConfigArgs *c )
{
	slap_overinst *on = (slap_overinst *)c->bi;
	int rc = 1;

	switch( c->op ) {
	case SLAP_CONFIG_EMIT:
		{
		adpair *ap;
		for ( ap = on->on_bi.bi_private; ap; ap = ap->ap_next ) {
			struct berval bv;
			char *ptr;
			bv.bv_len = ap->ap_mem->ad_cname.bv_len + 1 +
				ap->ap_uri->ad_cname.bv_len;
			bv.bv_val = ch_malloc( bv.bv_len + 1 );
			ptr = lutil_strcopy( bv.bv_val, ap->ap_mem->ad_cname.bv_val );
			*ptr++ = ' ';
			strcpy( ptr, ap->ap_uri->ad_cname.bv_val );
			ber_bvarray_add( &c->rvalue_vals, &bv );
			rc = 0;
		}
		}
		break;
	case LDAP_MOD_DELETE:
		if ( c->valx == -1 ) {
			adpair *ap;
			while (( ap = on->on_bi.bi_private )) {
				on->on_bi.bi_private = ap->ap_next;
				ch_free( ap );
			}
		} else {
			adpair **app, *ap;
			int i;
			app = (adpair **)&on->on_bi.bi_private;
			for (i=0; i<=c->valx; i++, app = &ap->ap_next) {
				ap = *app;
			}
			*app = ap->ap_next;
			ch_free( ap );
		}
		rc = 0;
		break;
	case SLAP_CONFIG_ADD:
	case LDAP_MOD_ADD:
		{
		adpair ap = { NULL, NULL, NULL }, *a2;
		const char *text;
		if ( slap_str2ad( c->argv[1], &ap.ap_mem, &text ) ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s attribute description unknown: \"%s\"",
				c->argv[0], c->argv[1] );
			Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
				"%s: %s\n", c->log, c->cr_msg, 0 );
			return ARG_BAD_CONF;
		}
		if ( slap_str2ad( c->argv[2], &ap.ap_uri, &text ) ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s attribute description unknown: \"%s\"",
				c->argv[0], c->argv[2] );
			Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
				"%s: %s\n", c->log, c->cr_msg, 0 );
			return ARG_BAD_CONF;
		}
		/* The on->on_bi.bi_private pointer can be used for
		 * anything this instance of the overlay needs.
		 */
		a2 = ch_malloc( sizeof(adpair) );
		a2->ap_next = on->on_bi.bi_private;
		a2->ap_mem = ap.ap_mem;
		a2->ap_uri = ap.ap_uri;
		on->on_bi.bi_private = a2;
		rc = 0;
		}
	}
	return rc;
}
Ejemplo n.º 10
0
static int
valsort_cf_func(ConfigArgs *c) {
	slap_overinst *on = (slap_overinst *)c->bi;
	valsort_info vitmp, *vi;
	const char *text = NULL;
	int i, is_numeric;
	struct berval bv = BER_BVNULL;

	if ( c->op == SLAP_CONFIG_EMIT ) {
		for ( vi = on->on_bi.bi_private; vi; vi = vi->vi_next ) {
			struct berval bv2 = BER_BVNULL, bvret;
			char *ptr;
			int len;
			
			len = vi->vi_ad->ad_cname.bv_len + 1 + vi->vi_dn.bv_len + 2;
			i = vi->vi_sort;
			if ( i & VALSORT_WEIGHTED ) {
				enum_to_verb( sorts, VALSORT_WEIGHTED, &bv2 );
				len += bv2.bv_len + 1;
				i ^= VALSORT_WEIGHTED;
			}
			if ( i ) {
				enum_to_verb( sorts, i, &bv );
				len += bv.bv_len + 1;
			}
			bvret.bv_val = ch_malloc( len+1 );
			bvret.bv_len = len;

			ptr = lutil_strcopy( bvret.bv_val, vi->vi_ad->ad_cname.bv_val );
			*ptr++ = ' ';
			*ptr++ = '"';
			ptr = lutil_strcopy( ptr, vi->vi_dn.bv_val );
			*ptr++ = '"';
			if ( vi->vi_sort & VALSORT_WEIGHTED ) {
				*ptr++ = ' ';
				ptr = lutil_strcopy( ptr, bv2.bv_val );
			}
			if ( i ) {
				*ptr++ = ' ';
				strcpy( ptr, bv.bv_val );
			}
			ber_bvarray_add( &c->rvalue_vals, &bvret );
		}
		i = ( c->rvalue_vals != NULL ) ? 0 : 1;
		return i;
	} else if ( c->op == LDAP_MOD_DELETE ) {
		if ( c->valx < 0 ) {
			for ( vi = on->on_bi.bi_private; vi; vi = on->on_bi.bi_private ) {
				on->on_bi.bi_private = vi->vi_next;
				ch_free( vi->vi_dn.bv_val );
				ch_free( vi );
			}
		} else {
			valsort_info **prev;

			for (i=0, prev = (valsort_info **)&on->on_bi.bi_private,
				vi = *prev; vi && i<c->valx;
				prev = &vi->vi_next, vi = vi->vi_next, i++ );
			(*prev)->vi_next = vi->vi_next;
			ch_free( vi->vi_dn.bv_val );
			ch_free( vi );
		}
		return 0;
	}
	vitmp.vi_ad = NULL;
	i = slap_str2ad( c->argv[1], &vitmp.vi_ad, &text );
	if ( i ) {
		snprintf( c->cr_msg, sizeof( c->cr_msg), "<%s> %s", c->argv[0], text );
		Debug( LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
			c->log, c->cr_msg, c->argv[1] );
		return(1);
	}
	if ( is_at_single_value( vitmp.vi_ad->ad_type )) {
		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> %s is single-valued, ignoring", c->argv[0],
			vitmp.vi_ad->ad_cname.bv_val );
		Debug( LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
			c->log, c->cr_msg, c->argv[1] );
		return(0);
	}
	is_numeric = ( vitmp.vi_ad->ad_type->sat_syntax == syn_numericString ||
		vitmp.vi_ad->ad_type->sat_syntax == slap_schema.si_syn_integer ) ? 1
		: 0;
	ber_str2bv( c->argv[2], 0, 0, &bv );
	i = dnNormalize( 0, NULL, NULL, &bv, &vitmp.vi_dn, NULL );
	if ( i ) {
		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unable to normalize DN", c->argv[0] );
		Debug( LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
			c->log, c->cr_msg, c->argv[2] );
		return(1);
	}
	i = verb_to_mask( c->argv[3], sorts );
	if ( BER_BVISNULL( &sorts[i].word )) {
		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unrecognized sort type", c->argv[0] );
		Debug( LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
			c->log, c->cr_msg, c->argv[3] );
		return(1);
	}
	vitmp.vi_sort = sorts[i].mask;
	if ( sorts[i].mask == VALSORT_WEIGHTED && c->argc == 5 ) {
		i = verb_to_mask( c->argv[4], sorts );
		if ( BER_BVISNULL( &sorts[i].word )) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> unrecognized sort type", c->argv[0] );
			Debug( LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
				c->log, c->cr_msg, c->argv[4] );
			return(1);
		}
		vitmp.vi_sort |= sorts[i].mask;
	}
	if (( vitmp.vi_sort & VALSORT_NUMERIC ) && !is_numeric ) {
		snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> numeric sort specified for non-numeric syntax",
			c->argv[0] );
		Debug( LDAP_DEBUG_ANY, "%s: %s (%s)!\n",
			c->log, c->cr_msg, c->argv[1] );
		return(1);
	}
	vi = ch_malloc( sizeof(valsort_info) );
	*vi = vitmp;
	vi->vi_next = on->on_bi.bi_private;
	on->on_bi.bi_private = vi;
	return 0;
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 12
0
static int
collect_cf( ConfigArgs *c )
{
	slap_overinst *on = (slap_overinst *)c->bi;
	int rc = 1, idx;

	switch( c->op ) {
	case SLAP_CONFIG_EMIT:
		{
		collect_info *ci;
		for ( ci = on->on_bi.bi_private; ci; ci = ci->ci_next ) {
			struct berval bv;
			char *ptr;
			int len;

			/* calculate the length & malloc memory */
			bv.bv_len = ci->ci_dn.bv_len + STRLENOF("\"\" ");
			for (idx=0; idx<ci->ci_ad_num; idx++) {
				bv.bv_len += ci->ci_ad[idx]->ad_cname.bv_len;
				if (idx<(ci->ci_ad_num-1)) { 
					bv.bv_len++;
				}
			}
			bv.bv_val = ch_malloc( bv.bv_len + 1 );

			/* copy the value and update len */
			len = snprintf( bv.bv_val, bv.bv_len + 1, "\"%s\" ", 
				ci->ci_dn.bv_val);
			ptr = bv.bv_val + len;
			for (idx=0; idx<ci->ci_ad_num; idx++) {
				ptr = lutil_strncopy( ptr,
					ci->ci_ad[idx]->ad_cname.bv_val,
					ci->ci_ad[idx]->ad_cname.bv_len);
				if (idx<(ci->ci_ad_num-1)) {
					*ptr++ = ',';
				}
			}
			*ptr = '\0';
			bv.bv_len = ptr - bv.bv_val;

			ber_bvarray_add( &c->rvalue_vals, &bv );
			rc = 0;
		}
		}
		break;
	case LDAP_MOD_DELETE:
		if ( c->valx == -1 ) {
		/* Delete entire attribute */
			collect_info *ci;
			while (( ci = on->on_bi.bi_private )) {
				on->on_bi.bi_private = ci->ci_next;
				ch_free( ci->ci_dn.bv_val );
				ch_free( ci );
			}
		} else {
		/* Delete just one value */
			collect_info **cip, *ci;
			int i;
			cip = (collect_info **)&on->on_bi.bi_private;
			ci = *cip;
			for ( i=0; i < c->valx; i++ ) {
				cip = &ci->ci_next;
				ci = *cip;
			}
			*cip = ci->ci_next;
			ch_free( ci->ci_dn.bv_val );
			ch_free( ci );
		}
		rc = 0;
		break;
	case SLAP_CONFIG_ADD:
	case LDAP_MOD_ADD:
		{
		collect_info *ci;
		struct berval bv, dn;
		const char *text;
		int idx, count=0;
		char *arg;

		/* count delimiters in attribute argument */
		arg = strtok(c->argv[2], ",");
		while (arg!=NULL) {
			count++;
			arg = strtok(NULL, ",");
		}

		/* validate and normalize dn */
		ber_str2bv( c->argv[1], 0, 0, &bv );
		if ( dnNormalize( 0, NULL, NULL, &bv, &dn, NULL ) ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s invalid DN: \"%s\"",
				c->argv[0], c->argv[1] );
			Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
				"%s: %s\n", c->log, c->cr_msg, 0 );
			return ARG_BAD_CONF;
		}

		/* check for duplicate DNs */
		for ( ci = (collect_info *)on->on_bi.bi_private; ci;
			ci = ci->ci_next ) {
			/* If new DN is longest, there are no possible matches */
			if ( dn.bv_len > ci->ci_dn.bv_len ) {
				ci = NULL;
				break;
			}
			if ( bvmatch( &dn, &ci->ci_dn )) {
				break;
			}
		}
		if ( ci ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s DN already configured: \"%s\"",
				c->argv[0], c->argv[1] );
			Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
				"%s: %s\n", c->log, c->cr_msg, 0 );
			return ARG_BAD_CONF;
		}

		/* allocate config info with room for attribute array */
		ci = ch_malloc( sizeof( collect_info ) +
			sizeof( AttributeDescription * ) * count );

		/* load attribute description for attribute list */
		arg = c->argv[2];
		for( idx=0; idx<count; idx++) {
			ci->ci_ad[idx] = NULL;

			if ( slap_str2ad( arg, &ci->ci_ad[idx], &text ) ) {
				snprintf( c->cr_msg, sizeof( c->cr_msg ), 
					"%s attribute description unknown: \"%s\"",
					c->argv[0], arg);
				Debug( LDAP_DEBUG_CONFIG|LDAP_DEBUG_NONE,
					"%s: %s\n", c->log, c->cr_msg, 0 );
				ch_free( ci );
				return ARG_BAD_CONF;
			}
			while(*arg!='\0') {
				arg++; /* skip to end of argument */
			}
			if (idx<count-1) {
				arg++; /* skip inner delimiters */
			}
		}

		/* The on->on_bi.bi_private pointer can be used for
		 * anything this instance of the overlay needs.
		 */
		ci->ci_ad[count] = NULL;
		ci->ci_ad_num = count;
		ci->ci_dn = dn;

		/* creates list of ci's ordered by dn length */ 
		insert_ordered ( on, ci );

		/* New ci wasn't simply appended to end, adjust its
		 * position in the config entry's a_vals
		 */
		if ( c->ca_entry && ci->ci_next ) {
			Attribute *a = attr_find( c->ca_entry->e_attrs,
				collectcfg[0].ad );
			if ( a ) {
				struct berval bv, nbv;
				collect_info *c2 = (collect_info *)on->on_bi.bi_private;
				int i, j;
				for ( i=0; c2 != ci; i++, c2 = c2->ci_next );
				bv = a->a_vals[a->a_numvals-1];
				nbv = a->a_nvals[a->a_numvals-1];
				for ( j=a->a_numvals-1; j>i; j-- ) {
					a->a_vals[j] = a->a_vals[j-1];
					a->a_nvals[j] = a->a_nvals[j-1];
				}
				a->a_vals[j] = bv;
				a->a_nvals[j] = nbv;
			}
		}

		rc = 0;
		}
	}
	return rc;
}
Ejemplo n.º 13
0
static int
nss_cf_gen(ConfigArgs *c)
{
	slap_overinst *on = (slap_overinst *)c->bi;
	nssov_info *ni = on->on_bi.bi_private;
	nssov_mapinfo *mi;
	int i, j, rc = 0;
	slap_mask_t m;

	if ( c->op == SLAP_CONFIG_EMIT ) {
		switch(c->type) {
		case NSS_SSD:
			rc = 1;
			for (i=NM_alias;i<NM_NONE;i++) {
				struct berval scope;
				struct berval ssd;
				struct berval base;

				mi = &ni->ni_maps[i];

				/* ignore all-default services */
				if ( mi->mi_scope == LDAP_SCOPE_DEFAULT &&
					bvmatch( &mi->mi_filter, &mi->mi_filter0 ) &&
					BER_BVISNULL( &mi->mi_base ))
					continue;

				if ( BER_BVISNULL( &mi->mi_base ))
					base = ni->ni_db->be_nsuffix[0];
				else
					base = mi->mi_base;
				ldap_pvt_scope2bv(mi->mi_scope == LDAP_SCOPE_DEFAULT ?
					LDAP_SCOPE_SUBTREE : mi->mi_scope, &scope);
				ssd.bv_len = STRLENOF(" ldap:///???") + nss_svcs[i].word.bv_len +
					base.bv_len + scope.bv_len + mi->mi_filter.bv_len;
				ssd.bv_val = ch_malloc( ssd.bv_len + 1 );
				sprintf(ssd.bv_val, "%s ldap:///%s??%s?%s", nss_svcs[i].word.bv_val,
					base.bv_val, scope.bv_val, mi->mi_filter.bv_val );
				ber_bvarray_add( &c->rvalue_vals, &ssd );
				rc = 0;
			}
			break;
		case NSS_MAP:
			rc = 1;
			for (i=NM_alias;i<NM_NONE;i++) {

				mi = &ni->ni_maps[i];
				for (j=0;!BER_BVISNULL(&mi->mi_attrkeys[j]);j++) {
					if ( ber_bvstrcasecmp(&mi->mi_attrkeys[j],
						&mi->mi_attrs[j].an_name)) {
						struct berval map;

						map.bv_len = nss_svcs[i].word.bv_len +
							mi->mi_attrkeys[j].bv_len +
							mi->mi_attrs[j].an_desc->ad_cname.bv_len + 2;
						map.bv_val = ch_malloc(map.bv_len + 1);
						sprintf(map.bv_val, "%s %s %s", nss_svcs[i].word.bv_val,
							mi->mi_attrkeys[j].bv_val, mi->mi_attrs[j].an_desc->ad_cname.bv_val );
						ber_bvarray_add( &c->rvalue_vals, &map );
						rc = 0;
					}
				}
			}
			break;
		case NSS_PAM:
			rc = mask_to_verbs( pam_opts, ni->ni_pam_opts, &c->rvalue_vals );
			break;
		case NSS_PAMGROUP:
			if (!BER_BVISEMPTY( &ni->ni_pam_group_dn )) {
				value_add_one( &c->rvalue_vals, &ni->ni_pam_group_dn );
				value_add_one( &c->rvalue_nvals, &ni->ni_pam_group_dn );
			} else {
				rc = 1;
			}
			break;
		case NSS_PAMSESS:
			if (ni->ni_pam_sessions) {
				ber_bvarray_dup_x( &c->rvalue_vals, ni->ni_pam_sessions, NULL );
			} else {
				rc = 1;
			}
			break;
		}
		return rc;
	} else if ( c->op == LDAP_MOD_DELETE ) {
		/* FIXME */
		return 1;
	}
	switch( c->type ) {
	case NSS_SSD: {
		LDAPURLDesc *lud;

		i = verb_to_mask(c->argv[1], nss_svcs);
		if ( i == NM_NONE )
			return 1;

		mi = &ni->ni_maps[i];
		rc = ldap_url_parse(c->argv[2], &lud);
		if ( rc )
			return 1;
		do {
			struct berval base;
			/* Must be LDAP scheme */
			if (strcasecmp(lud->lud_scheme,"ldap")) {
				rc = 1;
				break;
			}
			/* Host part, attrs, and extensions must be empty */
			if (( lud->lud_host && *lud->lud_host ) ||
				lud->lud_attrs || lud->lud_exts ) {
				rc = 1;
				break;
			}
			ber_str2bv( lud->lud_dn,0,0,&base);
			rc = dnNormalize( 0,NULL,NULL,&base,&mi->mi_base,NULL);
			if ( rc )
				break;
			if ( lud->lud_filter ) {
				/* steal this */
				ber_str2bv( lud->lud_filter,0,0,&mi->mi_filter);
				lud->lud_filter = NULL;
			}
			mi->mi_scope = lud->lud_scope;
		} while(0);
		ldap_free_urldesc( lud );
		}
		break;
	case NSS_MAP:
		i = verb_to_mask(c->argv[1], nss_svcs);
		if ( i == NM_NONE )
			return 1;
		rc = 1;
		mi = &ni->ni_maps[i];
		for (j=0; !BER_BVISNULL(&mi->mi_attrkeys[j]); j++) {
			if (!strcasecmp(c->argv[2],mi->mi_attrkeys[j].bv_val)) {
				AttributeDescription *ad = NULL;
				const char *text;
				rc = slap_str2ad( c->argv[3], &ad, &text);
				if ( rc == 0 ) {
					mi->mi_attrs[j].an_desc = ad;
					mi->mi_attrs[j].an_name = ad->ad_cname;
				}
				break;
			}
		}
		break;
	case NSS_PAM:
		m = ni->ni_pam_opts;
		i = verbs_to_mask(c->argc, c->argv, pam_opts, &m);
		if (i == 0) {
			ni->ni_pam_opts = m;
			if ((m & NI_PAM_USERHOST) && !nssov_pam_host_ad) {
				const char *text;
				i = slap_str2ad("host", &nssov_pam_host_ad, &text);
				if (i != LDAP_SUCCESS) {
					snprintf(c->cr_msg, sizeof(c->cr_msg),
						"nssov: host attr unknown: %s", text);
					Debug(LDAP_DEBUG_ANY,"%s\n",c->cr_msg,0,0);
					rc = 1;
					break;
				}
			}
			if ((m & (NI_PAM_USERSVC|NI_PAM_HOSTSVC)) && !nssov_pam_svc_ad) {
				const char *text;
				i = slap_str2ad("authorizedService", &nssov_pam_svc_ad, &text);
				if (i != LDAP_SUCCESS) {
					snprintf(c->cr_msg, sizeof(c->cr_msg),
						"nssov: authorizedService attr unknown: %s", text);
					Debug(LDAP_DEBUG_ANY,"%s\n",c->cr_msg,0,0);
					rc = 1;
					break;
				}
			}
		} else {
			rc = 1;
		}
		break;
	case NSS_PAMGROUP:
		ni->ni_pam_group_dn = c->value_ndn;
		ch_free( c->value_dn.bv_val );
		break;
	case NSS_PAMSESS:
		ber_bvarray_add( &ni->ni_pam_sessions, &c->value_bv );
		break;
	}
	return rc;
}
Ejemplo n.º 14
0
static int
adremap_cf_dnv(ConfigArgs *c)
{
	BackendDB *be = (BackendDB *)c->be;
	slap_overinst *on = (slap_overinst *)c->bi;
	adremap_info *ai = on->on_bi.bi_private;
	adremap_dnv *ad, **a2;
	int rc = ARG_BAD_CONF;

	switch(c->op) {
	case SLAP_CONFIG_EMIT:
		for (ad = ai->ai_dnv; ad; ad=ad->ad_next) {
			char *ptr;
			struct berval bv;
			bv.bv_len = ad->ad_dnattr->ad_cname.bv_len + ad->ad_deref->ad_cname.bv_len + ad->ad_newattr->ad_cname.bv_len + 2;
			bv.bv_len += ad->ad_group->soc_cname.bv_len + ad->ad_mapgrp->soc_cname.bv_len + ad->ad_refgrp->soc_cname.bv_len + 3;
			bv.bv_len += ad->ad_refbase.bv_len + 3;
			bv.bv_val = ch_malloc(bv.bv_len + 1);
			ptr = lutil_strcopy(bv.bv_val, ad->ad_dnattr->ad_cname.bv_val);
			*ptr++ = ' ';
			ptr = lutil_strcopy(ptr, ad->ad_deref->ad_cname.bv_val);
			*ptr++ = ' ';
			ptr = lutil_strcopy(ptr, ad->ad_newattr->ad_cname.bv_val);
			*ptr++ = ' ';
			ptr = lutil_strcopy(ptr, ad->ad_group->soc_cname.bv_val);
			*ptr++ = ' ';
			ptr = lutil_strcopy(ptr, ad->ad_mapgrp->soc_cname.bv_val);
			*ptr++ = ' ';
			ptr = lutil_strcopy(ptr, ad->ad_refgrp->soc_cname.bv_val);
			*ptr++ = ' ';
			*ptr++ = '"';
			ptr = lutil_strcopy(ptr, ad->ad_refbase.bv_val);
			*ptr++ = '"';
			*ptr = '\0';
			ber_bvarray_add(&c->rvalue_vals, &bv);
		}
		if (ai->ai_dnv) rc = 0;
		break;
	case LDAP_MOD_DELETE:
		if (c->valx < 0) {
			for (ad = ai->ai_dnv; ad; ad=ai->ai_dnv) {
				ai->ai_dnv = ad->ad_next;
				ch_free(ad);
			}
		} else {
			int i;
			for (i=0, a2 = &ai->ai_dnv; i<c->valx; i++, a2 = &(*a2)->ad_next);
			ad = *a2;
			*a2 = ad->ad_next;
			ch_free(ad);
		}
		rc = 0;
		break;
	default: {
		const char *text;
		adremap_dnv av = {0};
		struct berval dn;
		rc = slap_str2ad(c->argv[1], &av.ad_dnattr, &text);
		if (rc) break;
		if (av.ad_dnattr->ad_type->sat_syntax != slap_schema.si_syn_distinguishedName) {
			rc = 1;
			snprintf(c->cr_msg, sizeof(c->cr_msg), "<%s> not a DN-valued attribute",
				c->argv[0]);
			Debug(LDAP_DEBUG_ANY, "%s: %s(%s)\n", c->log, c->cr_msg, c->argv[1]);
			break;
		}
		rc = slap_str2ad(c->argv[2], &av.ad_deref, &text);
		if (rc) break;
		rc = slap_str2ad(c->argv[3], &av.ad_newattr, &text);
		if (rc) break;
		av.ad_group = oc_find(c->argv[4]);
		if (!av.ad_group) {
			rc = 1;
			break;
		}
		av.ad_mapgrp = oc_find(c->argv[5]);
		if (!av.ad_mapgrp) {
			rc = 1;
			break;
		}
		av.ad_refgrp = oc_find(c->argv[6]);
		if (!av.ad_refgrp) {
			rc = 1;
			break;
		}
		ber_str2bv(c->argv[7], 0, 0, &dn);
		rc = dnNormalize(0, NULL, NULL, &dn, &av.ad_refbase, NULL);
		if (rc) break;

		for (a2 = &ai->ai_dnv; *a2; a2 = &(*a2)->ad_next);
		ad = ch_malloc(sizeof(adremap_dnv));
		ad->ad_next = NULL;
		ad->ad_dnattr = av.ad_dnattr;
		ad->ad_deref = av.ad_deref;
		ad->ad_newattr = av.ad_newattr;
		ad->ad_group = av.ad_group;
		ad->ad_mapgrp = av.ad_mapgrp;
		ad->ad_refgrp = av.ad_refgrp;
		ad->ad_refbase = av.ad_refbase;
		*a2 = ad;
		break;
		}
	}
	return rc;
}