예제 #1
0
static int
dynlist_make_filter( Operation *op, struct berval *oldf, struct berval *newf )
{
	slap_overinst	*on = (slap_overinst *)op->o_bd->bd_info;
	dynlist_info_t	*dli = (dynlist_info_t *)on->on_bi.bi_private;

	char		*ptr;

	assert( oldf != NULL );
	assert( newf != NULL );
	assert( !BER_BVISNULL( oldf ) );
	assert( !BER_BVISEMPTY( oldf ) );

	newf->bv_len = STRLENOF( "(&(!(objectClass=" "))" ")" )
		+ dli->dli_oc->soc_cname.bv_len + oldf->bv_len;
	newf->bv_val = op->o_tmpalloc( newf->bv_len + 1, op->o_tmpmemctx );
	if ( newf->bv_val == NULL ) {
		return -1;
	}
	ptr = lutil_strcopy( newf->bv_val, "(&(!(objectClass=" );
	ptr = lutil_strcopy( ptr, dli->dli_oc->soc_cname.bv_val );
	ptr = lutil_strcopy( ptr, "))" );
	ptr = lutil_strcopy( ptr, oldf->bv_val );
	ptr = lutil_strcopy( ptr, ")" );
	newf->bv_len = ptr - newf->bv_val;

	return 0;
}
예제 #2
0
static int
pg_dynacl_unparse(
	void		*priv,
	struct berval	*bv )
{
	pg_t		*pg = (pg_t *)priv;
	char		*ptr;

	bv->bv_len = STRLENOF( " dynacl/posixGroup.expand=" ) + pg->pg_pat.bv_len;
	bv->bv_val = ch_malloc( bv->bv_len + 1 );

	ptr = lutil_strcopy( bv->bv_val, " dynacl/posixGroup" );

	switch ( pg->pg_style ) {
	case ACL_STYLE_BASE:
		ptr = lutil_strcopy( ptr, ".exact=" );
		break;

	case ACL_STYLE_EXPAND:
		ptr = lutil_strcopy( ptr, ".expand=" );
		break;

	default:
		assert( 0 );
	}

	ptr = lutil_strncopy( ptr, pg->pg_pat.bv_val, pg->pg_pat.bv_len );
	ptr[ 0 ] = '\0';

	bv->bv_len = ptr - bv->bv_val;

	return 0;
}
예제 #3
0
static char *
rwm_suffix_massage_patternize( const char *s, const char *p )
{
	ber_len_t	len;
	char		*res, *ptr;

	len = strlen( p );

	if ( s[ 0 ] == '\0' ) {
		len++;
	}

	res = ch_calloc( sizeof( char ), len + STRLENOF( "%1" ) + 1 );
	if ( res == NULL ) {
		return NULL;
	}

	ptr = lutil_strcopy( res, ( p[0] == '\0' ? "%2" : "%1" ) );
	if ( s[ 0 ] == '\0' ) {
		ptr[ 0 ] = ',';
		ptr++;
	}
	lutil_strcopy( ptr, p );

	return res;
}
예제 #4
0
int
perl_back_compare(
	Operation	*op,
	SlapReply	*rs )
{
	int count;
	char *avastr;

	PerlBackend *perl_back = (PerlBackend *)op->o_bd->be_private;

	avastr = ch_malloc( op->orc_ava->aa_desc->ad_cname.bv_len + 1 +
		op->orc_ava->aa_value.bv_len + 1 );
	
	lutil_strcopy( lutil_strcopy( lutil_strcopy( avastr,
		op->orc_ava->aa_desc->ad_cname.bv_val ), "=" ),
		op->orc_ava->aa_value.bv_val );

#if defined(HAVE_WIN32_ASPERL) || defined(USE_ITHREADS)
	PERL_SET_CONTEXT( PERL_INTERPRETER );
#endif
	ldap_pvt_thread_mutex_lock( &perl_interpreter_mutex );	

	{
		dSP; ENTER; SAVETMPS;

		PUSHMARK(sp);
		XPUSHs( perl_back->pb_obj_ref );
		XPUSHs(sv_2mortal(newSVpv( op->o_req_dn.bv_val , 0)));
		XPUSHs(sv_2mortal(newSVpv( avastr , 0)));
		PUTBACK;

#ifdef PERL_IS_5_6
		count = call_method("compare", G_SCALAR);
#else
		count = perl_call_method("compare", G_SCALAR);
#endif

		SPAGAIN;

		if (count != 1) {
			croak("Big trouble in back_compare\n");
		}

		rs->sr_err = POPi;

		PUTBACK; FREETMPS; LEAVE;
	}

	ldap_pvt_thread_mutex_unlock( &perl_interpreter_mutex );	

	ch_free( avastr );

	send_ldap_result( op, rs );

	Debug( LDAP_DEBUG_ANY, "Perl COMPARE\n", 0, 0, 0 );

	return (0);
}
예제 #5
0
파일: dn2id.c 프로젝트: cptaffe/openldap
/* This function constructs a full DN for a given entry.
 */
int hdb_fix_dn(
	Entry *e,
	int checkit )
{
	EntryInfo *ei;
	int rlen = 0, nrlen = 0;
	char *ptr, *nptr;
	int max = 0;

	if ( !e->e_id )
		return 0;

	/* count length of all DN components */
	for ( ei = BEI(e); ei && ei->bei_id; ei=ei->bei_parent ) {
		rlen += ei->bei_rdn.bv_len + 1;
		nrlen += ei->bei_nrdn.bv_len + 1;
		if (ei->bei_modrdns > max) max = ei->bei_modrdns;
	}

	/* See if the entry DN was invalidated by a subtree rename */
	if ( checkit ) {
		if ( BEI(e)->bei_modrdns >= max ) {
			return 0;
		}
		/* We found a mismatch, tell the caller to lock it */
		if ( checkit == 1 ) {
			return 1;
		}
		/* checkit == 2. do the fix. */
		free( e->e_name.bv_val );
		free( e->e_nname.bv_val );
	}

	e->e_name.bv_len = rlen - 1;
	e->e_nname.bv_len = nrlen - 1;
	e->e_name.bv_val = ch_malloc(rlen);
	e->e_nname.bv_val = ch_malloc(nrlen);
	ptr = e->e_name.bv_val;
	nptr = e->e_nname.bv_val;
	for ( ei = BEI(e); ei && ei->bei_id; ei=ei->bei_parent ) {
		ptr = lutil_strcopy(ptr, ei->bei_rdn.bv_val);
		nptr = lutil_strcopy(nptr, ei->bei_nrdn.bv_val);
		if ( ei->bei_parent ) {
			*ptr++ = ',';
			*nptr++ = ',';
		}
	}
	BEI(e)->bei_modrdns = max;
	if ( ptr > e->e_name.bv_val ) ptr[-1] = '\0';
	if ( nptr > e->e_nname.bv_val ) nptr[-1] = '\0';

	return 0;
}
예제 #6
0
static int idattr_dynacl_unparse_selfattr(idattr_t *id,  char **ace)
{
    if (id == NULL || ace == NULL || *ace == NULL)
        return -1;

    if (!BER_BVISNULL(&id->idattr_selfattr)) {
        *ace = lutil_strcopy( *ace, "SELFATTR:" );
        *ace = lutil_strcopy( *ace, id->idattr_selfattr.bv_val );
        *ace = lutil_strcopy( *ace, ";" );
    }

    return 0;
}
예제 #7
0
static int idattr_dynacl_unparse_applyto(idattr_t *id,  char **ace)
{
    if (id == NULL || ace == NULL || *ace == NULL)
        return -1;

    if (!BER_BVISNULL(&id->idattr_applyto_uuid)) {
        *ace = lutil_strcopy( *ace, "APPLYTO:" );
        *ace = lutil_strcopy( *ace, id->idattr_applyto_uuid.bv_val );
        *ace = lutil_strcopy( *ace, ";" );
    }

    return 0;
}
예제 #8
0
파일: aci.c 프로젝트: Smilefant/ReOpenLDAP
static int
dynacl_aci_unparse( void *priv, struct berval *bv )
{
	AttributeDescription	*ad = ( AttributeDescription * )priv;
	char			*ptr;

	assert( ad != NULL );

	bv->bv_val = ch_malloc( STRLENOF(" aci=") + ad->ad_cname.bv_len + 1 );
	ptr = lutil_strcopy( bv->bv_val, " aci=" );
	ptr = lutil_strcopy( ptr, ad->ad_cname.bv_val );
	bv->bv_len = ptr - bv->bv_val;

	return 0;
}
예제 #9
0
파일: ndbio.cpp 프로젝트: cptaffe/openldap
extern "C" int
ndb_aset_create( struct ndb_info *ni, NdbOcInfo *oci )
{
	char buf[4096], *ptr;
	NdbAttrInfo *ai;
	int i;

	ptr = buf + sprintf( buf,
		"CREATE TABLE IF NOT EXISTS `%s` (eid bigint unsigned NOT NULL, vid int unsigned NOT NULL",
		oci->no_table.bv_val );

	for ( i=0; i<oci->no_nattrs; i++ ) {
		if ( oci->no_attrs[i]->na_oi != oci )
			continue;
		ai = oci->no_attrs[i];
		ptr += sprintf( ptr, ", `%s` VARCHAR(%d)", ai->na_attr->sat_cname.bv_val,
			ai->na_len );
		if ( ai->na_flag & NDB_INFO_INDEX ) {
			ptr += sprintf( ptr, ", INDEX (`%s`)", ai->na_attr->sat_cname.bv_val );
		}
	}
	ptr = lutil_strcopy( ptr, ", PRIMARY KEY(eid, vid) ) ENGINE=ndb PARTITION BY KEY(eid)" );
	i = mysql_real_query( &ni->ni_sql, buf, ptr - buf );
	if ( i ) {
		Debug( LDAP_DEBUG_ANY,
			"ndb_aset_create: CREATE TABLE %s failed, %s (%d)\n",
			oci->no_table.bv_val, mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) );
	}
	return i;
}
예제 #10
0
static int idattr_dynacl_unparse_style(idattr_t *id,  char **ace)
{
    if (id == NULL || ace == NULL || *ace == NULL)
        return -1;

    switch ( id->idattr_style ) {
    case ACL_STYLE_BASE:
        *ace = lutil_strcopy( *ace, ".exact=" );
        break;

    case ACL_STYLE_EXPAND:
        *ace = lutil_strcopy( *ace, ".expand=" );
        break;
    default:
        break;
    }

    return 0;
}
예제 #11
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 );
	}
}
예제 #12
0
static int
gssattr_dynacl_unparse(
	void		*priv,
	struct berval	*bv )
{
	gssattr_t	*gssattr = (gssattr_t *)priv;
	char		*ptr;

	bv->bv_len = STRLENOF( " dynacl/gss/.expand=" ) +
		     gssattr->gssattr_name.bv_len +
		     gssattr->gssattr_value.bv_len;
	bv->bv_val = ch_malloc( bv->bv_len + 1 );

	ptr = lutil_strcopy( bv->bv_val, " dynacl/gss/" );
	ptr = lutil_strncopy( ptr, gssattr->gssattr_name.bv_val,
			      gssattr->gssattr_name.bv_len );
	switch ( gssattr->gssattr_style ) {
	case ACL_STYLE_BASE:
		ptr = lutil_strcopy( ptr, ".exact=" );
		break;
	case ACL_STYLE_REGEX:
		ptr = lutil_strcopy( ptr, ".regex=" );
		break;
	case ACL_STYLE_EXPAND:
		ptr = lutil_strcopy( ptr, ".expand=" );
		break;
	default:
		assert( 0 );
		break;
	}

	ptr = lutil_strncopy( ptr, gssattr->gssattr_value.bv_val,
			      gssattr->gssattr_value.bv_len );

	ptr[ 0 ] = '\0';

	bv->bv_len = ptr - bv->bv_val;

	return 0;
}
예제 #13
0
파일: dynlist.c 프로젝트: cptaffe/openldap
static int
dynlist_build_def_filter( dynlist_info_t *dli )
{
	char	*ptr;

	dli->dli_default_filter.bv_len = STRLENOF( "(!(objectClass=" "))" )
		+ dli->dli_oc->soc_cname.bv_len;
	dli->dli_default_filter.bv_val = ch_malloc( dli->dli_default_filter.bv_len + 1 );
	if ( dli->dli_default_filter.bv_val == NULL ) {
		Debug( LDAP_DEBUG_ANY, "dynlist_db_open: malloc failed.\n",
			0, 0, 0 );
		return -1;
	}

	ptr = lutil_strcopy( dli->dli_default_filter.bv_val, "(!(objectClass=" );
	ptr = lutil_strcopy( ptr, dli->dli_oc->soc_cname.bv_val );
	ptr = lutil_strcopy( ptr, "))" );

	assert( ptr == &dli->dli_default_filter.bv_val[dli->dli_default_filter.bv_len] );

	return 0;
}
예제 #14
0
static int idattr_dynacl_unparse_optionsavailable(idattr_t *id,  char **ace)
{
    if (id == NULL || ace == NULL || *ace == NULL)
        return -1;
    if ((id->idattr_ops != 0) ||
            !BER_BVISNULL(&id->idattr_applyto_uuid) ||
            !BER_BVISNULL(&id->idattr_selfattr)     ||
            !BER_BVISNULL(&id->idattr_boolattr)) {
        *ace = lutil_strcopy( *ace, "/" );
    }

    return 0;
}
예제 #15
0
static char *
rwm_suffix_massage_regexize( const char *s )
{
	char *res, *ptr;
	const char *p, *r;
	int i;

	if ( s[0] == '\0' ) {
		return ch_strdup( "^(.+)$" );
	}

	for ( i = 0, p = s; 
			( r = strchr( p, ',' ) ) != NULL; 
			p = r + 1, i++ )
		;

	res = ch_calloc( sizeof( char ), strlen( s )
			+ STRLENOF( "((.+),)?" )
			+ STRLENOF( "[ ]?" ) * i
			+ STRLENOF( "$" ) + 1 );

	ptr = lutil_strcopy( res, "((.+),)?" );
	for ( i = 0, p = s;
			( r = strchr( p, ',' ) ) != NULL;
			p = r + 1 , i++ ) {
		ptr = lutil_strncopy( ptr, p, r - p + 1 );
		ptr = lutil_strcopy( ptr, "[ ]?" );

		if ( r[ 1 ] == ' ' ) {
			r++;
		}
	}
	ptr = lutil_strcopy( ptr, p );
	ptr[0] = '$';
	ptr[1] = '\0';

	return res;
}
예제 #16
0
/* This function constructs a full DN for a given id. We really should
 * be passing idNodes directly, to save some effort...
 */
int bdb_fix_dn(
	BackendDB *be,
	ID id,
	Entry *e
)
{
	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
	idNode *n, *o;
	int rlen, nrlen;
	char *ptr, *nptr;
	
	ldap_pvt_thread_rdwr_rlock(&bdb->bi_tree_rdwr);
	o = bdb_find_id_node(id, bdb->bi_tree);
	rlen = be->be_suffix[0].bv_len + 1;
	nrlen = be->be_nsuffix[0].bv_len + 1;
	for (n = o; n && n->i_parent; n=n->i_parent) {
		rlen += n->i_rdn->rdn.bv_len + 1;
		nrlen += n->i_rdn->nrdn.bv_len + 1;
	}
	e->e_name.bv_len = rlen - 1;
	e->e_nname.bv_len = nrlen - 1;
	e->e_name.bv_val = ch_malloc(rlen + nrlen);
	e->e_nname.bv_val = e->e_name.bv_val + rlen;
	ptr = e->e_name.bv_val;
	nptr = e->e_nname.bv_val;
	for (n = o; n && n->i_parent; n=n->i_parent) {
		ptr = lutil_strcopy(ptr, n->i_rdn->rdn.bv_val);
		*ptr++ = ',';
		nptr = lutil_strcopy(nptr, n->i_rdn->nrdn.bv_val);
		*nptr++ = ',';
	}
	ldap_pvt_thread_rdwr_runlock(&bdb->bi_tree_rdwr);

	strcpy(ptr, be->be_suffix[0].bv_val);
	strcpy(nptr, be->be_nsuffix[0].bv_val);

	return 0;
}
예제 #17
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 );
}
예제 #18
0
파일: dynlist.c 프로젝트: cptaffe/openldap
static int
dynlist_make_filter( Operation *op, Entry *e, const char *url, struct berval *oldf, struct berval *newf )
{
	slap_overinst	*on = (slap_overinst *)op->o_bd->bd_info;
	dynlist_info_t	*dli = (dynlist_info_t *)on->on_bi.bi_private;

	char		*ptr;
	int		needBrackets = 0;

	assert( oldf != NULL );
	assert( newf != NULL );
	assert( !BER_BVISNULL( oldf ) );
	assert( !BER_BVISEMPTY( oldf ) );

	if ( oldf->bv_val[0] != '(' ) {
		Debug( LDAP_DEBUG_ANY, "%s: dynlist, DN=\"%s\": missing brackets in URI=\"%s\" filter\n",
			op->o_log_prefix, e->e_name.bv_val, url );
		needBrackets = 2;
	}

	newf->bv_len = STRLENOF( "(&(!(objectClass=" "))" ")" )
		+ dli->dli_oc->soc_cname.bv_len + oldf->bv_len + needBrackets;
	newf->bv_val = op->o_tmpalloc( newf->bv_len + 1, op->o_tmpmemctx );
	if ( newf->bv_val == NULL ) {
		return -1;
	}
	ptr = lutil_strcopy( newf->bv_val, "(&(!(objectClass=" );
	ptr = lutil_strcopy( ptr, dli->dli_oc->soc_cname.bv_val );
	ptr = lutil_strcopy( ptr, "))" );
	if ( needBrackets ) *ptr++ = '(';
	ptr = lutil_strcopy( ptr, oldf->bv_val );
	if ( needBrackets ) *ptr++ = ')';
	ptr = lutil_strcopy( ptr, ")" );
	newf->bv_len = ptr - newf->bv_val;

	return 0;
}
예제 #19
0
파일: ndbio.cpp 프로젝트: cptaffe/openldap
static int
ndb_oc_create( struct ndb_info *ni, NdbOcInfo *oci, int create )
{
	char buf[4096], *ptr;
	int i, rc = 0, col;

	if ( create ) {
		ptr = buf + sprintf( buf,
			"CREATE TABLE `%s` (eid bigint unsigned NOT NULL, vid int unsigned NOT NULL",
			oci->no_table.bv_val );
	}

	col = 0;
	if ( oci->no_oc->soc_required ) {
		for ( i=0; oci->no_oc->soc_required[i]; i++ );
		col += i;
	}
	if ( oci->no_oc->soc_allowed ) {
		for ( i=0; oci->no_oc->soc_allowed[i]; i++ );
		col += i;
	}
	/* assume all are present */
	oci->no_attrs = (struct ndb_attrinfo **)ch_malloc( col * sizeof(struct ndb_attrinfo *));

	col = 2;
	ldap_pvt_thread_rdwr_wlock( &ni->ni_ai_rwlock );
	if ( oci->no_oc->soc_required ) {
		rc = ndb_ai_check( ni, oci, oci->no_oc->soc_required, &ptr, &col, create );
	}
	if ( !rc && oci->no_oc->soc_allowed ) {
		rc = ndb_ai_check( ni, oci, oci->no_oc->soc_allowed, &ptr, &col, create );
	}
	ldap_pvt_thread_rdwr_wunlock( &ni->ni_ai_rwlock );

	/* shrink down to just the needed size */
	oci->no_attrs = (struct ndb_attrinfo **)ch_realloc( oci->no_attrs,
		oci->no_nattrs * sizeof(struct ndb_attrinfo *));

	if ( create ) {
		ptr = lutil_strcopy( ptr, ", PRIMARY KEY(eid, vid) ) ENGINE=ndb PARTITION BY KEY(eid)" );
		rc = mysql_real_query( &ni->ni_sql, buf, ptr - buf );
		if ( rc ) {
			Debug( LDAP_DEBUG_ANY,
				"ndb_oc_create: CREATE TABLE %s failed, %s (%d)\n",
				oci->no_table.bv_val, mysql_error(&ni->ni_sql), mysql_errno(&ni->ni_sql) );
		}
	}
	return rc;
}
예제 #20
0
/* 
** Builds a filter for searching for the 
** group entries, according to the objectClass. 
*/
static int
autogroup_build_def_filter( autogroup_def_t *agd, Operation *op )
{
	char	*ptr;

	Debug( LDAP_DEBUG_TRACE, "==> autogroup_build_def_filter\n", 0, 0, 0);

	op->ors_filterstr.bv_len = STRLENOF( "(=)" ) 
			+ slap_schema.si_ad_objectClass->ad_cname.bv_len
			+ agd->agd_oc->soc_cname.bv_len;
	ptr = op->ors_filterstr.bv_val = op->o_tmpalloc( op->ors_filterstr.bv_len + 1, op->o_tmpmemctx );
	*ptr++ = '(';
	ptr = lutil_strcopy( ptr, slap_schema.si_ad_objectClass->ad_cname.bv_val );
	*ptr++ = '=';
	ptr = lutil_strcopy( ptr, agd->agd_oc->soc_cname.bv_val );
	*ptr++ = ')';
	*ptr = '\0';

	op->ors_filter = str2filter_x( op, op->ors_filterstr.bv_val );

	assert( op->ors_filterstr.bv_len == ptr - op->ors_filterstr.bv_val );

	return 0;
}
예제 #21
0
파일: index.c 프로젝트: osstech-jp/openldap
/* caller must provide buffer space, after calling index2bvlen */
void slap_index2bv( slap_mask_t idx, struct berval *bv )
{
	int i;
	char *ptr;

	if ( !bv->bv_len ) return;

	ptr = bv->bv_val;
	for ( i=0; !BER_BVISNULL( &idxstr[i].word ); i++ ) {
		if ( !idxstr[i].mask ) continue;
		if ( IS_SLAP_INDEX( idx, idxstr[i].mask )) {
			if ( (idxstr[i].mask & SLAP_INDEX_SUBSTR) &&
				((idx & SLAP_INDEX_SUBSTR_DEFAULT) != idxstr[i].mask))
				continue;
			if ( ptr != bv->bv_val ) *ptr++ = ',';
			ptr = lutil_strcopy( ptr, idxstr[i].word.bv_val );
		}
	}
}
예제 #22
0
void
build_new_dn( struct berval * new_dn,
	struct berval * parent_dn,
	struct berval * newrdn )
{
	char *ptr;

	if ( parent_dn == NULL ) {
		ber_dupbv( new_dn, newrdn );
		return;
	}

	new_dn->bv_len = parent_dn->bv_len + newrdn->bv_len + 1;
	new_dn->bv_val = (char *) ch_malloc( new_dn->bv_len + 1 );

	ptr = lutil_strcopy( new_dn->bv_val, newrdn->bv_val );
	*ptr++ = ',';
	strcpy( ptr, parent_dn->bv_val );
}
예제 #23
0
static int idattr_dynacl_unparse(
    void		*priv,
    struct berval	*bv )
{
    idattr_t		*id = (idattr_t *)priv;
    char		*ptr = NULL, *start = NULL;
    size_t len = 0;
    bv->bv_len = MAX_ACE_LEN;
    bv->bv_val = ch_calloc( 1, bv->bv_len + 1 );

    start = ptr = lutil_strcopy( bv->bv_val, " dynacl/idattr" );

    if (idattr_dynacl_unparse_optionsavailable(id, &ptr) != 0)
        goto exit_on_error;

    if (idattr_dynacl_unparse_operation(id, &ptr) != 0)
        goto exit_on_error;
    if (idattr_dynacl_unparse_applyto(id, &ptr) != 0)
        goto exit_on_error;
    if (idattr_dynacl_unparse_selfattr(id, &ptr) != 0)
        goto exit_on_error;
    if (idattr_dynacl_unparse_boolattr(id, &ptr) != 0)
        goto exit_on_error;

    // remove trailing option terminator
    len = strlen(start);
    if (len && start[len - 1] == ';') {
        start[len - 1] = '\0';
        ptr = start + len - 1;
    }

    if (idattr_dynacl_unparse_style(id, &ptr) != 0)
        goto exit_on_error;

    ptr = lutil_strncopy( ptr, id->idattr_pat.bv_val, id->idattr_pat.bv_len );
    ptr[ 0 ] = '\0';

    bv->bv_len = ptr - bv->bv_val;

exit_on_error:
    return 0;
}
예제 #24
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;
}
예제 #25
0
static int
ndb_cf_gen( ConfigArgs *c )
{
	struct ndb_info *ni = (struct ndb_info *)c->be->be_private;
	int i, rc;
	NdbAttrInfo *ai;
	NdbOcInfo *oci;
	ListNode *ln, **l2;
	struct berval bv, *bva;

	if ( c->op == SLAP_CONFIG_EMIT ) {
		char buf[BUFSIZ];
		rc = 0;
		bv.bv_val = buf;
		switch( c->type ) {
		case NDB_ATLEN:
			if ( ni->ni_attrlens ) {
				for ( ln = ni->ni_attrlens; ln; ln=ln->ln_next ) {
					ai = (NdbAttrInfo *)ln->ln_data;
					bv.bv_len = snprintf( buf, sizeof(buf),
						"%s %d", ai->na_name.bv_val,
							ai->na_len );
					value_add_one( &c->rvalue_vals, &bv );
				}
			} else {
				rc = 1;
			}
			break;

		case NDB_ATSET:
			if ( ni->ni_attrsets ) {
				char *ptr, *end = buf+sizeof(buf);
				for ( ln = ni->ni_attrsets; ln; ln=ln->ln_next ) {
					oci = (NdbOcInfo *)ln->ln_data;
					ptr = lutil_strcopy( buf, oci->no_name.bv_val );
					*ptr++ = ' ';
					for ( i=0; i<oci->no_nattrs; i++ ) {
						if ( end - ptr < oci->no_attrs[i]->na_name.bv_len+1 )
							break;
						if ( i )
							*ptr++ = ',';
						ptr = lutil_strcopy(ptr,
							oci->no_attrs[i]->na_name.bv_val );
					}
					bv.bv_len = ptr - buf;
					value_add_one( &c->rvalue_vals, &bv );
				}
			} else {
				rc = 1;
			}
			break;

		case NDB_INDEX:
			if ( ni->ni_attridxs ) {
				for ( ln = ni->ni_attridxs; ln; ln=ln->ln_next ) {
					ai = (NdbAttrInfo *)ln->ln_data;
					value_add_one( &c->rvalue_vals, &ai->na_name );
				}
			} else {
				rc = 1;
			}
			break;

		case NDB_ATBLOB:
			if ( ni->ni_attrblobs ) {
				for ( ln = ni->ni_attrblobs; ln; ln=ln->ln_next ) {
					ai = (NdbAttrInfo *)ln->ln_data;
					value_add_one( &c->rvalue_vals, &ai->na_name );
				}
			} else {
				rc = 1;
			}
			break;

		}
		return rc;
	} else if ( c->op == LDAP_MOD_DELETE ) { /* FIXME */
		rc = 0;
		switch( c->type ) {
		case NDB_INDEX:
			if ( c->valx == -1 ) {

				/* delete all */

			} else {

			}
			break;
		}
		return rc;
	}

	switch( c->type ) {
	case NDB_ATLEN:
		ber_str2bv( c->argv[1], 0, 0, &bv );
		ai = ndb_ai_get( ni, &bv );
		if ( !ai ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s",
				c->log, c->argv[1] );
			Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
			return -1;
		}
		for ( ln = ni->ni_attrlens; ln; ln = ln->ln_next ) {
			if ( ln->ln_data == (void *)ai ) {
				snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr len already set for %s",
					c->log, c->argv[1] );
				Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
				return -1;
			}
		}
		ai->na_len = atoi( c->argv[2] );
		ai->na_flag |= NDB_INFO_ATLEN;
		ln = (ListNode *)ch_malloc( sizeof(ListNode));
		ln->ln_data = ai;
		ln->ln_next = NULL;
		for ( l2 = &ni->ni_attrlens; *l2; l2 = &(*l2)->ln_next );
		*l2 = ln;
		break;
		
	case NDB_INDEX:
		ber_str2bv( c->argv[1], 0, 0, &bv );
		ai = ndb_ai_get( ni, &bv );
		if ( !ai ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s",
				c->log, c->argv[1] );
			Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
			return -1;
		}
		for ( ln = ni->ni_attridxs; ln; ln = ln->ln_next ) {
			if ( ln->ln_data == (void *)ai ) {
				snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr index already set for %s",
					c->log, c->argv[1] );
				Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
				return -1;
			}
		}
		ai->na_flag |= NDB_INFO_INDEX;
		ln = (ListNode *)ch_malloc( sizeof(ListNode));
		ln->ln_data = ai;
		ln->ln_next = NULL;
		for ( l2 = &ni->ni_attridxs; *l2; l2 = &(*l2)->ln_next );
		*l2 = ln;
		break;

	case NDB_ATSET:
		ber_str2bv( c->argv[1], 0, 0, &bv );
		bva = ndb_str2bvarray( c->argv[2], strlen( c->argv[2] ), ',', NULL );
		rc = ndb_aset_get( ni, &bv, bva, &oci );
		ber_bvarray_free( bva );
		if ( rc ) {
			if ( rc == LDAP_ALREADY_EXISTS ) {
				snprintf( c->cr_msg, sizeof( c->cr_msg ),
					"%s: attrset %s already defined",
					c->log, c->argv[1] );
			} else {
				snprintf( c->cr_msg, sizeof( c->cr_msg ),
					"%s: invalid attrset %s (%d)",
					c->log, c->argv[1], rc );
			}
			Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
			return -1;
		}
		ln = (ListNode *)ch_malloc( sizeof(ListNode));
		ln->ln_data = oci;
		ln->ln_next = NULL;
		for ( l2 = &ni->ni_attrsets; *l2; l2 = &(*l2)->ln_next );
		*l2 = ln;
		break;

	case NDB_ATBLOB:
		ber_str2bv( c->argv[1], 0, 0, &bv );
		ai = ndb_ai_get( ni, &bv );
		if ( !ai ) {
			snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: invalid attr %s",
				c->log, c->argv[1] );
			Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
			return -1;
		}
		for ( ln = ni->ni_attrblobs; ln; ln = ln->ln_next ) {
			if ( ln->ln_data == (void *)ai ) {
				snprintf( c->cr_msg, sizeof( c->cr_msg ), "%s: attr blob already set for %s",
					c->log, c->argv[1] );
				Debug( LDAP_DEBUG_ANY, "%s\n", c->cr_msg, 0, 0 );
				return -1;
			}
		}
		ai->na_flag |= NDB_INFO_ATBLOB;
		ln = (ListNode *)ch_malloc( sizeof(ListNode));
		ln->ln_data = ai;
		ln->ln_next = NULL;
		for ( l2 = &ni->ni_attrblobs; *l2; l2 = &(*l2)->ln_next );
		*l2 = ln;
		break;

	}
	return 0;
}
예제 #26
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;
}
예제 #27
0
파일: modify.c 프로젝트: fcelda/openldap
int
do_modify(
    Operation	*op,
    SlapReply	*rs )
{
	struct berval dn = BER_BVNULL;
	char		textbuf[ SLAP_TEXT_BUFLEN ];
	size_t		textlen = sizeof( textbuf );
#ifdef LDAP_DEBUG
	Modifications	*tmp;
#endif

	Debug( LDAP_DEBUG_TRACE, "%s do_modify\n",
		op->o_log_prefix, 0, 0 );
	/*
	 * Parse the modify request.  It looks like this:
	 *
	 *	ModifyRequest := [APPLICATION 6] SEQUENCE {
	 *		name	DistinguishedName,
	 *		mods	SEQUENCE OF SEQUENCE {
	 *			operation	ENUMERATED {
	 *				add	(0),
	 *				delete	(1),
	 *				replace	(2)
	 *			},
	 *			modification	SEQUENCE {
	 *				type	AttributeType,
	 *				values	SET OF AttributeValue
	 *			}
	 *		}
	 *	}
	 */

	if ( ber_scanf( op->o_ber, "{m" /*}*/, &dn ) == LBER_ERROR ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modify: ber_scanf failed\n",
			op->o_log_prefix, 0, 0 );
		send_ldap_discon( op, rs, LDAP_PROTOCOL_ERROR, "decoding error" );
		return SLAPD_DISCONNECT;
	}

	Debug( LDAP_DEBUG_ARGS, "%s do_modify: dn (%s)\n",
		op->o_log_prefix, dn.bv_val, 0 );

	rs->sr_err = slap_parse_modlist( op, rs, op->o_ber, &op->oq_modify );
	if ( rs->sr_err != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modify: slap_parse_modlist failed err=%d msg=%s\n",
			op->o_log_prefix, rs->sr_err, rs->sr_text );
		send_ldap_result( op, rs );
		goto cleanup;
	}

	if( get_ctrls( op, rs, 1 ) != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modify: get_ctrls failed\n",
			op->o_log_prefix, 0, 0 );
		/* get_ctrls has sent results.	Now clean up. */
		goto cleanup;
	}

	rs->sr_err = dnPrettyNormal( NULL, &dn, &op->o_req_dn, &op->o_req_ndn,
		op->o_tmpmemctx );
	if( rs->sr_err != LDAP_SUCCESS ) {
		Debug( LDAP_DEBUG_ANY, "%s do_modify: invalid dn (%s)\n",
			op->o_log_prefix, dn.bv_val, 0 );
		send_ldap_error( op, rs, LDAP_INVALID_DN_SYNTAX, "invalid DN" );
		goto cleanup;
	}

	op->orm_no_opattrs = 0;

#ifdef LDAP_DEBUG
	Debug( LDAP_DEBUG_ARGS, "%s modifications:\n",
			op->o_log_prefix, 0, 0 );

	for ( tmp = op->orm_modlist; tmp != NULL; tmp = tmp->sml_next ) {
		Debug( LDAP_DEBUG_ARGS, "\t%s: %s\n",
			tmp->sml_op == LDAP_MOD_ADD ? "add" :
				(tmp->sml_op == LDAP_MOD_INCREMENT ? "increment" :
				(tmp->sml_op == LDAP_MOD_DELETE ? "delete" :
					"replace")), tmp->sml_type.bv_val, 0 );

		if ( tmp->sml_values == NULL ) {
			Debug( LDAP_DEBUG_ARGS, "%s\n",
			   "\t\tno values", NULL, NULL );
		} else if ( BER_BVISNULL( &tmp->sml_values[ 0 ] ) ) {
			Debug( LDAP_DEBUG_ARGS, "%s\n",
			   "\t\tzero values", NULL, NULL );
		} else if ( BER_BVISNULL( &tmp->sml_values[ 1 ] ) ) {
			Debug( LDAP_DEBUG_ARGS, "%s, length %ld\n",
			   "\t\tone value", (long) tmp->sml_values[0].bv_len, NULL );
		} else {
			Debug( LDAP_DEBUG_ARGS, "%s\n",
			   "\t\tmultiple values", NULL, NULL );
		}
	}

	if ( StatslogTest( LDAP_DEBUG_STATS ) ) {
		char abuf[BUFSIZ/2], *ptr = abuf;
		int len = 0;

		Statslog( LDAP_DEBUG_STATS, "%s MOD dn=\"%s\"\n",
			op->o_log_prefix, op->o_req_dn.bv_val, 0, 0, 0 );

		for ( tmp = op->orm_modlist; tmp != NULL; tmp = tmp->sml_next ) {
			if (len + 1 + tmp->sml_type.bv_len > sizeof(abuf)) {
				Statslog( LDAP_DEBUG_STATS, "%s MOD attr=%s\n",
				    op->o_log_prefix, abuf, 0, 0, 0 );

				len = 0;
				ptr = abuf;

				if( 1 + tmp->sml_type.bv_len > sizeof(abuf)) {
					Statslog( LDAP_DEBUG_STATS, "%s MOD attr=%s\n",
						op->o_log_prefix, tmp->sml_type.bv_val, 0, 0, 0 );
					continue;
				}
			}
			if (len) {
				*ptr++ = ' ';
				len++;
			}
			ptr = lutil_strcopy(ptr, tmp->sml_type.bv_val);
			len += tmp->sml_type.bv_len;
		}
		if (len) {
			Statslog( LDAP_DEBUG_STATS, "%s MOD attr=%s\n",
	    			op->o_log_prefix, abuf, 0, 0, 0 );
		}
	}
#endif	/* LDAP_DEBUG */

	rs->sr_err = slap_mods_check( op, op->orm_modlist,
		&rs->sr_text, textbuf, textlen, NULL );

	if ( rs->sr_err != LDAP_SUCCESS ) {
		send_ldap_result( op, rs );
		goto cleanup;
	}

	op->o_bd = frontendDB;
	rs->sr_err = frontendDB->be_modify( op, rs );

#ifdef LDAP_X_TXN
	if( rs->sr_err == LDAP_X_TXN_SPECIFY_OKAY ) {
		/* skip cleanup */
		return rs->sr_err;
	}
#endif

cleanup:
	op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
	op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
	if ( op->orm_modlist != NULL ) slap_mods_free( op->orm_modlist, 1 );

	return rs->sr_err;
}
예제 #28
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;
}
예제 #29
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;
}
예제 #30
0
/* return 0 IFF op_dn is a value in group_at (member) attribute
 * of entry with gr_dn AND that entry has an objectClass
 * value of group_oc (groupOfNames)
 */
int
ldap_back_group(
	Backend		*be,
	Connection 	*conn,
	Operation 	*op,
	Entry		*target,
	struct berval	*gr_ndn,
	struct berval	*op_ndn,
	ObjectClass	*group_oc,
	AttributeDescription* group_at
)
{
	struct ldapinfo *li = (struct ldapinfo *) be->be_private;    
	int rc = 1;
	Attribute   *attr;

	LDAPMessage	*result;
	char *gattr[2];
	char *filter = NULL, *ptr;
	LDAP *ld;
	struct berval mop_ndn = { 0, NULL }, mgr_ndn = { 0, NULL };

	AttributeDescription *ad_objectClass = slap_schema.si_ad_objectClass;
	struct berval group_oc_name = {0, NULL};
	struct berval group_at_name = group_at->ad_cname;

	if( group_oc->soc_names && group_oc->soc_names[0] ) {
		group_oc_name.bv_val = group_oc->soc_names[0];
	} else {
		group_oc_name.bv_val = group_oc->soc_oid;
	}
	if (group_oc_name.bv_val)
		group_oc_name.bv_len = strlen(group_oc_name.bv_val);

	if (target != NULL && dn_match( &target->e_nname, gr_ndn ) ) {
		/* we already have a copy of the entry */
		/* attribute and objectclass mapping has already been done */

		/*
		 * first we need to check if the objectClass attribute
		 * has been retieved; otherwise we need to repeat the search
		 */
		attr = attr_find( target->e_attrs, ad_objectClass );
		if ( attr != NULL ) {

			/*
			 * Now we can check for the group objectClass value
			 */
			if( !is_entry_objectclass( target, group_oc, 0 ) ) {
				return(1);
			}

			/*
			 * This part has been reworked: the group attr compare
			 * fails only if the attribute is PRESENT but the value
			 * is NOT PRESENT; if the attribute is NOT PRESENT, the
			 * search must be repeated as well.
			 * This may happen if a search for an entry has already
			 * been performed (target is not null) but the group
			 * attribute has not been required
			 */
			if ((attr = attr_find(target->e_attrs, group_at)) != NULL) {
				if( value_find_ex( group_at, SLAP_MR_VALUE_NORMALIZED_MATCH,
					attr->a_vals, op_ndn ) != LDAP_SUCCESS )
					return(1);
				return(0);
			} /* else: repeat the search */
		} /* else: repeat the search */
	} /* else: do the search */

	/*
	 * Rewrite the op ndn if needed
	 */
#ifdef ENABLE_REWRITE
	switch ( rewrite_session( li->rwinfo, "bindDn",
				op_ndn->bv_val, conn, &mop_ndn.bv_val ) ) {
	case REWRITE_REGEXEC_OK:
		if ( mop_ndn.bv_val == NULL ) {
			mop_ndn = *op_ndn;
		}
#ifdef NEW_LOGGING
		LDAP_LOG( BACK_LDAP, DETAIL1, 
			"[rw] bindDn (op ndn in group): \"%s\" -> \"%s\"\n", 
			op_ndn->bv_val, mop_ndn.bv_val, 0 );
#else /* !NEW_LOGGING */
		Debug( LDAP_DEBUG_ARGS,
			"rw> bindDn (op ndn in group): \"%s\" -> \"%s\"\n%s",
			op_ndn->bv_val, mop_ndn.bv_val, "" );
#endif /* !NEW_LOGGING */
		break;
	
	case REWRITE_REGEXEC_UNWILLING:
	
	case REWRITE_REGEXEC_ERR:
		goto cleanup;
	}

	/*
	 * Rewrite the gr ndn if needed
	 */
        switch ( rewrite_session( li->rwinfo, "searchBase",
				gr_ndn->bv_val, conn, &mgr_ndn.bv_val ) ) {
	case REWRITE_REGEXEC_OK:
		if ( mgr_ndn.bv_val == NULL ) {
			mgr_ndn = *gr_ndn;
		}
#ifdef NEW_LOGGING
		LDAP_LOG( BACK_LDAP, DETAIL1, 
			"[rw] searchBase (gr ndn in group): \"%s\" -> \"%s\"\n%s", 
			gr_ndn->bv_val, mgr_ndn.bv_val, "" );
#else /* !NEW_LOGGING */
		Debug( LDAP_DEBUG_ARGS,
			"rw> searchBase (gr ndn in group):"
			" \"%s\" -> \"%s\"\n%s",
			gr_ndn->bv_val, mgr_ndn.bv_val, "" );
#endif /* !NEW_LOGGING */
		break;
	
	case REWRITE_REGEXEC_UNWILLING:
	
	case REWRITE_REGEXEC_ERR:
		goto cleanup;
	}
#else /* !ENABLE_REWRITE */
	ldap_back_dn_massage( li, op_ndn, &mop_ndn, 1, 1 );
	if ( mop_ndn.bv_val == NULL ) {
		goto cleanup;
	}
	ldap_back_dn_massage( li, gr_ndn, &mgr_ndn, 1, 1 );
	if ( mgr_ndn.bv_val == NULL ) {
		goto cleanup;
	}
#endif /* !ENABLE_REWRITE */

	ldap_back_map(&li->oc_map, &group_oc_name, &group_oc_name,
			BACKLDAP_MAP);
	if (group_oc_name.bv_val == NULL || group_oc_name.bv_val[0] == '\0')
		goto cleanup;
	ldap_back_map(&li->at_map, &group_at_name, &group_at_name,
			BACKLDAP_MAP);
	if (group_at_name.bv_val == NULL || group_at_name.bv_val[0] == '\0')
		goto cleanup;

	filter = ch_malloc(sizeof("(&(objectclass=)(=))")
						+ group_oc_name.bv_len
						+ group_at_name.bv_len
						+ mop_ndn.bv_len + 1);
	if (filter == NULL)
		goto cleanup;

	if (ldap_initialize(&ld, li->url) != LDAP_SUCCESS) {
		goto cleanup;
	}

	if (ldap_bind_s(ld, li->binddn, li->bindpw, LDAP_AUTH_SIMPLE)
			!= LDAP_SUCCESS) {
		goto cleanup;
	}

	ptr = lutil_strcopy(filter, "(&(objectclass=");
	ptr = lutil_strcopy(ptr, group_oc_name.bv_val);
	ptr = lutil_strcopy(ptr, ")(");
	ptr = lutil_strcopy(ptr, group_at_name.bv_val);
	ptr = lutil_strcopy(ptr, "=");
	ptr = lutil_strcopy(ptr, mop_ndn.bv_val);
	strcpy(ptr, "))");

	gattr[0] = "objectclass";
	gattr[1] = NULL;
	if (ldap_search_ext_s(ld, mgr_ndn.bv_val, LDAP_SCOPE_BASE, filter,
		gattr, 0, NULL, NULL, LDAP_NO_LIMIT,
		LDAP_NO_LIMIT, &result) == LDAP_SUCCESS) {
		if (ldap_first_entry(ld, result) != NULL)
			rc = 0;
		ldap_msgfree(result);
	}

cleanup:;
	if ( ld != NULL ) {
		ldap_unbind(ld);
	}
	ch_free(filter);
	if ( mop_ndn.bv_val != op_ndn->bv_val ) {
		free( mop_ndn.bv_val );
	}
	if ( mgr_ndn.bv_val != gr_ndn->bv_val ) {
		free( mgr_ndn.bv_val );
	}
	return(rc);
}