[Date Prev][Date Next] [Chronological] [Thread] [Top]

Re: back_meta does not like my LDAP_MATCHING_RULE_IN_CHAIN filter



On 06/05/2014 01:54 PM, Charles Bueche wrote:

On 04.06.14 15:14, Charles Bueche wrote:
On 03.06.14 16:52, Pierangelo Masarati wrote:
On 06/03/2014 04:23 PM, Charles Bueche wrote:
Hi,

I'm running the latest openldap stable 2.4.39 on Ubuntu.
My openldap server is configured as a LDAP proxy to MS-AD using
back-meta. It works nicely, as long as I don't use OID in filters.

Specifically, I need LDAP_MATCHING_RULE_IN_CHAIN
(http://msdn.microsoft.com/en-us/library/aa746475(v=vs.85).aspx) to
search recursive groups in MS-AD.

If I use that special filter directly against AD, I get my group list.
filter='(memberOf:1.2.840.113556.1.4.1941:=cn=ls-msp-app1,OU=App,DC=ad,DC=stuff,DC=ch)'


Or if I use a "normal" filter across my proxy, I get my group list as
well.
filter='(memberOf=cn=gs-msp-report,OU=Customers,DC=ad,DC=stuff,DC=ch)'

BROKEN: If I use the special filter across my LDAP proxy's back-meta, I
get no results and filter="(?=undefined)" in my debug log.
filter='(memberOf:1.2.840.113556.1.4.1941:=cn=ls-msp-app1,OU=App,DC=ad,DC=stuff,DC=ch)'


So my guess is that my filter syntax with OID is not accepted by
back-meta.

When using -d -1, I see this:

...
538dd110 begin get_filter
538dd110 EXTENSIBLE
...
538dd110 end get_filter 0
538dd110     filter: (?=undefined)
...

I have looked at the code of openldap-2.4.39/servers/slapd/filter.c but
I don't really see what's wrong.
Without looking at the code, I think OpenLDAP's slapd doesn't like
filters with unknown OIDs, that's it.  The request doesn't even get to
back-meta.

On a side note, since the filter is supposed to be passed through to
the remote server, slapd should not worry about it; however, AFAIK
there's no way, so far, to disable such check.  The easiest way is to
define a module that registers a dummy matching rule with that OID,
although it won't likely be that straightforward.

p.

Hi Pierangelo and list,

thanks for your answer, I'm very unsure now how to continue. I studied
the code of get_filter() and get_mra() without really understanding at
what time my filter is classified as invalid.

The ideas is to implement a workaround in form of a list of white-listed
OID's (only 4 are needed from
http://msdn.microsoft.com/en-us/library/cc223367.aspx), where should I
put this in the code ?

I do compile my own openldap package anyway, so I can well put some
#ifdef around this, at least to be able to continue my project. I'm now
stopped by this problem and as usual I do have to deliver rsn.

On the other side, what do you mean with "define a module that registers
a dummy matching rule with that OID" ?
Is this a module like back_meta, rwn and friends ? Do you have any
pointer like a dummy module to show where to begin ?

As you see, I'm pretty much at the beginning of the learning curve and I
am very happy to get your help.

Regards,
Charles

ok, it did cost me a lot of brain power, but I do have a workaround. I
mention it here because I'm quite sure someone else will hit the same
problem one day.

1. the recursive search filter passed to the proxy should use a filter
supported by the proxy, eg

filter='(RecursiveMemberOf=cn=ls-msp-app2,OU=App,DC=extra,DC=proxy,DC=stuff,DC=ch)'

2. the proxy gasp it, accept it, and pass it to the rewrite module

3. use a rewrite rule to massage the filter:

rewriteRule
     "RecursiveMemberOf=cn=(.*),dc=extra,dc=proxy,dc=stuff,dc=ch"
     "memberOf:1.2.840.113556.1.4.1941:=cn=%1,dc=ad,dc=stuff,dc=ch"
     ":"

back_meta then pass the rewritten filter to the back-end AD.


To the developers: as mentioned by Pierangelo above, it should be
possible to disable the filter sanity check when it is passed to a LDAP
back-end. If the filter is insane, the back-end will complain soon enough.

This does the trick in your specific case; you should be able to modify it to add more matching rule definitions.

p.

--
Pierangelo Masarati
Associate Professor
Dipartimento di Scienze e Tecnologie Aerospaziali
Politecnico di Milano
/* matching rule passthru */
/* $OpenLDAP$ */
/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
 *
 * Copyright 2014 The OpenLDAP Foundation.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted only as authorized by the OpenLDAP
 * Public License.
 *
 * A copy of this license is available in the file LICENSE in the
 * top-level directory of the distribution or, alternatively, at
 * <http://www.OpenLDAP.org/license.html>.
 */
/* ACKNOWLEDGEMENTS:
 * This work was initially developed by Pierangelo Masarati for inclusion
 * in OpenLDAP Software.
 */

#include "portable.h"

#include "slap.h"
#include "config.h"
#include "lutil.h"
#include "ac/string.h"

static int
okMatch(
	int *matchp,
	slap_mask_t flags,
	Syntax *syntax,
	MatchingRule *mr,
	struct berval *value,
	void *assertedValue )
{
	int match;
	struct berval *asserted = (struct berval *) assertedValue;

	assert( matchp != NULL );
	assert( value != NULL );
	assert( assertedValue != NULL );
	assert( !BER_BVISNULL( value ) );
	assert( !BER_BVISNULL( asserted ) );

	match = 0;

	*matchp = match;
	return LDAP_SUCCESS;
}

static int
failMatch(
	int *matchp,
	slap_mask_t flags,
	Syntax *syntax,
	MatchingRule *mr,
	struct berval *value,
	void *assertedValue )
{
	int match;
	struct berval *asserted = (struct berval *) assertedValue;

	assert( matchp != NULL );
	assert( value != NULL );
	assert( assertedValue != NULL );
	assert( !BER_BVISNULL( value ) );
	assert( !BER_BVISNULL( asserted ) );

	match = 1;

	*matchp = match;
	return LDAP_SUCCESS;
}

static int
mr_passthru_initialize( void )
{
	static slap_mrule_defs_rec mr_def = {
		"( 1.2.840.113556.1.4.1941 "
			"NAME 'inChain' "
			"SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 "
			"X-PASSTHRU '' "
			")",
			SLAP_MR_HIDE | SLAP_MR_EXT, NULL,
			NULL, dnNormalize, failMatch,
			NULL, NULL,
			NULL
	};

	int			rc;

	/* equality rule */
	rc = register_matching_rule( &mr_def );
	if ( rc != 0 ) {
		return rc;
	}

	return rc;
}

int
init_module( int argc, char *argv[] )
{
	return mr_passthru_initialize();
}