LDAP Present Filter processing (ITS#2466)

Full_Name: Wai Un
Version: 2.1.17
OS: Solaris 8.0
File: ldap/servers/slapd/filterentry.c
URL:
Submission from:
I tried to control anonymous access to specific attributes using the ACL
statements. The slapd LDAP DSA instance is configured with the following
ACL statement:
....
< lines abbrev >
....
access to filter="(mail=*)" attrs=mail,serialNumber
by anonymous none
....
< lines abbrev/>
....
the purpose is to prohibit any anonymous access with the LDAP search
filter "(mail=*)".
the problem is that the LDAP DSA responded with ALL the LDAP entry
objects with ALL
the available attributes of entries who have the 'mail' attribute.
It is clear that my intent is to specify in the ACL statement an LDAP
'Present' filter => ( =* )
as the target. The effect is, so far my test is concerned, not the one
that I intented.
In the source file ( filterentry.c ), this is the code excerpt:
the prototype of the ( public ) test_filter function:
int test_filter( Backend *be, Connection *conn, Operation *op, Entry *e,
Filter *f );
the code use switch to handle different filter types, in case of the
LDAP present filter type, code reads:
....
....
case LDAP_FILTER_PRESENT:
#ifdef NEW_LOGGING
LDAP_LOG( FILTER, DETAIL1, "test_filter: PRESENT\n", 0, 0, 0 );
#else
Debug( LDAP_DEBUG_FILTER, " PRESENT\n", 0, 0, 0 );
#endif
rc = test_presence_filter( be, conn, op, e, f->f_desc );
break;
....
....
the 'test_filter' function is used extensively in the backend codes, in
the section where the LDAP_FILTER_PRESENT macro is tested, the ( private
) static function test_presence_filter
is called to handle access rules.
static int test_presence_filter( Backend *be,
Connection *conn, Operation
*op,
Entry *e,
AttributeDescription *desc );
....
....
static int
test_presence_filter(
Backend *be,
Connection *conn,
Operation *op,
Entry *e,
AttributeDescription *desc
)
{
Attribute *a;
if ( !access_allowed( be, conn, op, e, desc, NULL, ACL_SEARCH, NULL
) )
{
return LDAP_INSUFFICIENT_ACCESS;
}
a = attrs_find( e->e_attrs, desc );
if ( a == NULL && desc == slap_schema.si_ad_hasSubordinates ) {
/*
* XXX: fairly optimistic: if the function is defined,
* then PRESENCE must succeed, because hasSubordinate
* is boolean-valued; I think we may live with this
* simplification by now
*/
if ( be && be->be_has_subordinates ) {
return LDAP_COMPARE_TRUE;
}
return LDAP_COMPARE_FALSE;
}
return a != NULL ? LDAP_COMPARE_TRUE : LDAP_COMPARE_FALSE;
}
it seems that this test of 'access_allowed' is not called with proper
parameters.
I mean in the line:
access_allowed( be, conn, op, e, desc, NULL, ACL_SEARCH, NULL )
Why would the programmer pass a NULL pointer to 'access_allowed' 's last
parameter here?
It's supposed to be a pointer to the 'slap_acl_state' (
AccessControlState ) structure. Could it be better to pass initialized
pointer instead so specific members from the 'AccessControlState'
structure
could be selected?
And could this parameter passing be the reason for the weird behavior of
slapd DSA when handling LDAP present search filter?
- Especially in the form of "(mail=*)". The fact is that I do not want
to grant anonymous access to
ANY attributes at all when user search THAT WAY.
Is there a bug fix for this?
Thank you.
- Wai