Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in / Register
Toggle navigation
Menu
Open sidebar
Joe Martin
OpenLDAP
Commits
8ca6626f
Commit
8ca6626f
authored
Nov 08, 2007
by
Quanah Gibson-Mount
Browse files
ITS#5191
Fix paged results control handling
parent
c371349a
Changes
6
Hide whitespace changes
Inline
Side-by-side
CHANGES
View file @
8ca6626f
OpenLDAP 2.4 Change Log
OpenLDAP 2.4.7 Engineering
Fixed slapd paged results control handling (ITS#5191)
Documentation
Fixed grammar errors (ITS#5223)
Refint overlay doc contribution (ITS#5217)
...
...
servers/slapd/back-bdb/search.c
View file @
8ca6626f
...
...
@@ -1123,12 +1123,7 @@ static int search_candidates(
static
int
parse_paged_cookie
(
Operation
*
op
,
SlapReply
*
rs
)
{
LDAPControl
**
c
;
int
rc
=
LDAP_SUCCESS
;
ber_tag_t
tag
;
ber_int_t
size
;
BerElement
*
ber
;
struct
berval
cookie
=
BER_BVNULL
;
PagedResultsState
*
ps
=
op
->
o_pagedresults_state
;
/* this function must be invoked only if the pagedResults
...
...
@@ -1136,53 +1131,17 @@ parse_paged_cookie( Operation *op, SlapReply *rs )
* by the frontend */
assert
(
get_pagedresults
(
op
)
>
SLAP_CONTROL_IGNORED
);
/* look for the appropriate ctrl structure */
for
(
c
=
op
->
o_ctrls
;
c
[
0
]
!=
NULL
;
c
++
)
{
if
(
strcmp
(
c
[
0
]
->
ldctl_oid
,
LDAP_CONTROL_PAGEDRESULTS
)
==
0
)
{
break
;
}
}
if
(
c
[
0
]
==
NULL
)
{
rs
->
sr_text
=
"missing pagedResults control"
;
return
LDAP_PROTOCOL_ERROR
;
}
/* Tested by frontend */
assert
(
c
[
0
]
->
ldctl_value
.
bv_len
>
0
);
/* Parse the control value
* realSearchControlValue ::= SEQUENCE {
* size INTEGER (0..maxInt),
* -- requested page size from client
* -- result set size estimate from server
* cookie OCTET STRING
* }
*/
ber
=
ber_init
(
&
c
[
0
]
->
ldctl_value
);
if
(
ber
==
NULL
)
{
rs
->
sr_text
=
"internal error"
;
return
LDAP_OTHER
;
}
tag
=
ber_scanf
(
ber
,
"{im}"
,
&
size
,
&
cookie
);
/* Tested by frontend */
assert
(
tag
!=
LBER_ERROR
);
assert
(
size
>=
0
);
/* cookie decoding/checks deferred to backend... */
if
(
cookie
.
bv_len
)
{
if
(
ps
->
ps_
cookie
val
.
bv_len
)
{
PagedResultsCookie
reqcookie
;
if
(
cookie
.
bv_len
!=
sizeof
(
reqcookie
)
)
{
if
(
ps
->
ps_
cookie
val
.
bv_len
!=
sizeof
(
reqcookie
)
)
{
/* bad cookie */
rs
->
sr_text
=
"paged results cookie is invalid"
;
rc
=
LDAP_PROTOCOL_ERROR
;
goto
done
;
}
AC_MEMCPY
(
&
reqcookie
,
cookie
.
bv_val
,
sizeof
(
reqcookie
));
AC_MEMCPY
(
&
reqcookie
,
ps
->
ps_
cookie
val
.
bv_val
,
sizeof
(
reqcookie
));
if
(
reqcookie
>
ps
->
ps_cookie
)
{
/* bad cookie */
...
...
@@ -1198,22 +1157,11 @@ parse_paged_cookie( Operation *op, SlapReply *rs )
}
else
{
/* Initial request. Initialize state. */
#if 0
if ( op->o_conn->c_pagedresults_state.ps_cookie != 0 ) {
/* There's another pagedResults control on the
* same connection; reject new pagedResults controls
* (allowed by RFC2696) */
rs->sr_text = "paged results cookie unavailable; try later";
rc = LDAP_UNWILLING_TO_PERFORM;
goto done;
}
#endif
ps
->
ps_cookie
=
0
;
ps
->
ps_count
=
0
;
}
done:
;
(
void
)
ber_free
(
ber
,
1
);
return
rc
;
}
...
...
servers/slapd/back-sql/search.c
View file @
8ca6626f
...
...
@@ -2668,12 +2668,7 @@ backsql_entry_release(
static
int
parse_paged_cookie
(
Operation
*
op
,
SlapReply
*
rs
)
{
LDAPControl
**
c
;
int
rc
=
LDAP_SUCCESS
;
ber_tag_t
tag
;
ber_int_t
size
;
BerElement
*
ber
;
struct
berval
cookie
=
BER_BVNULL
;
PagedResultsState
*
ps
=
op
->
o_pagedresults_state
;
/* this function must be invoked only if the pagedResults
...
...
@@ -2681,53 +2676,17 @@ parse_paged_cookie( Operation *op, SlapReply *rs )
* by the frontend */
assert
(
get_pagedresults
(
op
)
>
SLAP_CONTROL_IGNORED
);
/* look for the appropriate ctrl structure */
for
(
c
=
op
->
o_ctrls
;
c
[
0
]
!=
NULL
;
c
++
)
{
if
(
strcmp
(
c
[
0
]
->
ldctl_oid
,
LDAP_CONTROL_PAGEDRESULTS
)
==
0
)
{
break
;
}
}
if
(
c
[
0
]
==
NULL
)
{
rs
->
sr_text
=
"missing pagedResults control"
;
return
LDAP_PROTOCOL_ERROR
;
}
/* Tested by frontend */
assert
(
c
[
0
]
->
ldctl_value
.
bv_len
>
0
);
/* Parse the control value
* realSearchControlValue ::= SEQUENCE {
* size INTEGER (0..maxInt),
* -- requested page size from client
* -- result set size estimate from server
* cookie OCTET STRING
* }
*/
ber
=
ber_init
(
&
c
[
0
]
->
ldctl_value
);
if
(
ber
==
NULL
)
{
rs
->
sr_text
=
"internal error"
;
return
LDAP_OTHER
;
}
tag
=
ber_scanf
(
ber
,
"{im}"
,
&
size
,
&
cookie
);
/* Tested by frontend */
assert
(
tag
!=
LBER_ERROR
);
assert
(
size
>=
0
);
/* cookie decoding/checks deferred to backend... */
if
(
cookie
.
bv_len
)
{
if
(
ps
->
ps_
cookie
val
.
bv_len
)
{
PagedResultsCookie
reqcookie
;
if
(
cookie
.
bv_len
!=
sizeof
(
reqcookie
)
)
{
if
(
ps
->
ps_
cookie
val
.
bv_len
!=
sizeof
(
reqcookie
)
)
{
/* bad cookie */
rs
->
sr_text
=
"paged results cookie is invalid"
;
rc
=
LDAP_PROTOCOL_ERROR
;
goto
done
;
}
AC_MEMCPY
(
&
reqcookie
,
cookie
.
bv_val
,
sizeof
(
reqcookie
));
AC_MEMCPY
(
&
reqcookie
,
ps
->
ps_
cookie
val
.
bv_val
,
sizeof
(
reqcookie
));
if
(
reqcookie
>
ps
->
ps_cookie
)
{
/* bad cookie */
...
...
@@ -2743,22 +2702,11 @@ parse_paged_cookie( Operation *op, SlapReply *rs )
}
else
{
/* Initial request. Initialize state. */
#if 0
if ( op->o_conn->c_pagedresults_state.ps_cookie != 0 ) {
/* There's another pagedResults control on the
* same connection; reject new pagedResults controls
* (allowed by RFC2696) */
rs->sr_text = "paged results cookie unavailable; try later";
rc = LDAP_UNWILLING_TO_PERFORM;
goto done;
}
#endif
ps
->
ps_cookie
=
0
;
ps
->
ps_count
=
0
;
}
done:
;
(
void
)
ber_free
(
ber
,
1
);
return
rc
;
}
...
...
servers/slapd/backglue.c
View file @
8ca6626f
...
...
@@ -161,6 +161,31 @@ glue_op_response ( Operation *op, SlapReply *rs )
if
(
!
j
)
{
newctrls
=
ch_malloc
((
i
+
1
)
*
sizeof
(
LDAPControl
*
));
}
else
{
/* Forget old pagedResults response if we're sending
* a new one now
*/
if
(
get_pagedresults
(
op
)
>
SLAP_CONTROL_IGNORED
)
{
int
newpage
=
0
;
for
(
k
=
0
;
k
<
i
;
k
++
)
{
if
(
!
strcmp
(
rs
->
sr_ctrls
[
k
]
->
ldctl_oid
,
LDAP_CONTROL_PAGEDRESULTS
))
{
newpage
=
1
;
break
;
}
}
if
(
newpage
)
{
for
(
k
=
0
;
k
<
j
;
k
++
)
{
if
(
!
strcmp
(
gs
->
ctrls
[
k
]
->
ldctl_oid
,
LDAP_CONTROL_PAGEDRESULTS
))
{
gs
->
ctrls
[
k
]
->
ldctl_oid
=
NULL
;
ldap_control_free
(
gs
->
ctrls
[
k
]
);
gs
->
ctrls
[
k
]
=
gs
->
ctrls
[
--
j
];
gs
->
ctrls
[
j
]
=
NULL
;
break
;
}
}
}
}
newctrls
=
ch_realloc
(
gs
->
ctrls
,
(
j
+
i
+
1
)
*
sizeof
(
LDAPControl
*
));
}
...
...
@@ -321,7 +346,7 @@ glue_op_search ( Operation *op, SlapReply *rs )
slap_overinst
*
on
=
(
slap_overinst
*
)
op
->
o_bd
->
bd_info
;
glueinfo
*
gi
=
(
glueinfo
*
)
on
->
on_bi
.
bi_private
;
BackendDB
*
b0
=
op
->
o_bd
;
BackendDB
*
b1
=
NULL
,
*
btmp
;
BackendDB
*
btmp
;
BackendInfo
*
bi0
=
op
->
o_bd
->
bd_info
;
int
i
;
long
stoptime
=
0
,
starttime
;
...
...
@@ -360,7 +385,6 @@ glue_op_search ( Operation *op, SlapReply *rs )
tlimit0
=
op
->
ors_tlimit
;
dn
=
op
->
o_req_dn
;
ndn
=
op
->
o_req_ndn
;
b1
=
op
->
o_bd
;
/*
* Execute in reverse order, most specific first
...
...
@@ -375,9 +399,16 @@ glue_op_search ( Operation *op, SlapReply *rs )
}
if
(
!
btmp
||
!
btmp
->
be_search
)
continue
;
if
(
!
dnIsSuffix
(
&
btmp
->
be_nsuffix
[
0
],
&
b1
->
be_nsuffix
[
0
]))
if
(
!
dnIsSuffix
(
&
btmp
->
be_nsuffix
[
0
],
&
b0
->
be_nsuffix
[
0
]))
continue
;
if
(
get_no_subordinate_glue
(
op
)
&&
btmp
!=
b0
)
continue
;
if
(
get_no_subordinate_glue
(
op
)
&&
btmp
!=
b1
)
/* If we remembered which backend we were on before,
* skip down to it now
*/
if
(
get_pagedresults
(
op
)
>
SLAP_CONTROL_IGNORED
&&
op
->
o_conn
->
c_pagedresults_state
.
ps_be
&&
op
->
o_conn
->
c_pagedresults_state
.
ps_be
!=
btmp
)
continue
;
if
(
tlimit0
!=
SLAP_NO_LIMIT
)
{
...
...
@@ -449,7 +480,41 @@ glue_op_search ( Operation *op, SlapReply *rs )
case
LDAP_X_CANNOT_CHAIN
:
#endif
/* LDAP_CONTROL_X_CHAINING_BEHAVIOR */
goto
end_of_loop
;
case
LDAP_SUCCESS
:
if
(
get_pagedresults
(
op
)
>
SLAP_CONTROL_IGNORED
)
{
PagedResultsState
*
ps
=
op
->
o_pagedresults_state
;
/* Assume this backend can be forgotten now */
op
->
o_conn
->
c_pagedresults_state
.
ps_be
=
NULL
;
/* If we have a full page, exit the loop. We may
* need to remember this backend so we can continue
* from here on a subsequent request.
*/
if
(
rs
->
sr_nentries
>=
ps
->
ps_size
)
{
/* Don't bother to remember the first backend.
* Only remember the last one if there's more state left.
*/
if
(
op
->
o_bd
!=
b0
&&
(
op
->
o_conn
->
c_pagedresults_state
.
ps_cookie
||
op
->
o_bd
!=
gi
->
gi_n
[
0
].
gn_be
))
op
->
o_conn
->
c_pagedresults_state
.
ps_be
=
op
->
o_bd
;
goto
end_of_loop
;
}
/* This backend has run out of entries, but more responses
* can fit in the page. Fake a reset of the state so the
* next backend will start up properly. Only back-[bh]db
* and back-sql look at this state info.
*/
if
(
ps
->
ps_cookieval
.
bv_len
==
sizeof
(
PagedResultsCookie
))
{
ps
->
ps_cookie
=
0
;
memset
(
ps
->
ps_cookieval
.
bv_val
,
0
,
sizeof
(
PagedResultsCookie
));
}
}
default:
break
;
}
...
...
servers/slapd/controls.c
View file @
8ca6626f
...
...
@@ -1050,12 +1050,13 @@ static int parsePagedResults (
SlapReply
*
rs
,
LDAPControl
*
ctrl
)
{
BerElementBuffer
berbuf
;
BerElement
*
ber
=
(
BerElement
*
)
&
berbuf
;
struct
berval
cookie
;
PagedResultsState
*
ps
;
int
rc
=
LDAP_SUCCESS
;
ber_tag_t
tag
;
ber_int_t
size
;
BerElement
*
ber
;
struct
berval
cookie
=
BER_BVNULL
;
PagedResultsState
*
ps
;
if
(
op
->
o_pagedresults
!=
SLAP_CONTROL_NONE
)
{
rs
->
sr_text
=
"paged results control specified multiple times"
;
...
...
@@ -1080,11 +1081,7 @@ static int parsePagedResults (
* cookie OCTET STRING
* }
*/
ber
=
ber_init
(
&
ctrl
->
ldctl_value
);
if
(
ber
==
NULL
)
{
rs
->
sr_text
=
"internal error"
;
return
LDAP_OTHER
;
}
ber_init2
(
ber
,
&
ctrl
->
ldctl_value
,
LBER_USE_DER
);
tag
=
ber_scanf
(
ber
,
"{im}"
,
&
size
,
&
cookie
);
...
...
@@ -1103,6 +1100,7 @@ static int parsePagedResults (
ps
=
op
->
o_tmpalloc
(
sizeof
(
PagedResultsState
),
op
->
o_tmpmemctx
);
*
ps
=
op
->
o_conn
->
c_pagedresults_state
;
ps
->
ps_size
=
size
;
ps
->
ps_cookieval
=
cookie
;
op
->
o_pagedresults_state
=
ps
;
/* NOTE: according to RFC 2696 3.:
...
...
@@ -1126,7 +1124,6 @@ static int parsePagedResults (
}
done:
;
(
void
)
ber_free
(
ber
,
1
);
return
rc
;
}
...
...
servers/slapd/slap.h
View file @
8ca6626f
...
...
@@ -2330,8 +2330,9 @@ typedef unsigned long PagedResultsCookie;
typedef
struct
PagedResultsState
{
Backend
*
ps_be
;
ber_int_t
ps_size
;
PagedResultsCookie
ps_cookie
;
int
ps_count
;
PagedResultsCookie
ps_cookie
;
struct
berval
ps_cookieval
;
}
PagedResultsState
;
struct
slap_csn_entry
{
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment