Пример #1
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);
}
Пример #2
0
/*
 * massages "in" into "dn"
 * 
 * "dn" may contain the value of "in" if no massage occurred
 */
int
rwm_dn_massage(
	dncookie *dc,
	struct berval *in,
	struct berval *dn
)
{
	int		rc = 0;
	struct berval	mdn;
	static char	*dmy = "";
	char *in_val;

	assert( dc != NULL );
	assert( in != NULL );
	assert( dn != NULL );

	/* protect from NULL berval */
	in_val = in->bv_val ? in->bv_val : dmy;

	rc = rewrite_session( dc->rwmap->rwm_rw, dc->ctx,
			in_val, dc->conn, &mdn.bv_val );
	switch ( rc ) {
	case REWRITE_REGEXEC_OK:
		if ( !BER_BVISNULL( &mdn ) && mdn.bv_val != in_val ) {
			mdn.bv_len = strlen( mdn.bv_val );
			*dn = mdn;
		} else {
			dn->bv_len = in->bv_len;
			dn->bv_val = in_val;
		}
		rc = LDAP_SUCCESS;

		Debug( LDAP_DEBUG_ARGS,
			"[rw] %s: \"%s\" -> \"%s\"\n",
			dc->ctx, in_val, dn->bv_val );
		break;
 		
 	case REWRITE_REGEXEC_UNWILLING:
		if ( dc->rs ) {
			dc->rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
			dc->rs->sr_text = "Operation not allowed";
		}
		rc = LDAP_UNWILLING_TO_PERFORM;
		break;
	       	
	case REWRITE_REGEXEC_ERR:
		if ( dc->rs ) {
			dc->rs->sr_err = LDAP_OTHER;
			dc->rs->sr_text = "Rewrite error";
		}
		rc = LDAP_OTHER;
		break;
	}

	if ( mdn.bv_val == dmy ) {
		BER_BVZERO( &mdn );
	}

	if ( dn->bv_val == dmy ) {
		BER_BVZERO( dn );
	}

	return rc;
}
Пример #3
0
/*
 * init_one_conn
 * 
 * Initializes one connection
 */
static int
init_one_conn(
		Connection *conn, 
		Operation *op, 
		struct metatarget *lt, 
		struct metasingleconn *lsc
		)
{
	int err, vers;

	/*
	 * Already init'ed
	 */
	if ( lsc->ld != NULL ) {
		return LDAP_SUCCESS;
	}
       
	/*
	 * Attempts to initialize the connection to the target ds
	 */
	err = ldap_initialize( &lsc->ld, lt->uri );
	if ( err != LDAP_SUCCESS ) {
		return ldap_back_map_result( err );
	}

	/*
	 * Set LDAP version. This will always succeed: If the client
	 * bound with a particular version, then so can we.
	 */
	vers = conn->c_protocol;
	ldap_set_option( lsc->ld, LDAP_OPT_PROTOCOL_VERSION, &vers );

	/*
	 * Sets a cookie for the rewrite session
	 */
	( void )rewrite_session_init( lt->rwinfo, conn );

	/*
	 * If the connection dn is not null, an attempt to rewrite it is made
	 */
	if ( conn->c_dn.bv_len != 0 ) {
		
		/*
		 * Rewrite the bind dn if needed
		 */
		lsc->bound_dn.bv_val = NULL;
		switch ( rewrite_session( lt->rwinfo, "bindDn",
					conn->c_dn.bv_val, conn, 
					&lsc->bound_dn.bv_val ) ) {
		case REWRITE_REGEXEC_OK:
			if ( lsc->bound_dn.bv_val == NULL ) {
				ber_dupbv( &lsc->bound_dn, &conn->c_dn );
			}
#ifdef NEW_LOGGING
			LDAP_LOG( BACK_META, DETAIL1,
				"[rw] bindDn: \"%s\" -> \"%s\"\n",
				conn->c_dn.bv_val, lsc->bound_dn.bv_val, 0 );
#else /* !NEW_LOGGING */
			Debug( LDAP_DEBUG_ARGS,
				       	"rw> bindDn: \"%s\" -> \"%s\"\n",
					conn->c_dn.bv_val, lsc->bound_dn.bv_val, 0 );
#endif /* !NEW_LOGGING */
			break;
			
		case REWRITE_REGEXEC_UNWILLING:
			send_ldap_result( conn, op,
					LDAP_UNWILLING_TO_PERFORM,
					NULL, "Operation not allowed",
					NULL, NULL );
			return LDAP_UNWILLING_TO_PERFORM;
			
		case REWRITE_REGEXEC_ERR:
			send_ldap_result( conn, op,
					LDAP_OTHER,
					NULL, "Rewrite error",
					NULL, NULL );
			return LDAP_OTHER;
		}

		assert( lsc->bound_dn.bv_val );

	} else {
		ber_str2bv( "", 0, 1, &lsc->bound_dn );
	}

	lsc->bound = META_UNBOUND;

	/*
	 * The candidate is activated
	 */
	lsc->candidate = META_CANDIDATE;
	return LDAP_SUCCESS;
}
Пример #4
0
int
rwm_filter_map_rewrite(
	Operation		*op,
	dncookie		*dc,
	Filter			*f,
	struct berval		*fstr )
{
	int		rc;
	dncookie 	fdc;
	struct berval	ftmp;

	rc = rwm_int_filter_map_rewrite( op, dc, f, fstr );

	if ( rc != 0 ) {
		return rc;
	}

	fdc = *dc;
	ftmp = *fstr;

	fdc.ctx = "searchFilter";

	switch ( rewrite_session( fdc.rwmap->rwm_rw, fdc.ctx, 
				( !BER_BVISEMPTY( &ftmp ) ? ftmp.bv_val : "" ), 
				fdc.conn, &fstr->bv_val ) )
	{
	case REWRITE_REGEXEC_OK:
		if ( !BER_BVISNULL( fstr ) ) {
			fstr->bv_len = strlen( fstr->bv_val );

		} else {
			*fstr = ftmp;
		}

		Debug( LDAP_DEBUG_ARGS,
			"[rw] %s: \"%s\" -> \"%s\"\n",
			fdc.ctx, ftmp.bv_val, fstr->bv_val );		
		if ( fstr->bv_val != ftmp.bv_val ) {
			ber_bvreplace_x( &ftmp, fstr, op->o_tmpmemctx );
			ch_free( fstr->bv_val );
			*fstr = ftmp;
		}
		rc = LDAP_SUCCESS;
		break;
 		
 	case REWRITE_REGEXEC_UNWILLING:
		if ( fdc.rs ) {
			fdc.rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
			fdc.rs->sr_text = "Operation not allowed";
		}
		op->o_tmpfree( ftmp.bv_val, op->o_tmpmemctx );
		rc = LDAP_UNWILLING_TO_PERFORM;
		break;
	       	
	case REWRITE_REGEXEC_ERR:
		if ( fdc.rs ) {
			fdc.rs->sr_err = LDAP_OTHER;
			fdc.rs->sr_text = "Rewrite error";
		}
		op->o_tmpfree( ftmp.bv_val, op->o_tmpmemctx );
		rc = LDAP_OTHER;
		break;
	}

	return rc;
}
Пример #5
0
int
ldap_back_filter_map_rewrite(
		dncookie		*dc,
		Filter			*f,
		struct berval	*fstr,
		int				remap,
		void			*memctx )
{
	int		rc;
	dncookie	fdc;
	struct berval	ftmp;
	static char	*dmy = "";

	rc = ldap_back_int_filter_map_rewrite( dc, f, fstr, remap, memctx );

#ifdef ENABLE_REWRITE
	if ( rc != LDAP_SUCCESS ) {
		return rc;
	}

	fdc = *dc;
	ftmp = *fstr;

	fdc.ctx = "searchFilter";
	
	switch ( rewrite_session( fdc.target->mt_rwmap.rwm_rw, fdc.ctx,
				( !BER_BVISEMPTY( &ftmp ) ? ftmp.bv_val : dmy ),
				fdc.conn, &fstr->bv_val ) )
	{
	case REWRITE_REGEXEC_OK:
		if ( !BER_BVISNULL( fstr ) ) {
			fstr->bv_len = strlen( fstr->bv_val );

		} else {
			*fstr = ftmp;
		}
		Debug( LDAP_DEBUG_ARGS,
			"[rw] %s: \"%s\" -> \"%s\"\n",
			fdc.ctx, BER_BVISNULL( &ftmp ) ? "" : ftmp.bv_val,
			BER_BVISNULL( fstr ) ? "" : fstr->bv_val );		
		rc = LDAP_SUCCESS;
		break;
 		
 	case REWRITE_REGEXEC_UNWILLING:
		if ( fdc.rs ) {
			fdc.rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
			fdc.rs->sr_text = "Operation not allowed";
		}
		rc = LDAP_UNWILLING_TO_PERFORM;
		break;
	       	
	case REWRITE_REGEXEC_ERR:
		if ( fdc.rs ) {
			fdc.rs->sr_err = LDAP_OTHER;
			fdc.rs->sr_text = "Rewrite error";
		}
		rc = LDAP_OTHER;
		break;
	}

	if ( fstr->bv_val == dmy ) {
		BER_BVZERO( fstr );

	} else if ( fstr->bv_val != ftmp.bv_val ) {
		/* NOTE: need to realloc mapped filter on slab
		 * and free the original one, until librewrite
		 * becomes slab-aware
		 */
		ber_dupbv_x( &ftmp, fstr, memctx );
		ch_free( fstr->bv_val );
		*fstr = ftmp;
	}
#endif /* ENABLE_REWRITE */

	return rc;
}
Пример #6
0
int
meta_back_compare(
		Backend			*be,
		Connection		*conn,
		Operation		*op,
		struct berval		*dn,
		struct berval		*ndn,
		AttributeAssertion 	*ava
)
{
	struct metainfo	*li = ( struct metainfo * )be->be_private;
	struct metaconn *lc;
	struct metasingleconn *lsc;
	char *match = NULL, *err = NULL, *mmatch = NULL;
	int candidates = 0, last = 0, i, count, rc;
       	int cres = LDAP_SUCCESS, rres = LDAP_SUCCESS;
	int *msgid;

	lc = meta_back_getconn( li, conn, op, META_OP_ALLOW_MULTIPLE,
			ndn, NULL );
	if ( !lc || !meta_back_dobind( lc, op ) ) {
 		send_ldap_result( conn, op, LDAP_OTHER,
 				NULL, NULL, NULL, NULL );
		return -1;
	}

	msgid = ch_calloc( sizeof( int ), li->ntargets );
	if ( msgid == NULL ) {
		return -1;
	}

	/*
	 * start an asynchronous compare for each candidate target
	 */
	for ( i = 0, lsc = lc->conns; !META_LAST(lsc); ++i, ++lsc ) {
		char *mdn = NULL;
		struct berval mapped_attr = ava->aa_desc->ad_cname;
		struct berval mapped_value = ava->aa_value;

		if ( lsc->candidate != META_CANDIDATE ) {
			msgid[ i ] = -1;
			continue;
		}

		/*
		 * Rewrite the compare dn, if needed
		 */
		switch ( rewrite_session( li->targets[ i ]->rwinfo,
					"compareDn", 
					dn->bv_val, conn, &mdn ) ) {
		case REWRITE_REGEXEC_OK:
			if ( mdn == NULL ) {
				mdn = ( char * )dn->bv_val;
			}
#ifdef NEW_LOGGING
			LDAP_LOG( BACK_META, DETAIL1,
				"[rw] compareDn: \"%s\" -> \"%s\"\n", dn->bv_val, mdn, 0 );
#else /* !NEW_LOGGING */
			Debug( LDAP_DEBUG_ARGS,
				     	"rw> compareDn: \"%s\" -> \"%s\"\n%s",
					dn->bv_val, mdn, "" );
#endif /* !NEW_LOGGING */
			break;
		
		case REWRITE_REGEXEC_UNWILLING:
			send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
					NULL, "Operation not allowed",
					NULL, NULL );
			return -1;
			
		case REWRITE_REGEXEC_ERR:
			send_ldap_result( conn, op,  LDAP_OTHER,
					NULL, "Rewrite error",
					NULL, NULL );
			return -1;
		}

		/*
		 * if attr is objectClass, try to remap the value
		 */
		if ( ava->aa_desc == slap_schema.si_ad_objectClass ) {
			ldap_back_map( &li->targets[ i ]->oc_map,
					&ava->aa_value, &mapped_value,
					BACKLDAP_MAP );

			if ( mapped_value.bv_val == NULL || mapped_value.bv_val[0] == '\0' ) {
				continue;
			}
		/*
		 * else try to remap the attribute
		 */
		} else {
			ldap_back_map( &li->targets[ i ]->at_map,
				&ava->aa_desc->ad_cname, &mapped_attr,
				BACKLDAP_MAP );
			if ( mapped_attr.bv_val == NULL || mapped_attr.bv_val[0] == '\0' ) {
				continue;
			}
		}
		
		/*
		 * the compare op is spawned across the targets and the first
		 * that returns determines the result; a constraint on unicity
		 * of the result ought to be enforced
		 */
		msgid[ i ] = ldap_compare( lc->conns[ i ].ld, mdn,
				mapped_attr.bv_val, mapped_value.bv_val );
		if ( mdn != dn->bv_val ) {
			free( mdn );
		}
		if ( mapped_attr.bv_val != ava->aa_desc->ad_cname.bv_val ) {
			free( mapped_attr.bv_val );
		}
		if ( mapped_value.bv_val != ava->aa_value.bv_val ) {
			free( mapped_value.bv_val );
		}

		if ( msgid[ i ] == -1 ) {
			continue;
		}

		++candidates;
	}

	/*
	 * wait for replies
	 */
	for ( rc = 0, count = 0; candidates > 0; ) {

		/*
		 * FIXME: should we check for abandon?
		 */
		for ( i = 0, lsc = lc->conns; !META_LAST(lsc); lsc++, i++ ) {
			int lrc;
			LDAPMessage *res = NULL;

			if ( msgid[ i ] == -1 ) {
				continue;
			}

			lrc = ldap_result( lsc->ld, msgid[ i ],
					0, NULL, &res );

			if ( lrc == 0 ) {
				/*
				 * FIXME: should we yield?
				 */
				if ( res ) {
					ldap_msgfree( res );
				}
				continue;
			} else if ( lrc == LDAP_RES_COMPARE ) {
				if ( count > 0 ) {
					rres = LDAP_OTHER;
					rc = -1;
					goto finish;
				}
				
				cres = ldap_result2error( lsc->ld, res, 1 );
				switch ( cres ) {
				case LDAP_COMPARE_TRUE:
				case LDAP_COMPARE_FALSE:

					/*
					 * true or flase, got it;
					 * sending to cache ...
					 */
					if ( li->cache.ttl != META_DNCACHE_DISABLED ) {
						( void )meta_dncache_update_entry( &li->cache, ndn, i );
					}

					count++;
					rc = 0;
					break;

				default:
					rres = ldap_back_map_result( cres );

					if ( err != NULL ) {
						free( err );
					}
					ldap_get_option( lsc->ld,
						LDAP_OPT_ERROR_STRING, &err );

					if ( match != NULL ) {
						free( match );
					}
					ldap_get_option( lsc->ld,
						LDAP_OPT_MATCHED_DN, &match );
					
					last = i;
					break;
				}
				msgid[ i ] = -1;
				--candidates;

			} else {
				msgid[ i ] = -1;
				--candidates;
				if ( res ) {
					ldap_msgfree( res );
				}
				break;
			}
		}
	}

finish:;

	/*
	 * Rewrite the matched portion of the search base, if required
	 * 
	 * FIXME: only the last one gets caught!
	 */
	if ( count == 1 ) {
		if ( match != NULL ) {
			free( match );
			match = NULL;
		}
		
		/*
		 * the result of the compare is assigned to the res code
		 * that will be returned
		 */
		rres = cres;
		
	} else if ( match != NULL ) {
		
		/*
		 * At least one compare failed with matched portion,
		 * and none was successful
		 */
		switch ( rewrite_session( li->targets[ last ]->rwinfo,
					"matchedDn", match, conn, &mmatch ) ) {
		case REWRITE_REGEXEC_OK:
			if ( mmatch == NULL ) {
				mmatch = ( char * )match;
			}
#ifdef NEW_LOGGING
			LDAP_LOG( BACK_META, DETAIL1,
				"[rw] matchedDn: \"%s\" -> \"%s\"\n", match, mmatch, 0 );
#else /* !NEW_LOGGING */
			Debug( LDAP_DEBUG_ARGS, "rw> matchedDn:"
					" \"%s\" -> \"%s\"\n%s",
					match, mmatch, "" );
#endif /* !NEW_LOGGING */
			break;
			
		
		case REWRITE_REGEXEC_UNWILLING:
			send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
					NULL, "Operation not allowed",
					NULL, NULL );
			rc = -1;
			goto cleanup;
			
		case REWRITE_REGEXEC_ERR:
			send_ldap_result( conn, op, LDAP_OTHER,
					NULL, "Rewrite error",
					NULL, NULL );
			rc = -1;
			goto cleanup;
		}
	}

	send_ldap_result( conn, op, rres, mmatch, err, NULL, NULL );

cleanup:;
	if ( match != NULL ) {
		if ( mmatch != match ) {
			free( mmatch );
		}
		free( match );
	}

	if ( msgid ) {
		free( msgid );
	}
	
	return rc;
}
Пример #7
0
static void
apply( 
		FILE *fin, 
		const char *rewriteContext,
		const char *arg
)
{
	struct rewrite_info *info;
	char *string, *sep, *result = NULL;
	int rc;
	void *cookie = &info;

	info = rewrite_info_init( REWRITE_MODE_ERR );

	if ( rewrite_read( fin, info ) != 0 ) {
		exit( EXIT_FAILURE );
	}

	rewrite_param_set( info, "prog", "rewrite" );

	rewrite_session_init( info, cookie );

	string = (char *)arg;
	for ( sep = strchr( rewriteContext, ',' );
			rewriteContext != NULL;
			rewriteContext = sep,
			sep ? sep = strchr( rewriteContext, ',' ) : NULL )
	{
		char	*errmsg = "";

		if ( sep != NULL ) {
			sep[ 0 ] = '\0';
			sep++;
		}
		/* rc = rewrite( info, rewriteContext, string, &result ); */
		rc = rewrite_session( info, rewriteContext, string,
				cookie, &result );
		
		switch ( rc ) {
		case REWRITE_REGEXEC_OK:
			errmsg = "ok";
			break;

		case REWRITE_REGEXEC_ERR:
			errmsg = "error";
			break;

		case REWRITE_REGEXEC_STOP:
			errmsg = "stop";
			break;

		case REWRITE_REGEXEC_UNWILLING:
			errmsg = "unwilling to perform";
			break;

		default:
			if (rc >= REWRITE_REGEXEC_USER) {
				errmsg = "user-defined";
			} else {
				errmsg = "unknown";
			}
			break;
		}
		
		fprintf( stdout, "%s -> %s [%d:%s]\n", string, 
				( result ? result : "(null)" ),
				rc, errmsg );
		if ( result == NULL ) {
			break;
		}
		if ( string != arg && string != result ) {
			free( string );
		}
		string = result;
	}

	if ( result && result != arg ) {
		free( result );
	}

	rewrite_session_delete( info, cookie );

	rewrite_info_delete( &info );
}
Пример #8
0
int
meta_back_modify(
		Backend	*be,
		Connection	*conn,
		Operation	*op,
		struct berval	*dn,
		struct berval	*ndn,
		Modifications	*modlist
)
{
	struct metainfo	*li = ( struct metainfo * )be->be_private;
	struct metaconn *lc;
	LDAPMod **modv;
	LDAPMod *mods;
	Modifications *ml;
	int candidate = -1, i;
	char *mdn;
	struct berval mapped;

	lc = meta_back_getconn( li, conn, op, META_OP_REQUIRE_SINGLE,
			ndn, &candidate );
	if ( !lc || !meta_back_dobind( lc, op )
			|| !meta_back_is_valid( lc, candidate ) ) {
 		send_ldap_result( conn, op, LDAP_OTHER,
 				NULL, NULL, NULL, NULL );
		return -1;
	}

	/*
	 * Rewrite the modify dn, if needed
	 */
	switch ( rewrite_session( li->targets[ candidate ]->rwinfo,
				"modifyDn", dn->bv_val, conn, &mdn ) ) {
	case REWRITE_REGEXEC_OK:
		if ( mdn == NULL ) {
			mdn = ( char * )dn->bv_val;
		}
#ifdef NEW_LOGGING
		LDAP_LOG( BACK_META, DETAIL1,
			"[rw] modifyDn: \"%s\" -> \"%s\"\n", dn->bv_val, mdn, 0 );
#else /* !NEW_LOGGING */
		Debug( LDAP_DEBUG_ARGS, "rw> modifyDn: \"%s\" -> \"%s\"\n%s",
				dn->bv_val, mdn, "" );
#endif /* !NEW_LOGGING */
		break;
		
	case REWRITE_REGEXEC_UNWILLING:
		send_ldap_result( conn, op, LDAP_UNWILLING_TO_PERFORM,
				NULL, "Operation not allowed", NULL, NULL );
		return -1;

	case REWRITE_REGEXEC_ERR:
		send_ldap_result( conn, op, LDAP_OTHER,
				NULL, "Rewrite error", NULL, NULL );
		return -1;
	}

	for ( i = 0, ml = modlist; ml; i++ ,ml = ml->sml_next )
		;

	mods = ch_malloc( sizeof( LDAPMod )*i );
	if ( mods == NULL ) {
		if ( mdn != dn->bv_val ) {
			free( mdn );
		}
		return -1;
	}
	modv = ( LDAPMod ** )ch_malloc( ( i + 1 )*sizeof( LDAPMod * ) );
	if ( modv == NULL ) {
		free( mods );
		if ( mdn != dn->bv_val ) {
			free( mdn );
		}
		return -1;
	}

	for ( i = 0, ml = modlist; ml; ml = ml->sml_next ) {
		int j;

		if ( ml->sml_desc->ad_type->sat_no_user_mod  ) {
			continue;
		}

		ldap_back_map( &li->targets[ candidate ]->at_map,
				&ml->sml_desc->ad_cname, &mapped,
				BACKLDAP_MAP );
		if ( mapped.bv_val == NULL || mapped.bv_val[0] == '\0' ) {
			continue;
		}

		modv[ i ] = &mods[ i ];
		mods[ i ].mod_op = ml->sml_op | LDAP_MOD_BVALUES;
		mods[ i ].mod_type = mapped.bv_val;

		/*
		 * FIXME: dn-valued attrs should be rewritten
		 * to allow their use in ACLs at the back-ldap
		 * level.
		 */
		if ( strcmp( ml->sml_desc->ad_type->sat_syntax->ssyn_oid,
					SLAPD_DN_SYNTAX ) == 0 ) {
			ldap_dnattr_rewrite(
				li->targets[ candidate ]->rwinfo,
				ml->sml_bvalues, conn );
		}

		if ( ml->sml_bvalues != NULL ){
			for (j = 0; ml->sml_bvalues[ j ].bv_val; j++);
			mods[ i ].mod_bvalues = (struct berval **)ch_malloc((j+1) *
				sizeof(struct berval *));
			for (j = 0; ml->sml_bvalues[ j ].bv_val; j++)
				mods[ i ].mod_bvalues[ j ] = &ml->sml_bvalues[j];
			mods[ i ].mod_bvalues[ j ] = NULL;

		} else {
			mods[ i ].mod_bvalues = NULL;
		}

		i++;
	}
	modv[ i ] = 0;

	ldap_modify_s( lc->conns[ candidate ].ld, mdn, modv );

	if ( mdn != dn->bv_val ) {
		free( mdn );
	}
	for ( i=0; modv[ i ]; i++)
		free( modv[ i ]->mod_bvalues );
	free( mods );
	free( modv );
	return meta_back_op_result( lc, op );
}