Issue 6598 - EXOP to return number of children of a (sub)tree
Summary: EXOP to return number of children of a (sub)tree
Status: VERIFIED FIXED
Alias: None
Product: OpenLDAP
Classification: Unclassified
Component: slapd (show other issues)
Version: unspecified
Hardware: All All
: --- normal
Target Milestone: ---
Assignee: OpenLDAP project
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2010-07-21 18:56 UTC by Quanah Gibson-Mount
Modified: 2021-09-11 10:19 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Quanah Gibson-Mount 2010-07-21 18:56:13 UTC
Full_Name: Quanah Gibson-Mount
Version: NA
OS: NA
URL: ftp://ftp.openldap.org/incoming/
Submission from: (NULL) (75.111.45.108)


It would be extremely useful to have an extended operation that allows querying
the number of children of a given (sub)tree, so that one can avoid iterating
through the entire subtree to determine this number.
Comment 1 Howard Chu 2010-07-21 19:17:55 UTC
quanah@zimbra.com wrote:
> Full_Name: Quanah Gibson-Mount
> Version: NA
> OS: NA
> URL: ftp://ftp.openldap.org/incoming/
> Submission from: (NULL) (75.111.45.108)
>
>
> It would be extremely useful to have an extended operation that allows querying
> the number of children of a given (sub)tree, so that one can avoid iterating
> through the entire subtree to determine this number.
>
Might as well ask for the numSubordinates operational attribute to be 
implemented instead, this doesn't seem to merit a new exop. And for 
numSubordinates, see the -devel archives for why we chose not to implement it.

In either case, the server still needs to iterate over all entries internally, 
and the result has to take ACLs and entry disclosure into account.

-- 
   -- Howard Chu
   CTO, Symas Corp.           http://www.symas.com
   Director, Highland Sun     http://highlandsun.com/hyc/
   Chief Architect, OpenLDAP  http://www.openldap.org/project/

Comment 2 ando@openldap.org 2010-07-21 19:24:49 UTC
> quanah@zimbra.com wrote:
>> Full_Name: Quanah Gibson-Mount
>> Version: NA
>> OS: NA
>> URL: ftp://ftp.openldap.org/incoming/
>> Submission from: (NULL) (75.111.45.108)
>>
>>
>> It would be extremely useful to have an extended operation that allows
>> querying
>> the number of children of a given (sub)tree, so that one can avoid
>> iterating
>> through the entire subtree to determine this number.
>>
> Might as well ask for the numSubordinates operational attribute to be
> implemented instead, this doesn't seem to merit a new exop. And for
> numSubordinates, see the -devel archives for why we chose not to implement
> it.
>
> In either case, the server still needs to iterate over all entries
> internally,
> and the result has to take ACLs and entry disclosure into account.

An exop would allow to easily discriminate between intentional and
"catchall" requests, like "+".  Moreover, it might make sense to
discriminate at least between subtree and onelevel number of subordinates;
this would require two distinct operational attributes, or a parameter in
the exop.

I'm not endorsing either solution, I'm just pointing out possible pros and
cons.

p.

Comment 3 Howard Chu 2010-07-21 20:37:54 UTC
masarati@aero.polimi.it wrote:
>> quanah@zimbra.com wrote:
>>> Full_Name: Quanah Gibson-Mount
>>> Version: NA
>>> OS: NA
>>> URL: ftp://ftp.openldap.org/incoming/
>>> Submission from: (NULL) (75.111.45.108)
>>>
>>>
>>> It would be extremely useful to have an extended operation that allows
>>> querying
>>> the number of children of a given (sub)tree, so that one can avoid
>>> iterating
>>> through the entire subtree to determine this number.
>>>
>> Might as well ask for the numSubordinates operational attribute to be
>> implemented instead, this doesn't seem to merit a new exop. And for
>> numSubordinates, see the -devel archives for why we chose not to implement
>> it.
>>
>> In either case, the server still needs to iterate over all entries
>> internally,
>> and the result has to take ACLs and entry disclosure into account.
>
> An exop would allow to easily discriminate between intentional and
> "catchall" requests, like "+".  Moreover, it might make sense to
> discriminate at least between subtree and onelevel number of subordinates;
> this would require two distinct operational attributes, or a parameter in
> the exop.
>
> I'm not endorsing either solution, I'm just pointing out possible pros and
> cons.

If you want to be able to distinguish results based on scope then it makes 
more sense to just define a Search control. Like No-op - count the entries 
that would be returned, instead of returning them. (And bypassing the 
sizelimit too, but probably not bypassing timelimit.)

-- 
   -- Howard Chu
   CTO, Symas Corp.           http://www.symas.com
   Director, Highland Sun     http://highlandsun.com/hyc/
   Chief Architect, OpenLDAP  http://www.openldap.org/project/

Comment 4 ando@openldap.org 2010-08-27 09:12:30 UTC
moved from Incoming to Software Enhancements
Comment 5 ando@openldap.org 2010-09-05 16:17:52 UTC
> masarati@aero.polimi.it wrote:
>>> quanah@zimbra.com wrote:
>>>> Full_Name: Quanah Gibson-Mount
>>>> Version: NA
>>>> OS: NA
>>>> URL: ftp://ftp.openldap.org/incoming/
>>>> Submission from: (NULL) (75.111.45.108)
>>>>
>>>>
>>>> It would be extremely useful to have an extended operation that allows
>>>> querying
>>>> the number of children of a given (sub)tree, so that one can avoid
>>>> iterating
>>>> through the entire subtree to determine this number.
>>>>
>>> Might as well ask for the numSubordinates operational attribute to be
>>> implemented instead, this doesn't seem to merit a new exop. And for
>>> numSubordinates, see the -devel archives for why we chose not to
>>> implement
>>> it.
>>>
>>> In either case, the server still needs to iterate over all entries
>>> internally,
>>> and the result has to take ACLs and entry disclosure into account.
>>
>> An exop would allow to easily discriminate between intentional and
>> "catchall" requests, like "+".  Moreover, it might make sense to
>> discriminate at least between subtree and onelevel number of
>> subordinates;
>> this would require two distinct operational attributes, or a parameter
>> in
>> the exop.
>>
>> I'm not endorsing either solution, I'm just pointing out possible pros
>> and
>> cons.
>
> If you want to be able to distinguish results based on scope then it makes
> more sense to just define a Search control. Like No-op - count the entries
> that would be returned, instead of returning them. (And bypassing the
> sizelimit too, but probably not bypassing timelimit.)

I'm drafting the code to implement this no-op search.

The semantics consists in a control request in a search request that
results in returning no intermediate responses, only a final response with
a control response that contains summary information on what the search
would have done.

The request control value is empty.

The response control value contains:
  - the error that the search would have returned if it were performed
regularly (should differ from the one actually returned only in case of
sizelimit exceeded)
  - the number of entries that would be returned
  - the number of search references that would be returned

The search request should request no attributes (in any case no attributes
will be returned); I'm not sure whether it is preferable to simply ignore
requested attrs or the control must require that no attrs ("1.1") be
explicitly requested; I favor the first (ignore req attrs) to ease
interoperability; similarly, attrsOnly can be safely ignored.

The rest of the search should be dealt with as usual (base, scope, filter,
alias dereferencing and so on), as well as ACL.  This allows, for example,
to count immediate children (scope=onelevel), to count subtrees
(scope=subtree); the filter allows to select what is counted; and so on.

The code is almost done; am I missing anything?  In case, let me know so I
can fix it before committing.

Thanks, p.

Comment 6 Michael Ströder 2010-09-06 20:06:13 UTC
masarati@aero.polimi.it wrote:
>> If you want to be able to distinguish results based on scope then it makes
>> more sense to just define a Search control. Like No-op - count the entries
>> that would be returned, instead of returning them. (And bypassing the
>> sizelimit too, but probably not bypassing timelimit.)
> 
> I'm drafting the code to implement this no-op search.

Maybe sizelimit should not be by-passed in all cases.
How about letting the client choose which limits are by-passed?

Ciao, Michael.

Comment 7 ando@openldap.org 2010-09-06 22:52:38 UTC
> masarati@aero.polimi.it wrote:
>>> If you want to be able to distinguish results based on scope then it
>>> makes
>>> more sense to just define a Search control. Like No-op - count the
>>> entries
>>> that would be returned, instead of returning them. (And bypassing the
>>> sizelimit too, but probably not bypassing timelimit.)
>>
>> I'm drafting the code to implement this no-op search.
>
> Maybe sizelimit should not be by-passed in all cases.
> How about letting the client choose which limits are by-passed?

Michael,

your idea sounds interesting.  In the current implementation sizelimits
are technically bypassed during the internal search.  Since the operation
returns only a (possibly successful) searchResultDone, it seems
appropriate to return success when sizelimit would be violated, because
from the client's perspective no sizelimit could be exceeded since no
entry is being returned.  The fact that the actual search would be
exceeded is reflected in the additional response code in the control
response's value.

Could you be more precise about what you mean?  One or two use cases or a
not-so-formal specification would suffice.

Thanks, p.

Comment 8 ando@openldap.org 2010-09-09 07:00:13 UTC
changed notes
changed state Open to Test
moved from Software Enhancements to Development
Comment 9 ando@openldap.org 2010-09-09 18:44:36 UTC
Committed to HEAD; please test.  Thanks, p.

Comment 10 ando@openldap.org 2010-09-14 12:41:03 UTC
changed notes
Comment 11 Quanah Gibson-Mount 2011-01-03 12:07:17 UTC
changed notes
changed state Test to Release
Comment 12 Quanah Gibson-Mount 2011-02-14 12:35:57 UTC
changed notes
changed state Release to Closed
Comment 13 Quanah Gibson-Mount 2012-02-17 23:47:11 UTC
--On Thursday, September 09, 2010 6:45 PM +0000 masarati@aero.polimi.it 
wrote:

> Committed to HEAD; please test.  Thanks, p.


Doesn't appear to work to me.

This search returns 15 entries normally:

ldapsearch -x -H ldapi:/// -D cn=config -w zimbra -b "" 
'(objectClass=zimbraAccount)' zimbraId

# numResponses: 16
# numEntries: 15


If you choose the control you get:

zimbra@zre-ldap003:~$ ldapsearch -x -H ldapi:/// -D cn=config -w zimbra -b 
"" -e '1.3.6.1.4.1.4203.666.5.18' '(objectClass=zimbraAccount)' zimbraId
# extended LDIF
#
# LDAPv3
# base <> with scope subtree
# filter: (objectClass=zimbraAccount)
# requesting: zimbraId
#

# search result
search: 2
result: 0 Success
control: 1.3.6.1.4.1.4203.666.5.18 false MAkCAQACAQ8CAQA=

# numResponses: 1

MAkCAQACAQ8CAQA= decodes to a 0 followed by several spaces.  If you try to 
make it critical, it fails:

zimbra@zre-ldap003:~$ ldapsearch -x -H ldapi:/// -D cn=config -w zimbra -b 
"" -e '!1.3.6.1.4.1.4203.666.5.18' '(objectClass=zimbraAccount)' zimbraId
# extended LDIF
#
# LDAPv3
# base <> with scope subtree
# filter: (objectClass=zimbraAccount)
# requesting: zimbraId
#

# search result
search: 2
result: 12 Critical extension is unavailable
text: critical control unavailable in context

# numResponses: 1


--Quanah


--

Quanah Gibson-Mount
Sr. Member of Technical Staff
Zimbra, Inc
A Division of VMware, Inc.
--------------------
Zimbra ::  the leader in open source messaging and collaboration

Comment 14 Quanah Gibson-Mount 2012-02-17 23:59:47 UTC
--On Friday, February 17, 2012 11:48 PM +0000 quanah@zimbra.com wrote:

> --On Thursday, September 09, 2010 6:45 PM +0000 masarati@aero.polimi.it
> wrote:
>
>> Committed to HEAD; please test.  Thanks, p.
>
>
> Doesn't appear to work to me.
>
> This search returns 15 entries normally:
>
> ldapsearch -x -H ldapi:/// -D cn=config -w zimbra -b ""
> '(objectClass=zimbraAccount)' zimbraId
>
># numResponses: 16
># numEntries: 15
>
>
> If you choose the control you get:
>
> zimbra@zre-ldap003:~$ ldapsearch -x -H ldapi:/// -D cn=config -w zimbra
> -b  "" -e '1.3.6.1.4.1.4203.666.5.18' '(objectClass=zimbraAccount)'


Also, just to show it is definitely loaded:

ldapsearch -x -H ldap://zre-ldap003.eng.vmware.com -s base -b "" +

dn:
structuralObjectClass: OpenLDAProotDSE
configContext: cn=config
monitorContext: cn=Monitor
namingContexts:
supportedControl: 1.3.6.1.4.1.4203.666.5.18


--Quanah



--

Quanah Gibson-Mount
Sr. Member of Technical Staff
Zimbra, Inc
A Division of VMware, Inc.
--------------------
Zimbra ::  the leader in open source messaging and collaboration

Comment 15 ando@openldap.org 2012-02-18 00:32:33 UTC
> --On Thursday, September 09, 2010 6:45 PM +0000 masarati@aero.polimi.it
> wrote:
>
>> Committed to HEAD; please test.  Thanks, p.
>
>
> Doesn't appear to work to me.
>
> This search returns 15 entries normally:
>
> ldapsearch -x -H ldapi:/// -D cn=config -w zimbra -b ""
> '(objectClass=zimbraAccount)' zimbraId
>
> # numResponses: 16
> # numEntries: 15
>
>
> If you choose the control you get:
>
> zimbra@zre-ldap003:~$ ldapsearch -x -H ldapi:/// -D cn=config -w zimbra -b
> "" -e '1.3.6.1.4.1.4203.666.5.18' '(objectClass=zimbraAccount)' zimbraId
> # extended LDIF
> #
> # LDAPv3
> # base <> with scope subtree
> # filter: (objectClass=zimbraAccount)
> # requesting: zimbraId
> #
>
> # search result
> search: 2
> result: 0 Success
> control: 1.3.6.1.4.1.4203.666.5.18 false MAkCAQACAQ8CAQA=

I think it works as expected:

$ echo -n 'MAkCAQACAQ8CAQA=' | base64 -d | od -x
0000000 0930 0102 0200 0f01 0102 0000

re-ordered:

0x30 ber sequence
0x09 length (9 bytes)

0x02 ber int
0x01 length (1 byte)
0x00 "0" (value of would be search result code)

0x02 ber int
0x01 length (1 byte)
0x0f "15" (number of would be returned entries)

0x02 ber int
0x01 length (1 byte)
0x00 "0" (number of would be returned search refs)

p.

>
> # numResponses: 1
>
> MAkCAQACAQ8CAQA= decodes to a 0 followed by several spaces.  If you try to
> make it critical, it fails:
>
> zimbra@zre-ldap003:~$ ldapsearch -x -H ldapi:/// -D cn=config -w zimbra -b
> "" -e '!1.3.6.1.4.1.4203.666.5.18' '(objectClass=zimbraAccount)' zimbraId
> # extended LDIF
> #
> # LDAPv3
> # base <> with scope subtree
> # filter: (objectClass=zimbraAccount)
> # requesting: zimbraId
> #
>
> # search result
> search: 2
> result: 12 Critical extension is unavailable
> text: critical control unavailable in context
>
> # numResponses: 1
>
>
> --Quanah
>
>
> --
>
> Quanah Gibson-Mount
> Sr. Member of Technical Staff
> Zimbra, Inc
> A Division of VMware, Inc.
> --------------------
> Zimbra ::  the leader in open source messaging and collaboration
>
>
>
>


Comment 16 Quanah Gibson-Mount 2012-02-18 00:39:08 UTC
--On Saturday, February 18, 2012 1:32 AM +0100 masarati@aero.polimi.it 
wrote:

>> --On Thursday, September 09, 2010 6:45 PM +0000 masarati@aero.polimi.it
>> wrote:
>>
>>> Committed to HEAD; please test.  Thanks, p.
>>
>>
>> Doesn't appear to work to me.
>>
>> This search returns 15 entries normally:
>>
>> ldapsearch -x -H ldapi:/// -D cn=config -w zimbra -b ""
>> '(objectClass=zimbraAccount)' zimbraId
>>
>> # numResponses: 16
>> # numEntries: 15
>>
>>
>> If you choose the control you get:
>>
>> zimbra@zre-ldap003:~$ ldapsearch -x -H ldapi:/// -D cn=config -w zimbra
>> -b "" -e '1.3.6.1.4.1.4203.666.5.18' '(objectClass=zimbraAccount)'
>> zimbraId
>> # extended LDIF
>> #
>> # LDAPv3
>> # base <> with scope subtree
>> # filter: (objectClass=zimbraAccount)
>> # requesting: zimbraId
>> #
>>
>> # search result
>> search: 2
>> result: 0 Success
>> control: 1.3.6.1.4.1.4203.666.5.18 false MAkCAQACAQ8CAQA=
>
> I think it works as expected:
>
> $ echo -n 'MAkCAQACAQ8CAQA=' | base64 -d | od -x
> 0000000 0930 0102 0200 0f01 0102 0000
>
> re-ordered:
>
> 0x30 ber sequence
> 0x09 length (9 bytes)
>
> 0x02 ber int
> 0x01 length (1 byte)
> 0x00 "0" (value of would be search result code)
>
> 0x02 ber int
> 0x01 length (1 byte)
> 0x0f "15" (number of would be returned entries)
>
> 0x02 ber int
> 0x01 length (1 byte)
> 0x00 "0" (number of would be returned search refs)

ah, ok thanks.  :)

--Quanah



--

Quanah Gibson-Mount
Sr. Member of Technical Staff
Zimbra, Inc
A Division of VMware, Inc.
--------------------
Zimbra ::  the leader in open source messaging and collaboration

Comment 17 Quanah Gibson-Mount 2012-02-18 00:48:31 UTC
--On Saturday, February 18, 2012 12:41 AM +0000 quanah@zimbra.com wrote:

> --On Saturday, February 18, 2012 1:32 AM +0100 masarati@aero.polimi.it
> wrote:

> ah, ok thanks.  :)


Any particularly reason why the control can't be made critical?

Thanks,
Quanah

--

Quanah Gibson-Mount
Sr. Member of Technical Staff
Zimbra, Inc
A Division of VMware, Inc.
--------------------
Zimbra ::  the leader in open source messaging and collaboration

Comment 18 ando@openldap.org 2012-04-10 22:51:37 UTC
> --On Saturday, February 18, 2012 12:41 AM +0000 quanah@zimbra.com wrote:
>
>> --On Saturday, February 18, 2012 1:32 AM +0100 masarati@aero.polimi.it
>> wrote:
>
>> ah, ok thanks.  :)
>
>
> Any particularly reason why the control can't be made critical?

No.  Now it can.  p.

Comment 19 OpenLDAP project 2014-08-01 21:05:02 UTC
noopsrch overlay (control) committed to HEAD
added to RE24