Sync with HEAD

This commit is contained in:
Kurt Zeilenga 2005-11-27 00:54:32 +00:00
parent 2c7553a359
commit 20c5ec953c
118 changed files with 5934 additions and 3921 deletions

3137
configure vendored

File diff suppressed because it is too large Load Diff

@ -43,7 +43,7 @@ ldapsearch \- LDAP search tool
[\c [\c
.BI \-b \ searchbase\fR] .BI \-b \ searchbase\fR]
[\c [\c
.BI \-s \ base\fR\||\|\fIone\fR\||\|\fIsub\fR] .BI \-s \ base\fR\||\|\fIone\fR\||\|\fIsub\fR\||\|\fIchildren\fR]
[\c [\c
.BI \-a \ never\fR\||\|\fIalways\fR\||\|\fIsearch\fR\||\|\fIfind\fR] .BI \-a \ never\fR\||\|\fIalways\fR\||\|\fIsearch\fR\||\|\fIfind\fR]
[\c [\c
@ -183,15 +183,19 @@ Deprecated in favor of -H.
Use \fIsearchbase\fP as the starting point for the search instead of Use \fIsearchbase\fP as the starting point for the search instead of
the default. the default.
.TP .TP
.BI \-s \ base\fR\||\|\fIone\fR\||\|\fIsub .BI \-s \ base\fR\||\|\fIone\fR\||\|\fIsub\fR\||\|\fIchildren
Specify the scope of the search to be one of Specify the scope of the search to be one of
.IR base , .IR base ,
.IR one , .IR one ,
.IR sub ,
or or
.I sub .I children
to specify a base object, one-level, or subtree search. The default to specify a base object, one-level, subtree, or children search.
is The default is
.IR sub . .IR sub .
Note:
.I children
scope requires LDAPv3 subordinate feature extension.
.TP .TP
.BI \-a \ never\fR\||\|\fIalways\fR\||\|\fIsearch\fR\||\|\fIfind .BI \-a \ never\fR\||\|\fIalways\fR\||\|\fIsearch\fR\||\|\fIfind
Specify how aliases dereferencing is done. Should be one of Specify how aliases dereferencing is done. Should be one of

@ -1758,7 +1758,8 @@ By default it is not built.
.B chain .B chain
Chaining. Chaining.
This overlay allows automatic referral chasing when a referral would This overlay allows automatic referral chasing when a referral would
have been returned. have been returned, either when configured by the server or when
requested by the client.
.TP .TP
.B denyop .B denyop
Deny Operation. Deny Operation.

@ -28,9 +28,9 @@ directive.
.B logdb <suffix> .B logdb <suffix>
Specify the suffix of a database to be used for storing the log records. Specify the suffix of a database to be used for storing the log records.
The specified database must have already been configured in a prior section The specified database must have already been configured in a prior section
of the config file. The suffix entry of the database must also already of the config file. The suffix entry of the log database will be created
exist. The log entries will be generated as the immediate children of the automatically by this overlay. The log entries will be generated as the
suffix entry. immediate children of the suffix entry.
.TP .TP
.B logops <operations> .B logops <operations>
Specify which types of operations to log. The valid operation types are Specify which types of operations to log. The valid operation types are

@ -13,7 +13,7 @@ overlay to
.BR slapd (8) .BR slapd (8)
allows automatic referral chasing. allows automatic referral chasing.
Any time a referral is returned (except for bind operations), Any time a referral is returned (except for bind operations),
it is chased by using an instance of the ldap backend. it chased by using an instance of the ldap backend.
If operations are performed with an identity (i.e. after a bind), If operations are performed with an identity (i.e. after a bind),
that identity can be asserted while chasing the referrals that identity can be asserted while chasing the referrals
by means of the \fIidentity assertion\fP feature of back-ldap by means of the \fIidentity assertion\fP feature of back-ldap
@ -21,52 +21,104 @@ by means of the \fIidentity assertion\fP feature of back-ldap
.BR slapd-ldap (5) .BR slapd-ldap (5)
for details), which is essentially based on the for details), which is essentially based on the
.B proxyAuthz .B proxyAuthz
control (see \fIdraft-weltman-ldapv3-proxy\fP for details). control (see \fIdraft-weltman-ldapv3-proxy\fP for details.)
Referral chasing can be controlled by the client by issuing the
\fBchaining\fP control
(see \fIdraft-sermersheim-ldap-chaining\fP for details.)
.LP .LP
The config directives that are specific to the The config directives that are specific to the
.B chain .B chain
overlay can be prefixed by overlay are prefixed by
.BR chain\- , .BR chain\- ,
to avoid potential conflicts with directives specific to the underlying to avoid potential conflicts with directives specific to the underlying
database or to other stacked overlays. database or to other stacked overlays.
.LP .LP
There are no chain overlay specific directives; however, directives There are very few chain overlay specific directives; however, directives
related to the \fIldap\fP database that is implicitly instantiated related to the instances of the \fIldap\fP backend that may be implicitly
by the overlay may assume a special meaning when used in conjunction instantiated by the overlay may assume a special meaning when used
with this overlay. They are described in in conjunction with this overlay. They are described in
.BR slapd-ldap (5). .BR slapd-ldap (5),
and they also need be prefixed by
.BR chain\- .
.TP .TP
.B overlay chain .B overlay chain
This directive adds the chain overlay to the current backend. This directive adds the chain overlay to the current backend.
The chain overlay may be used with any backend, but it is mainly The chain overlay may be used with any backend, but it is mainly
intended for use with local storage backends that may return referrals. intended for use with local storage backends that may return referrals.
It is useless in conjunction with the \fIldap\fP and \fImeta\fP backends It is useless in conjunction with the \fIslapd-ldap\fP and \fIslapd-meta\fP
because they already exploit the libldap specific referral chase feature. backends because they already exploit the libldap specific referral chase
feature.
[Note: this may change in the future, as the \fBldap\fP(5) and
\fBmeta\fP(5) backends might no longer chase referrals on their own.]
.TP
.B chain-chaining [resolve=<r>] [continuation=<c>] [critical]
This directive enables the \fIchaining\fP control
(see \fIdraft-sermersheim-ldap-chaining\fP for details)
with the desired resolve and continuation behaviors and criticality.
The \fBresolve\fP parameter refers to the behavior while discovering
a resource, namely when accessing the object indicated by the request DN;
the \fBcontinuation\fP parameter refers to the behavior while handling
intermediate responses, which is mostly significant for the search
operation, but may affect extended operations that return intermediate
responses.
The values \fBr\fP and \fBc\fP can be any of
.BR chainingPreferred ,
.BR chainingRequired ,
.BR referralsPreferred ,
.BR referralsRequired .
If the \fBcritical\fP flag affects the control criticality if provided.
[This control is experimental and its support may change in the future.]
.TP
.B chain-cache-uris {FALSE|true}
This directive instructs the \fIchain\fP overlay to cache
connections to URIs parsed out of referrals that are not predefined,
to be reused for later chaining.
.TP .TP
.B chain-uri <ldapuri> .B chain-uri <ldapuri>
This directive instructs the underlying ldap database about which This directive instantiates a new underlying \fIldap\fP database
URI to contact to chase referrals. and instructs it about which URI to contact to chase referrals.
If not present, the referral itself is parsed, and the protocol/host/port As opposed to what stated in \fBslapd-ldap\fP(5), only one URI
portions are used to establish a connection. can appear after this directive; all subsequent \fBslapd-ldap\fP(5)
directives prefixed by \fBchain-\fP refer to this specific instance
of a remote server.
.LP .LP
Directives for configuring the underlying ldap database may also Directives for configuring the underlying ldap database may also
be required, as shown here: be required, as shown in this example:
.LP .LP
.RS .RS
.nf .nf
chain-idassert-method "simple" overlay chain
chain-idassert-authcDN "cn=Auth,dc=example,dc=com" chain-rebind-as-user FALSE
chain-idassert-passwd "secret"
chain-idassert-mode "self" chain-uri "ldap://ldap1.example.com"
chain-rebind-as-user TRUE
chain-idassert-bind bindmethod="simple"
binddn="cn=Auth,dc=example,dc=com"
credentials="secret"
mode="self"
chain-uri "ldap://ldap2.example.com"
chain-idassert-bind bindmethod="simple"
binddn="cn=Auth,dc=example,dc=com"
credentials="secret"
mode="none"
.fi .fi
.RE .RE
.LP .LP
Any valid directives for the ldap database may be used; see Any valid directives for the ldap database may be used; see
.BR slapd-ldap (5) .BR slapd-ldap (5)
for details. for details.
Multiple occurrences of the \fBchain-uri\fP directive may appear,
to define multiple "trusted" URIs where operations with
\fIidentity assertion\fP are chained.
All URIs not listed in the configuration are chained anonymously.
All \fBslapd-ldap\fP(5) directives appearing before the first
occurrence of \fBchain-uri\fP are inherited by all URIs,
unless specifically overridden inside each URI configuration.
.SH FILES .SH FILES
.TP .TP
ETCDIR/slapd.conf ETCDIR/slapd.conf
@ -76,4 +128,4 @@ default slapd configuration file
.BR slapd\-ldap (5), .BR slapd\-ldap (5),
.BR slapd (8). .BR slapd (8).
.SH AUTHOR .SH AUTHOR
Originally implemented by Howard Chu. Originally implemented by Howard Chu; extended by Pierangelo Masarati.

@ -93,6 +93,23 @@ at response, it would cache entries that may be later "massaged"
by other databases and thus returned \fIafter\fP massaging the first by other databases and thus returned \fIafter\fP massaging the first
time, and \fIbefore\fP massaging when cached. time, and \fIbefore\fP massaging when cached.
.TP
There are some constraints:
all values must be positive;
.B <entry_limit>
must be less than or equal to
.BR <max_entries> ;
.B <numattrsets>
attribute sets SHOULD be defined by using the directive
.BR proxyattrset ;
all attribute sets SHOULD be referenced by (at least) one
.B proxytemplate
directive;
.LP .LP
The following adds a template with filter string \fB((&sn=)(givenName=))\fP The following adds a template with filter string \fB((&sn=)(givenName=))\fP
and attributes mail, postaladdress, telephonenumber and a TTL of 1 hour. and attributes mail, postaladdress, telephonenumber and a TTL of 1 hour.
@ -116,7 +133,52 @@ cachesize 100
.RE .RE
.LP .LP
Any valid directives for the chosen database type may be used. Any valid directives for the chosen database type may be used.
.SH CAVEATS
Caching data is prone to inconsistencies because updates on the remote server
will not be reflected in the response of the cache at least (and at most)
for the duration of the
.B proxytemplate
.BR TTL .
Another potential (and subtle) inconsistency may occur when data is retrieved
with different identities and specific per-identity access control
is enforced by the remote server.
If data was retrieved with an identity that collected only partial results
because of access rules enforcement on the remote server, other users
with different access privileges on the remote server will get different
results from the remote server and from the cache.
If those users have higher access privileges on the remote server, they will
get from the cache only a subset of the results they would get directly
from the remote server; but if they have lower access privileges, they will
get from the cache a superset of the results they would get directly
from the remote server.
Either occurrence may or may not be acceptable, based on the security policy
of the cache and of the remote server.
It is important to note that in this case the proxy is violating the security
of the remote server by disclosing to an identity data that was collected
by another identity.
For this reason, it is suggested that, when using
.BR back-ldap ,
proxy caching be used in conjunction with the
.I identity assertion
feature of
.BR slapd-ldap (5)
(see the
.B idassert-bind
and the
.B idassert-authz
statements), so that remote server interrogation occurs with a vanilla identity
that has some relatively high
.B search
and
.B read
access privileges, and the "real" access control is delegated to the proxy's ACLs.
Beware that since only the cached fraction of the real datum is available
to the cache, it may not be possible to enforce the same access rules that
are defined on the remote server.
When security is a concern, cached proxy access must be carefully tailored.
.SH FILES .SH FILES
.TP .TP
ETCDIR/slapd.conf ETCDIR/slapd.conf
default slapd configuration file default slapd configuration file

@ -104,19 +104,33 @@ rewrite_parse(
return -1; return -1;
} }
info->li_max_passes = atoi( argv[ 1 ] ); if ( lutil_atoi( &info->li_max_passes, argv[ 1 ] ) != 0 ) {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] unable to parse rewriteMaxPasses=\"%s\"\n",
fname, lineno, argv[ 1 ] );
return -1;
}
if ( info->li_max_passes <= 0 ) { if ( info->li_max_passes <= 0 ) {
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"[%s:%d] negative or null rewriteMaxPasses'\n", "[%s:%d] negative or null rewriteMaxPasses\n",
fname, lineno, 0 ); fname, lineno, 0 );
return -1;
} }
if ( argc > 2 ) { if ( argc > 2 ) {
info->li_max_passes_per_rule = atoi( argv[ 2 ] ); if ( lutil_atoi( &info->li_max_passes_per_rule, argv[ 2 ] ) != 0 ) {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] unable to parse rewriteMaxPassesPerRule=\"%s\"\n",
fname, lineno, argv[ 2 ] );
return -1;
}
if ( info->li_max_passes_per_rule <= 0 ) { if ( info->li_max_passes_per_rule <= 0 ) {
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"[%s:%d] negative or null rewriteMaxPassesPerRule'\n", "[%s:%d] negative or null rewriteMaxPassesPerRule\n",
fname, lineno, 0 ); fname, lineno, 0 );
return -1;
} }
} else { } else {

@ -696,7 +696,7 @@ aci_init( void )
&rc, &text, LDAP_SCHEMA_ALLOW_ALL ); &rc, &text, LDAP_SCHEMA_ALLOW_ALL );
if ( !at ) { if ( !at ) {
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"%s AttributeType load failed: %s %s\n", "aci_init: AttributeType \"%s\" parse failed: %s %s\n",
aci_at.name, ldap_scherr2str( rc ), text ); aci_at.name, ldap_scherr2str( rc ), text );
return rc; return rc;
} }
@ -704,9 +704,9 @@ aci_init( void )
rc = at_add( at, 0, &sat, &text ); rc = at_add( at, 0, &sat, &text );
if ( rc != LDAP_SUCCESS ) { if ( rc != LDAP_SUCCESS ) {
ldap_attributetype_free( at ); ldap_attributetype_free( at );
fprintf( stderr, "iMUX_monitor_schema_init: " Debug( LDAP_DEBUG_ANY,
"AttributeType load failed: %s %s\n", "aci_init: AttributeType \"%s\" load failed: %s %s\n",
scherr2str( rc ), text ); aci_at.name, scherr2str( rc ), text );
return rc; return rc;
} }
ldap_memfree( at ); ldap_memfree( at );
@ -715,7 +715,7 @@ aci_init( void )
aci_at.ad, &text ); aci_at.ad, &text );
if ( rc != LDAP_SUCCESS ) { if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"unable to find AttributeDescription " "aci_init: unable to find AttributeDescription "
"\"%s\": %d (%s)\n", "\"%s\": %d (%s)\n",
aci_at.name, rc, text ); aci_at.name, rc, text );
return 1; return 1;

@ -310,9 +310,10 @@ fe_access_allowed(
*/ */
be_orig = op->o_bd; be_orig = op->o_bd;
op->o_bd = select_backend( &op->o_req_ndn, 0, 0 );
if ( op->o_bd == NULL ) { if ( op->o_bd == NULL ) {
op->o_bd = frontendDB; op->o_bd = select_backend( &op->o_req_ndn, 0, 0 );
if ( op->o_bd == NULL )
op->o_bd = frontendDB;
} }
rc = slap_access_allowed( op, e, desc, val, access, state, maskp ); rc = slap_access_allowed( op, e, desc, val, access, state, maskp );
op->o_bd = be_orig; op->o_bd = be_orig;
@ -423,14 +424,10 @@ access_allowed_mask(
desc, val, access, state, &mask ); desc, val, access, state, &mask );
} else { } else {
BackendDB *be_orig = op->o_bd;
/* use default (but pass through frontend /* use default (but pass through frontend
* for global ACL overlays) */ * for global ACL overlays) */
op->o_bd = frontendDB;
ret = frontendDB->bd_info->bi_access_allowed( op, e, ret = frontendDB->bd_info->bi_access_allowed( op, e,
desc, val, access, state, &mask ); desc, val, access, state, &mask );
op->o_bd = be_orig;
} }
if ( !ret ) { if ( !ret ) {
@ -1603,12 +1600,9 @@ slap_acl_mask(
port = strrchr( ip.bv_val, ':' ); port = strrchr( ip.bv_val, ':' );
if ( port ) { if ( port ) {
char *next;
ip.bv_len = port - ip.bv_val; ip.bv_len = port - ip.bv_val;
++port; ++port;
port_number = strtol( port, &next, 10 ); if ( lutil_atoi( &port_number, port ) != 0 )
if ( next[0] != '\0' )
continue; continue;
} }

@ -325,7 +325,7 @@ parse_acl(
int pos ) int pos )
{ {
int i; int i;
char *left, *right, *style, *next; char *left, *right, *style;
struct berval bv; struct berval bv;
AccessControl *a; AccessControl *a;
Access *b; Access *b;
@ -776,10 +776,7 @@ parse_acl(
} else if ( strcasecmp( style, "level" ) == 0 ) } else if ( strcasecmp( style, "level" ) == 0 )
{ {
char *next; if ( lutil_atoi( &level, style_level ) != 0 ) {
level = strtol( style_level, &next, 10 );
if ( next[0] != '\0' ) {
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"%s: line %d: unable to parse level " "%s: line %d: unable to parse level "
"in \"level{n}\"\n", "in \"level{n}\"\n",
@ -1385,7 +1382,7 @@ parse_acl(
char *end = NULL; char *end = NULL;
b->a_peername_port = strtol( port, &end, 10 ); b->a_peername_port = strtol( port, &end, 10 );
if ( end[0] != '}' ) { if ( end == port || end[0] != '}' ) {
/* illegal port */ /* illegal port */
Debug( LDAP_DEBUG_ANY, "%s: line %d: " Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"illegal peername port specification " "illegal peername port specification "
@ -1700,8 +1697,7 @@ parse_acl(
return acl_usage(); return acl_usage();
} }
b->a_authz.sai_ssf = strtol( right, &next, 10 ); if ( lutil_atou( &b->a_authz.sai_ssf, right ) != 0 ) {
if ( next == NULL || next[0] != '\0' ) {
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"%s: line %d: unable to parse ssf value (%s).\n", "%s: line %d: unable to parse ssf value (%s).\n",
fname, lineno, right ); fname, lineno, right );
@ -1739,8 +1735,7 @@ parse_acl(
return acl_usage(); return acl_usage();
} }
b->a_authz.sai_transport_ssf = strtol( right, &next, 10 ); if ( lutil_atou( &b->a_authz.sai_transport_ssf, right ) != 0 ) {
if ( next == NULL || next[0] != '\0' ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: " Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"unable to parse transport_ssf value (%s).\n", "unable to parse transport_ssf value (%s).\n",
fname, lineno, right ); fname, lineno, right );
@ -1778,8 +1773,7 @@ parse_acl(
return acl_usage(); return acl_usage();
} }
b->a_authz.sai_tls_ssf = strtol( right, &next, 10 ); if ( lutil_atou( &b->a_authz.sai_tls_ssf, right ) != 0 ) {
if ( next == NULL || next[0] != '\0' ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: " Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"unable to parse tls_ssf value (%s).\n", "unable to parse tls_ssf value (%s).\n",
fname, lineno, right ); fname, lineno, right );
@ -1817,8 +1811,7 @@ parse_acl(
return acl_usage(); return acl_usage();
} }
b->a_authz.sai_sasl_ssf = strtol( right, &next, 10 ); if ( lutil_atou( &b->a_authz.sai_sasl_ssf, right ) != 0 ) {
if ( next == NULL || next[0] != '\0' ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: " Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"unable to parse sasl_ssf value (%s).\n", "unable to parse sasl_ssf value (%s).\n",
fname, lineno, right ); fname, lineno, right );

@ -345,14 +345,13 @@ at_insert(
const char **err ) const char **err )
{ {
struct aindexrec *air; struct aindexrec *air;
char **names; char **names = NULL;
if ( sat->sat_oid ) { if ( sat->sat_oid ) {
air = (struct aindexrec *) air = (struct aindexrec *)
ch_calloc( 1, sizeof(struct aindexrec) ); ch_calloc( 1, sizeof(struct aindexrec) );
air->air_name.bv_val = sat->sat_oid; ber_str2bv( sat->sat_oid, 0, 0, &air->air_name );
air->air_name.bv_len = strlen(sat->sat_oid);
air->air_at = sat; air->air_at = sat;
if ( avl_insert( &attr_index, (caddr_t) air, if ( avl_insert( &attr_index, (caddr_t) air,
attr_index_cmp, avl_dup_error ) ) attr_index_cmp, avl_dup_error ) )
@ -379,8 +378,7 @@ at_insert(
while ( *names ) { while ( *names ) {
air = (struct aindexrec *) air = (struct aindexrec *)
ch_calloc( 1, sizeof(struct aindexrec) ); ch_calloc( 1, sizeof(struct aindexrec) );
air->air_name.bv_val = *names; ber_str2bv( *names, 0, 0, &air->air_name );
air->air_name.bv_len = strlen(*names);
air->air_at = sat; air->air_at = sat;
if ( avl_insert( &attr_index, (caddr_t) air, if ( avl_insert( &attr_index, (caddr_t) air,
attr_index_cmp, avl_dup_error ) ) attr_index_cmp, avl_dup_error ) )
@ -396,6 +394,29 @@ at_insert(
ldap_memfree(air); ldap_memfree(air);
while ( names > sat->sat_names ) {
struct aindexrec tmpair;
names--;
ber_str2bv( *names, 0, 0, &tmpair.air_name );
tmpair.air_at = sat;
air = (struct aindexrec *)avl_delete( &attr_index,
(caddr_t)&tmpair, attr_index_cmp );
assert( air != NULL );
ldap_memfree( air );
}
if ( sat->sat_oid ) {
struct aindexrec tmpair;
ber_str2bv( sat->sat_oid, 0, 0, &tmpair.air_name );
tmpair.air_at = sat;
air = (struct aindexrec *)avl_delete( &attr_index,
(caddr_t)&tmpair, attr_index_cmp );
assert( air != NULL );
ldap_memfree( air );
}
return rc; return rc;
} }
/* FIX: temporal consistency check */ /* FIX: temporal consistency check */
@ -428,16 +449,17 @@ at_add(
AttributeType **rsat, AttributeType **rsat,
const char **err ) const char **err )
{ {
AttributeType *sat; AttributeType *sat = NULL;
MatchingRule *mr; MatchingRule *mr = NULL;
Syntax *syn; Syntax *syn = NULL;
int i; int i;
int code; int code = LDAP_SUCCESS;
char *cname; char *cname = NULL;
char *oid; char *oidm = NULL;
char *oidm = NULL;
if ( !OID_LEADCHAR( at->at_oid[0] )) { if ( !OID_LEADCHAR( at->at_oid[0] )) {
char *oid;
/* Expand OID macros */ /* Expand OID macros */
oid = oidm_find( at->at_oid ); oid = oidm_find( at->at_oid );
if ( !oid ) { if ( !oid ) {
@ -451,11 +473,14 @@ at_add(
} }
if ( at->at_syntax_oid && !OID_LEADCHAR( at->at_syntax_oid[0] )) { if ( at->at_syntax_oid && !OID_LEADCHAR( at->at_syntax_oid[0] )) {
char *oid;
/* Expand OID macros */ /* Expand OID macros */
oid = oidm_find( at->at_syntax_oid ); oid = oidm_find( at->at_syntax_oid );
if ( !oid ) { if ( !oid ) {
*err = at->at_syntax_oid; *err = at->at_syntax_oid;
return SLAP_SCHERR_OIDM; code = SLAP_SCHERR_OIDM;
goto error_return;
} }
if ( oid != at->at_syntax_oid ) { if ( oid != at->at_syntax_oid ) {
ldap_memfree( at->at_syntax_oid ); ldap_memfree( at->at_syntax_oid );
@ -469,7 +494,8 @@ at_add(
for( i=0; at->at_names[i]; i++ ) { for( i=0; at->at_names[i]; i++ ) {
if( !slap_valid_descr( at->at_names[i] ) ) { if( !slap_valid_descr( at->at_names[i] ) ) {
*err = at->at_names[i]; *err = at->at_names[i];
return SLAP_SCHERR_BAD_DESCR; code = SLAP_SCHERR_BAD_DESCR;
goto error_return;
} }
} }
@ -480,25 +506,29 @@ at_add(
} else { } else {
*err = ""; *err = "";
return SLAP_SCHERR_ATTR_INCOMPLETE; code = SLAP_SCHERR_ATTR_INCOMPLETE;
goto error_return;
} }
*err = cname; *err = cname;
if ( !at->at_usage && at->at_no_user_mod ) { if ( !at->at_usage && at->at_no_user_mod ) {
/* user attribute must be modifable */ /* user attribute must be modifable */
return SLAP_SCHERR_ATTR_BAD_USAGE; code = SLAP_SCHERR_ATTR_BAD_USAGE;
goto error_return;
} }
if ( at->at_collective ) { if ( at->at_collective ) {
if( at->at_usage ) { if( at->at_usage ) {
/* collective attributes cannot be operational */ /* collective attributes cannot be operational */
return SLAP_SCHERR_ATTR_BAD_USAGE; code = SLAP_SCHERR_ATTR_BAD_USAGE;
goto error_return;
} }
if( at->at_single_value ) { if( at->at_single_value ) {
/* collective attributes cannot be single-valued */ /* collective attributes cannot be single-valued */
return SLAP_SCHERR_ATTR_BAD_USAGE; code = SLAP_SCHERR_ATTR_BAD_USAGE;
goto error_return;
} }
} }

@ -484,10 +484,23 @@ bdb_cf_gen(ConfigArgs *c)
} }
switch( c->type ) { switch( c->type ) {
case BDB_CHKPT: case BDB_CHKPT: {
long l;
bdb->bi_txn_cp = 1; bdb->bi_txn_cp = 1;
bdb->bi_txn_cp_kbyte = strtol( c->argv[1], NULL, 0 ); if ( lutil_atolx( &l, c->argv[1], 0 ) != 0 ) {
bdb->bi_txn_cp_min = strtol( c->argv[2], NULL, 0 ); fprintf( stderr, "%s: "
"invalid kbyte \"%s\" in \"checkpoint\".\n",
c->log, c->argv[1] );
return 1;
}
bdb->bi_txn_cp_kbyte = l;
if ( lutil_atolx( &l, c->argv[2], 0 ) != 0 ) {
fprintf( stderr, "%s: "
"invalid minutes \"%s\" in \"checkpoint\".\n",
c->log, c->argv[2] );
return 1;
}
bdb->bi_txn_cp_min = l;
/* If we're in server mode and time-based checkpointing is enabled, /* If we're in server mode and time-based checkpointing is enabled,
* submit a task to perform periodic checkpoints. * submit a task to perform periodic checkpoints.
*/ */
@ -507,7 +520,7 @@ bdb_cf_gen(ConfigArgs *c)
LDAP_XSTRING(bdb_checkpoint), c->be->be_suffix[0].bv_val ); LDAP_XSTRING(bdb_checkpoint), c->be->be_suffix[0].bv_val );
} }
} }
break; } break;
case BDB_CONFIG: { case BDB_CONFIG: {
char *ptr = c->line; char *ptr = c->line;

@ -948,35 +948,38 @@ hdb_dn2idl_internal(
cx->data.ulen = BDB_IDL_UM_SIZE * sizeof(ID); cx->data.ulen = BDB_IDL_UM_SIZE * sizeof(ID);
cx->data.flags = DB_DBT_USERMEM; cx->data.flags = DB_DBT_USERMEM;
/* Fetch the rest of the IDs in a loop... */ if ( dkids > 1 ) {
while ( (cx->rc = cx->dbc->c_get( cx->dbc, &cx->key, &cx->data, /* Fetch the rest of the IDs in a loop... */
DB_MULTIPLE | DB_NEXT_DUP )) == 0 ) { while ( (cx->rc = cx->dbc->c_get( cx->dbc, &cx->key, &cx->data,
u_int8_t *j; DB_MULTIPLE | DB_NEXT_DUP )) == 0 ) {
size_t len; u_int8_t *j;
void *ptr; size_t len;
DB_MULTIPLE_INIT( ptr, &cx->data ); void *ptr;
while (ptr) { DB_MULTIPLE_INIT( ptr, &cx->data );
DB_MULTIPLE_NEXT( ptr, &cx->data, j, len ); while (ptr) {
if (j) { DB_MULTIPLE_NEXT( ptr, &cx->data, j, len );
EntryInfo *ei2; if (j) {
diskNode *d = (diskNode *)j; EntryInfo *ei2;
short nrlen; diskNode *d = (diskNode *)j;
short nrlen;
BDB_DISK2ID( j + len - sizeof(ID), &ei.bei_id ); BDB_DISK2ID( j + len - sizeof(ID), &ei.bei_id );
nrlen = ((d->nrdnlen[0] ^ 0x80) << 8) | d->nrdnlen[1]; nrlen = ((d->nrdnlen[0] ^ 0x80) << 8) | d->nrdnlen[1];
ei.bei_nrdn.bv_len = nrlen; ei.bei_nrdn.bv_len = nrlen;
/* nrdn/rdn are set in-place. /* nrdn/rdn are set in-place.
* hdb_cache_load will copy them as needed * hdb_cache_load will copy them as needed
*/ */
ei.bei_nrdn.bv_val = d->nrdn; ei.bei_nrdn.bv_val = d->nrdn;
ei.bei_rdn.bv_len = len - sizeof(diskNode) ei.bei_rdn.bv_len = len - sizeof(diskNode)
- ei.bei_nrdn.bv_len; - ei.bei_nrdn.bv_len;
ei.bei_rdn.bv_val = d->nrdn + ei.bei_nrdn.bv_len + 1; ei.bei_rdn.bv_val = d->nrdn + ei.bei_nrdn.bv_len + 1;
bdb_idl_append_one( cx->tmp, ei.bei_id ); bdb_idl_append_one( cx->tmp, ei.bei_id );
hdb_cache_load( cx->bdb, &ei, &ei2 ); hdb_cache_load( cx->bdb, &ei, &ei2 );
}
} }
} }
} }
cx->rc = cx->dbc->c_close( cx->dbc ); cx->rc = cx->dbc->c_close( cx->dbc );
done_one: done_one:
bdb_cache_entryinfo_lock( cx->ei ); bdb_cache_entryinfo_lock( cx->ei );

@ -978,7 +978,6 @@ inequality_candidates(
{ {
struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private; struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
DB *db; DB *db;
int i;
int rc; int rc;
slap_mask_t mask; slap_mask_t mask;
struct berval prefix = {0, NULL}; struct berval prefix = {0, NULL};
@ -1066,9 +1065,9 @@ inequality_candidates(
bdb_idl_union( ids, tmp ); bdb_idl_union( ids, tmp );
if( BDB_IDL_IS_ZERO( ids ) ) if( op->ors_limit && op->ors_limit->lms_s_unchecked != -1 &&
BDB_IDL_N( ids ) >= (unsigned) op->ors_limit->lms_s_unchecked )
break; break;
i++;
} }
ber_bvarray_free_x( keys, op->o_tmpmemctx ); ber_bvarray_free_x( keys, op->o_tmpmemctx );

@ -1311,7 +1311,7 @@ int bdb_idl_append_one( ID *ids, ID id )
*/ */
int bdb_idl_append( ID *a, ID *b ) int bdb_idl_append( ID *a, ID *b )
{ {
ID ida, idb, tmp; ID ida, idb, tmp, swap = 0;
if ( BDB_IDL_IS_ZERO( b ) ) { if ( BDB_IDL_IS_ZERO( b ) ) {
return 0; return 0;
@ -1333,6 +1333,7 @@ int bdb_idl_append( ID *a, ID *b )
} }
if ( b[0] > 1 && ida > idb ) { if ( b[0] > 1 && ida > idb ) {
swap = idb;
a[a[0]] = idb; a[a[0]] = idb;
b[b[0]] = ida; b[b[0]] = ida;
} }
@ -1351,6 +1352,9 @@ int bdb_idl_append( ID *a, ID *b )
AC_MEMCPY(a+a[0]+1, b+2, i * sizeof(ID)); AC_MEMCPY(a+a[0]+1, b+2, i * sizeof(ID));
a[0] += i; a[0] += i;
} }
if ( swap ) {
b[b[0]] = swap;
}
return 0; return 0;
} }

@ -81,6 +81,9 @@ bdb_db_init( BackendDB *be )
return 0; return 0;
} }
static int
bdb_db_close( BackendDB *be );
static int static int
bdb_db_open( BackendDB *be ) bdb_db_open( BackendDB *be )
{ {
@ -180,7 +183,7 @@ bdb_db_open( BackendDB *be )
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"bdb_db_open: db_env_create failed: %s (%d)\n", "bdb_db_open: db_env_create failed: %s (%d)\n",
db_strerror(rc), rc, 0 ); db_strerror(rc), rc, 0 );
return rc; goto fail;
} }
bdb->bi_dbenv->set_errpfx( bdb->bi_dbenv, be->be_suffix[0].bv_val ); bdb->bi_dbenv->set_errpfx( bdb->bi_dbenv, be->be_suffix[0].bv_val );
@ -198,7 +201,7 @@ bdb_db_open( BackendDB *be )
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"bdb_db_open: dbenv_set_flags failed: %s (%d)\n", "bdb_db_open: dbenv_set_flags failed: %s (%d)\n",
db_strerror(rc), rc, 0 ); db_strerror(rc), rc, 0 );
return rc; goto fail;
} }
} }
@ -248,7 +251,8 @@ bdb_db_open( BackendDB *be )
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"bdb_db_open: Database cannot be recovered. " "bdb_db_open: Database cannot be recovered. "
"Restore from backup!\n", 0, 0, 0); "Restore from backup!\n", 0, 0, 0);
return -1; rc = -1;
goto fail;
} }
/* We need to recover, and we had TXN support before: /* We need to recover, and we had TXN support before:
* Close this env, open a new one with recovery flags. * Close this env, open a new one with recovery flags.
@ -261,7 +265,7 @@ bdb_db_open( BackendDB *be )
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"bdb_db_open: db_env_create failed: %s (%d)\n", "bdb_db_open: db_env_create failed: %s (%d)\n",
db_strerror(rc), rc, 0 ); db_strerror(rc), rc, 0 );
return rc; goto fail;
} }
bdb->bi_dbenv->set_errpfx( bdb->bi_dbenv, bdb->bi_dbenv->set_errpfx( bdb->bi_dbenv,
be->be_suffix[0].bv_val ); be->be_suffix[0].bv_val );
@ -272,7 +276,7 @@ bdb_db_open( BackendDB *be )
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"bdb_db_open: recovery failed: %s (%d)\n", "bdb_db_open: recovery failed: %s (%d)\n",
db_strerror(rc), rc, 0 ); db_strerror(rc), rc, 0 );
return rc; goto fail;
} }
do_recover = 0; do_recover = 0;
} }
@ -285,7 +289,7 @@ bdb_db_open( BackendDB *be )
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"bdb_db_open: db_env_create failed: %s (%d)\n", "bdb_db_open: db_env_create failed: %s (%d)\n",
db_strerror(rc), rc, 0 ); db_strerror(rc), rc, 0 );
return rc; goto fail;
} }
bdb->bi_dbenv->remove( bdb->bi_dbenv, dbhome, 0 ); bdb->bi_dbenv->remove( bdb->bi_dbenv, dbhome, 0 );
bdb->bi_dbenv = NULL; bdb->bi_dbenv = NULL;
@ -297,7 +301,8 @@ bdb_db_open( BackendDB *be )
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"bdb_db_open: Database cannot be recovered. " "bdb_db_open: Database cannot be recovered. "
"Restore from backup!\n", 0, 0, 0); "Restore from backup!\n", 0, 0, 0);
return -1; rc = -1;
goto fail;
} }
/* Prev environment had no TXN support, close it */ /* Prev environment had no TXN support, close it */
if ( !flags_ok ) { if ( !flags_ok ) {
@ -321,7 +326,7 @@ bdb_db_open( BackendDB *be )
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"bdb_db_open: db_env_create failed: %s (%d)\n", "bdb_db_open: db_env_create failed: %s (%d)\n",
db_strerror(rc), rc, 0 ); db_strerror(rc), rc, 0 );
return rc; goto fail;
} }
bdb->bi_dbenv->set_errpfx( bdb->bi_dbenv, be->be_suffix[0].bv_val ); bdb->bi_dbenv->set_errpfx( bdb->bi_dbenv, be->be_suffix[0].bv_val );
@ -338,7 +343,7 @@ bdb_db_open( BackendDB *be )
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"bdb_db_open: dbenv_set_flags failed: %s (%d)\n", "bdb_db_open: dbenv_set_flags failed: %s (%d)\n",
db_strerror(rc), rc, 0 ); db_strerror(rc), rc, 0 );
return rc; goto fail;
} }
} }
} }
@ -375,7 +380,7 @@ bdb_db_open( BackendDB *be )
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"bdb_db_open: dbenv_open failed: %s (%d)\n", "bdb_db_open: dbenv_open failed: %s (%d)\n",
db_strerror(rc), rc, 0 ); db_strerror(rc), rc, 0 );
return rc; goto fail;
} }
} }
@ -383,7 +388,8 @@ bdb_db_open( BackendDB *be )
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"bdb_db_open: alock_recover failed\n", "bdb_db_open: alock_recover failed\n",
0, 0, 0 ); 0, 0, 0 );
return -1; rc = -1;
goto fail;
} }
#ifdef SLAP_ZONE_ALLOC #ifdef SLAP_ZONE_ALLOC
@ -422,7 +428,7 @@ bdb_db_open( BackendDB *be )
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"bdb_db_open: db_create(%s) failed: %s (%d)\n", "bdb_db_open: db_create(%s) failed: %s (%d)\n",
bdb->bi_dbenv_home, db_strerror(rc), rc ); bdb->bi_dbenv_home, db_strerror(rc), rc );
return rc; goto fail;
} }
if( i == BDB_ID2ENTRY ) { if( i == BDB_ID2ENTRY ) {
@ -483,7 +489,8 @@ bdb_db_open( BackendDB *be )
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"bdb_db_open: db_open(%s) failed: %s (%d)\n", "bdb_db_open: db_open(%s) failed: %s (%d)\n",
buf, db_strerror(rc), rc ); buf, db_strerror(rc), rc );
return rc; db->bdi_db->close( db->bdi_db, 0 );
goto fail;
} }
flags &= ~(DB_CREATE | DB_RDONLY); flags &= ~(DB_CREATE | DB_RDONLY);
@ -500,7 +507,7 @@ bdb_db_open( BackendDB *be )
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"bdb_db_open: last_id(%s) failed: %s (%d)\n", "bdb_db_open: last_id(%s) failed: %s (%d)\n",
bdb->bi_dbenv_home, db_strerror(rc), rc ); bdb->bi_dbenv_home, db_strerror(rc), rc );
return rc; goto fail;
} }
if ( !( slapMode & SLAP_TOOL_QUICK )) { if ( !( slapMode & SLAP_TOOL_QUICK )) {
@ -510,6 +517,10 @@ bdb_db_open( BackendDB *be )
bdb->bi_flags |= BDB_IS_OPEN; bdb->bi_flags |= BDB_IS_OPEN;
return 0; return 0;
fail:
bdb_db_close( be );
return rc;
} }
static int static int
@ -520,10 +531,6 @@ bdb_db_close( BackendDB *be )
struct bdb_db_info *db; struct bdb_db_info *db;
bdb_idl_cache_entry_t *entry, *next_entry; bdb_idl_cache_entry_t *entry, *next_entry;
/* backend_shutdown closes everything, even if not all were opened */
if ( !( bdb->bi_flags & BDB_IS_OPEN ))
return 0;
bdb->bi_flags &= ~BDB_IS_OPEN; bdb->bi_flags &= ~BDB_IS_OPEN;
ber_bvarray_free( bdb->bi_db_config ); ber_bvarray_free( bdb->bi_db_config );
@ -543,7 +550,6 @@ bdb_db_close( BackendDB *be )
bdb_cache_release_all (&bdb->bi_cache); bdb_cache_release_all (&bdb->bi_cache);
if ( bdb->bi_idl_cache_max_size ) { if ( bdb->bi_idl_cache_max_size ) {
ldap_pvt_thread_rdwr_wlock ( &bdb->bi_idl_tree_rwlock );
avl_free( bdb->bi_idl_tree, NULL ); avl_free( bdb->bi_idl_tree, NULL );
bdb->bi_idl_tree = NULL; bdb->bi_idl_tree = NULL;
entry = bdb->bi_idl_lru_head; entry = bdb->bi_idl_lru_head;
@ -556,7 +562,6 @@ bdb_db_close( BackendDB *be )
entry = next_entry; entry = next_entry;
} }
bdb->bi_idl_lru_head = bdb->bi_idl_lru_tail = NULL; bdb->bi_idl_lru_head = bdb->bi_idl_lru_tail = NULL;
ldap_pvt_thread_rdwr_wunlock ( &bdb->bi_idl_tree_rwlock );
} }
if ( !( slapMode & SLAP_TOOL_QUICK ) && bdb->bi_dbenv ) { if ( !( slapMode & SLAP_TOOL_QUICK ) && bdb->bi_dbenv ) {
@ -636,12 +641,8 @@ bdb_back_initialize(
LDAP_CONTROL_MANAGEDSAIT, LDAP_CONTROL_MANAGEDSAIT,
LDAP_CONTROL_NOOP, LDAP_CONTROL_NOOP,
LDAP_CONTROL_PAGEDRESULTS, LDAP_CONTROL_PAGEDRESULTS,
#ifdef LDAP_CONTROL_SUBENTRIES
LDAP_CONTROL_SUBENTRIES, LDAP_CONTROL_SUBENTRIES,
#endif
#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
LDAP_CONTROL_X_PERMISSIVE_MODIFY, LDAP_CONTROL_X_PERMISSIVE_MODIFY,
#endif
NULL NULL
}; };

@ -858,21 +858,6 @@ fetch_entry_retry:
if ( rs->sr_err == LDAP_COMPARE_TRUE ) { if ( rs->sr_err == LDAP_COMPARE_TRUE ) {
/* check size limit */ /* check size limit */
if ( --op->ors_slimit == -1 ) {
#ifdef SLAP_ZONE_ALLOC
slap_zn_runlock(bdb->bi_cache.c_zctx, e);
#endif
bdb_cache_return_entry_r( bdb->bi_dbenv,
&bdb->bi_cache, e, &lock );
e = NULL;
rs->sr_entry = NULL;
rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;
rs->sr_ref = rs->sr_v2ref;
send_ldap_result( op, rs );
rs->sr_err = LDAP_SUCCESS;
goto done;
}
if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) { if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) {
if ( rs->sr_nentries >= ((PagedResultsState *)op->o_pagedresults_state)->ps_size ) { if ( rs->sr_nentries >= ((PagedResultsState *)op->o_pagedresults_state)->ps_size ) {
#ifdef SLAP_ZONE_ALLOC #ifdef SLAP_ZONE_ALLOC
@ -889,20 +874,20 @@ fetch_entry_retry:
if (e) { if (e) {
/* safe default */ /* safe default */
int result = -1;
rs->sr_attrs = op->oq_search.rs_attrs; rs->sr_attrs = op->oq_search.rs_attrs;
rs->sr_operational_attrs = NULL; rs->sr_operational_attrs = NULL;
rs->sr_ctrls = NULL; rs->sr_ctrls = NULL;
rs->sr_flags = 0; rs->sr_flags = 0;
rs->sr_err = LDAP_SUCCESS; rs->sr_err = LDAP_SUCCESS;
result = send_search_entry( op, rs ); rs->sr_err = send_search_entry( op, rs );
switch (result) { switch ( rs->sr_err ) {
case 0: /* entry sent ok */ case LDAP_SUCCESS: /* entry sent ok */
break; break;
case 1: /* entry not sent */ default: /* entry not sent */
break; break;
case -1: /* connection closed */ case LDAP_UNAVAILABLE:
case LDAP_SIZELIMIT_EXCEEDED:
#ifdef SLAP_ZONE_ALLOC #ifdef SLAP_ZONE_ALLOC
slap_zn_runlock(bdb->bi_cache.c_zctx, e); slap_zn_runlock(bdb->bi_cache.c_zctx, e);
#endif #endif
@ -910,7 +895,14 @@ fetch_entry_retry:
&bdb->bi_cache, e, &lock); &bdb->bi_cache, e, &lock);
e = NULL; e = NULL;
rs->sr_entry = NULL; rs->sr_entry = NULL;
rs->sr_err = LDAP_OTHER; if ( rs->sr_err == LDAP_SIZELIMIT_EXCEEDED ) {
rs->sr_ref = rs->sr_v2ref;
send_ldap_result( op, rs );
rs->sr_err = LDAP_SUCCESS;
} else {
rs->sr_err = LDAP_OTHER;
}
goto done; goto done;
} }
} }

@ -93,7 +93,8 @@ int bdb_tool_entry_open(
} }
/* Set up for threaded slapindex */ /* Set up for threaded slapindex */
if (( slapMode & (SLAP_TOOL_QUICK|SLAP_TOOL_READONLY)) == SLAP_TOOL_QUICK) { if (( slapMode & (SLAP_TOOL_QUICK|SLAP_TOOL_READONLY)) == SLAP_TOOL_QUICK
&& bdb->bi_nattrs ) {
if ( !bdb_tool_info ) { if ( !bdb_tool_info ) {
int i; int i;
ldap_pvt_thread_mutex_init( &bdb_tool_index_mutex ); ldap_pvt_thread_mutex_init( &bdb_tool_index_mutex );

@ -36,9 +36,9 @@ ldap_back_add(
Operation *op, Operation *op,
SlapReply *rs ) SlapReply *rs )
{ {
struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
struct ldapconn *lc; ldapconn_t *lc;
int i = 0, int i = 0,
j = 0; j = 0;
Attribute *a; Attribute *a;
@ -103,10 +103,10 @@ retry:
rs->sr_err = ldap_add_ext( lc->lc_ld, op->o_req_dn.bv_val, attrs, rs->sr_err = ldap_add_ext( lc->lc_ld, op->o_req_dn.bv_val, attrs,
ctrls, NULL, &msgid ); ctrls, NULL, &msgid );
rs->sr_err = ldap_back_op_result( lc, op, rs, msgid, rs->sr_err = ldap_back_op_result( lc, op, rs, msgid,
li->timeout[ LDAP_BACK_OP_ADD ], LDAP_BACK_SENDRESULT ); li->li_timeout[ LDAP_BACK_OP_ADD ], LDAP_BACK_SENDRESULT );
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) { if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
do_retry = 0; do_retry = 0;
if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
goto retry; goto retry;
} }
} }

@ -26,7 +26,7 @@
LDAP_BEGIN_DECL LDAP_BEGIN_DECL
struct ldapconn { typedef struct ldapconn_t {
Connection *lc_conn; Connection *lc_conn;
#define LDAP_BACK_PCONN ((void *)0x0) #define LDAP_BACK_PCONN ((void *)0x0)
#define LDAP_BACK_PCONN_TLS ((void *)0x1) #define LDAP_BACK_PCONN_TLS ((void *)0x1)
@ -79,7 +79,7 @@ struct ldapconn {
unsigned lc_refcnt; unsigned lc_refcnt;
unsigned lc_flags; unsigned lc_flags;
}; } ldapconn_t;
/* /*
* identity assertion modes * identity assertion modes
@ -104,50 +104,58 @@ enum {
LDAP_BACK_OP_LAST LDAP_BACK_OP_LAST
}; };
struct ldapinfo { typedef struct ldap_avl_info_t {
char *url; ldap_pvt_thread_mutex_t lai_mutex;
LDAPURLDesc *lud; Avlnode *lai_tree;
} ldap_avl_info_t;
slap_bindconf acl_sb; typedef struct ldapinfo_t {
#define acl_authcID acl_sb.sb_authcId /* li_uri: the string that goes into ldap_initialize()
#define acl_authcDN acl_sb.sb_binddn * TODO: use li_acl.sb_uri instead */
#define acl_passwd acl_sb.sb_cred char *li_uri;
#define acl_authzID acl_sb.sb_authzId /* li_bvuri: an array of each single URI that is equivalent;
#define acl_authmethod acl_sb.sb_method * to be checked for the presence of a certain item */
#define acl_sasl_mech acl_sb.sb_saslmech BerVarray li_bvuri;
#define acl_sasl_realm acl_sb.sb_realm
#define acl_secprops acl_sb.sb_secprops slap_bindconf li_acl;
#define li_acl_authcID li_acl.sb_authcId
#define li_acl_authcDN li_acl.sb_binddn
#define li_acl_passwd li_acl.sb_cred
#define li_acl_authzID li_acl.sb_authzId
#define li_acl_authmethod li_acl.sb_method
#define li_acl_sasl_mech li_acl.sb_saslmech
#define li_acl_sasl_realm li_acl.sb_realm
#define li_acl_secprops li_acl.sb_secprops
/* ID assert stuff */ /* ID assert stuff */
int idassert_mode; int li_idassert_mode;
slap_bindconf idassert_sb; slap_bindconf li_idassert;
#define idassert_authcID idassert_sb.sb_authcId #define li_idassert_authcID li_idassert.sb_authcId
#define idassert_authcDN idassert_sb.sb_binddn #define li_idassert_authcDN li_idassert.sb_binddn
#define idassert_passwd idassert_sb.sb_cred #define li_idassert_passwd li_idassert.sb_cred
#define idassert_authzID idassert_sb.sb_authzId #define li_idassert_authzID li_idassert.sb_authzId
#define idassert_authmethod idassert_sb.sb_method #define li_idassert_authmethod li_idassert.sb_method
#define idassert_sasl_mech idassert_sb.sb_saslmech #define li_idassert_sasl_mech li_idassert.sb_saslmech
#define idassert_sasl_realm idassert_sb.sb_realm #define li_idassert_sasl_realm li_idassert.sb_realm
#define idassert_secprops idassert_sb.sb_secprops #define li_idassert_secprops li_idassert.sb_secprops
unsigned idassert_flags; unsigned li_idassert_flags;
#define LDAP_BACK_AUTH_NONE 0x00U #define LDAP_BACK_AUTH_NONE 0x00U
#define LDAP_BACK_AUTH_NATIVE_AUTHZ 0x01U #define LDAP_BACK_AUTH_NATIVE_AUTHZ 0x01U
#define LDAP_BACK_AUTH_OVERRIDE 0x02U #define LDAP_BACK_AUTH_OVERRIDE 0x02U
#define LDAP_BACK_AUTH_PRESCRIPTIVE 0x04U #define LDAP_BACK_AUTH_PRESCRIPTIVE 0x04U
BerVarray idassert_authz; BerVarray li_idassert_authz;
/* end of ID assert stuff */ /* end of ID assert stuff */
int nretries; int li_nretries;
#define LDAP_BACK_RETRY_UNDEFINED (-2) #define LDAP_BACK_RETRY_UNDEFINED (-2)
#define LDAP_BACK_RETRY_FOREVER (-1) #define LDAP_BACK_RETRY_FOREVER (-1)
#define LDAP_BACK_RETRY_NEVER (0) #define LDAP_BACK_RETRY_NEVER (0)
#define LDAP_BACK_RETRY_DEFAULT (3) #define LDAP_BACK_RETRY_DEFAULT (3)
ldap_pvt_thread_mutex_t conn_mutex; unsigned li_flags;
unsigned flags;
#define LDAP_BACK_F_NONE 0x00U #define LDAP_BACK_F_NONE 0x00U
#define LDAP_BACK_F_SAVECRED 0x01U #define LDAP_BACK_F_SAVECRED 0x01U
#define LDAP_BACK_F_USE_TLS 0x02U #define LDAP_BACK_F_USE_TLS 0x02U
@ -163,23 +171,20 @@ struct ldapinfo {
#define LDAP_BACK_F_SUPPORT_T_F_DISCOVER 0x40U #define LDAP_BACK_F_SUPPORT_T_F_DISCOVER 0x40U
#define LDAP_BACK_F_SUPPORT_T_F_MASK (LDAP_BACK_F_SUPPORT_T_F|LDAP_BACK_F_SUPPORT_T_F_DISCOVER) #define LDAP_BACK_F_SUPPORT_T_F_MASK (LDAP_BACK_F_SUPPORT_T_F|LDAP_BACK_F_SUPPORT_T_F_DISCOVER)
#define LDAP_BACK_SAVECRED(li) ( (li)->flags & LDAP_BACK_F_SAVECRED ) #define LDAP_BACK_ISSET(li,f) ( ( (li)->li_flags & (f) ) == (f) )
#define LDAP_BACK_USE_TLS(li) ( (li)->flags & LDAP_BACK_F_USE_TLS ) #define LDAP_BACK_SAVECRED(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_SAVECRED )
#define LDAP_BACK_PROPAGATE_TLS(li) ( (li)->flags & LDAP_BACK_F_PROPAGATE_TLS ) #define LDAP_BACK_USE_TLS(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_USE_TLS )
#define LDAP_BACK_TLS_CRITICAL(li) ( (li)->flags & LDAP_BACK_F_TLS_CRITICAL ) #define LDAP_BACK_PROPAGATE_TLS(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_PROPAGATE_TLS )
#define LDAP_BACK_CHASE_REFERRALS(li) ( (li)->flags & LDAP_BACK_F_CHASE_REFERRALS ) #define LDAP_BACK_TLS_CRITICAL(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_TLS_CRITICAL )
#define LDAP_BACK_CHASE_REFERRALS(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_CHASE_REFERRALS )
#define LDAP_BACK_PROXY_WHOAMI(li) LDAP_BACK_ISSET( (li), LDAP_BACK_F_PROXY_WHOAMI )
int version; int li_version;
Avlnode *conntree; ldap_avl_info_t li_conninfo;
#if 0 time_t li_timeout[ LDAP_BACK_OP_LAST ];
/* FIXME: automatic rwm instantiation removed */ } ldapinfo_t;
int rwm_started;
#endif
time_t timeout[ LDAP_BACK_OP_LAST ];
};
typedef enum ldap_back_send_t { typedef enum ldap_back_send_t {
LDAP_BACK_DONTSEND = 0x00, LDAP_BACK_DONTSEND = 0x00,

@ -42,16 +42,16 @@ static LDAP_REBIND_PROC ldap_back_default_rebind;
LDAP_REBIND_PROC *ldap_back_rebind_f = ldap_back_default_rebind; LDAP_REBIND_PROC *ldap_back_rebind_f = ldap_back_default_rebind;
static int static int
ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs ); ldap_back_proxy_authz_bind( ldapconn_t *lc, Operation *op, SlapReply *rs );
static int static int
ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok ); ldap_back_prepare_conn( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok );
int int
ldap_back_bind( Operation *op, SlapReply *rs ) ldap_back_bind( Operation *op, SlapReply *rs )
{ {
struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private; ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private;
struct ldapconn *lc; ldapconn_t *lc;
int rc = 0; int rc = 0;
ber_int_t msgid; ber_int_t msgid;
@ -79,7 +79,7 @@ ldap_back_bind( Operation *op, SlapReply *rs )
* purpose, a successful bind is followed by a * purpose, a successful bind is followed by a
* bind with the configured identity assertion */ * bind with the configured identity assertion */
/* NOTE: use with care */ /* NOTE: use with care */
if ( li->idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) { if ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) {
ldap_back_proxy_authz_bind( lc, op, rs ); ldap_back_proxy_authz_bind( lc, op, rs );
if ( !LDAP_BACK_CONN_ISBOUND( lc ) ) { if ( !LDAP_BACK_CONN_ISBOUND( lc ) ) {
rc = 1; rc = 1;
@ -109,22 +109,22 @@ done:;
/* wait for all other ops to release the connection */ /* wait for all other ops to release the connection */
retry_lock:; retry_lock:;
ldap_pvt_thread_mutex_lock( &li->conn_mutex ); ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
if ( lc->lc_refcnt > 1 ) { if ( lc->lc_refcnt > 1 ) {
ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
ldap_pvt_thread_yield(); ldap_pvt_thread_yield();
goto retry_lock; goto retry_lock;
} }
assert( lc->lc_refcnt == 1 ); assert( lc->lc_refcnt == 1 );
lc = avl_delete( &li->conntree, (caddr_t)lc, lc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc,
ldap_back_conn_cmp ); ldap_back_conn_cmp );
assert( lc != NULL ); assert( lc != NULL );
ber_bvreplace( &lc->lc_local_ndn, &op->o_req_ndn ); ber_bvreplace( &lc->lc_local_ndn, &op->o_req_ndn );
lerr = avl_insert( &li->conntree, (caddr_t)lc, lerr = avl_insert( &li->li_conninfo.lai_tree, (caddr_t)lc,
ldap_back_conn_cmp, ldap_back_conn_dup ); ldap_back_conn_cmp, ldap_back_conn_dup );
ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
if ( lerr == -1 ) { if ( lerr == -1 ) {
/* we can do this because lc_refcnt == 1 */ /* we can do this because lc_refcnt == 1 */
ldap_back_conn_free( lc ); ldap_back_conn_free( lc );
@ -142,14 +142,14 @@ retry_lock:;
/* /*
* ldap_back_conn_cmp * ldap_back_conn_cmp
* *
* compares two struct ldapconn based on the value of the conn pointer; * compares two ldapconn_t based on the value of the conn pointer;
* used by avl stuff * used by avl stuff
*/ */
int int
ldap_back_conn_cmp( const void *c1, const void *c2 ) ldap_back_conn_cmp( const void *c1, const void *c2 )
{ {
const struct ldapconn *lc1 = (const struct ldapconn *)c1; const ldapconn_t *lc1 = (const ldapconn_t *)c1;
const struct ldapconn *lc2 = (const struct ldapconn *)c2; const ldapconn_t *lc2 = (const ldapconn_t *)c2;
int rc; int rc;
/* If local DNs don't match, it is definitely not a match */ /* If local DNs don't match, it is definitely not a match */
@ -167,14 +167,14 @@ ldap_back_conn_cmp( const void *c1, const void *c2 )
/* /*
* ldap_back_conn_dup * ldap_back_conn_dup
* *
* returns -1 in case a duplicate struct ldapconn has been inserted; * returns -1 in case a duplicate ldapconn_t has been inserted;
* used by avl stuff * used by avl stuff
*/ */
int int
ldap_back_conn_dup( void *c1, void *c2 ) ldap_back_conn_dup( void *c1, void *c2 )
{ {
struct ldapconn *lc1 = (struct ldapconn *)c1; ldapconn_t *lc1 = (ldapconn_t *)c1;
struct ldapconn *lc2 = (struct ldapconn *)c2; ldapconn_t *lc2 = (ldapconn_t *)c2;
/* Cannot have more than one shared session with same DN */ /* Cannot have more than one shared session with same DN */
if ( dn_match( &lc1->lc_local_ndn, &lc2->lc_local_ndn ) && if ( dn_match( &lc1->lc_local_ndn, &lc2->lc_local_ndn ) &&
@ -190,8 +190,8 @@ ldap_back_conn_dup( void *c1, void *c2 )
static void static void
ravl_print( Avlnode *root, int depth ) ravl_print( Avlnode *root, int depth )
{ {
int i; int i;
struct ldapconn *lc; ldapconn_t *lc;
if ( root == 0 ) { if ( root == 0 ) {
return; return;
@ -227,22 +227,26 @@ myprint( Avlnode *root )
#endif /* PRINT_CONNTREE */ #endif /* PRINT_CONNTREE */
int int
ldap_back_freeconn( Operation *op, struct ldapconn *lc ) ldap_back_freeconn( Operation *op, ldapconn_t *lc, int dolock )
{ {
struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private; ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private;
ldap_pvt_thread_mutex_lock( &li->conn_mutex ); if ( dolock ) {
ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
}
assert( lc->lc_refcnt > 0 ); assert( lc->lc_refcnt > 0 );
if ( --lc->lc_refcnt == 0 ) { if ( --lc->lc_refcnt == 0 ) {
lc = avl_delete( &li->conntree, (caddr_t)lc, lc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)lc,
ldap_back_conn_cmp ); ldap_back_conn_cmp );
assert( lc != NULL ); assert( lc != NULL );
ldap_back_conn_free( (void *)lc ); ldap_back_conn_free( (void *)lc );
} }
ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); if ( dolock ) {
ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
}
return 0; return 0;
} }
@ -259,10 +263,10 @@ ldap_back_start_tls(
const char **text ) const char **text )
{ {
int rc = LDAP_SUCCESS; int rc = LDAP_SUCCESS;
struct ldapinfo dummy; ldapinfo_t dummy;
/* this is ridiculous... */ /* this is ridiculous... */
dummy.flags = flags; dummy.li_flags = flags;
/* start TLS ("tls-[try-]{start,propagate}" statements) */ /* start TLS ("tls-[try-]{start,propagate}" statements) */
if ( ( LDAP_BACK_USE_TLS( &dummy ) || ( *is_tls && LDAP_BACK_PROPAGATE_TLS( &dummy ) ) ) if ( ( LDAP_BACK_USE_TLS( &dummy ) || ( *is_tls && LDAP_BACK_PROPAGATE_TLS( &dummy ) ) )
@ -392,9 +396,9 @@ retry:;
#endif /* HAVE_TLS */ #endif /* HAVE_TLS */
static int static int
ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok ) ldap_back_prepare_conn( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok )
{ {
struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
int vers = op->o_protocol; int vers = op->o_protocol;
LDAP *ld = NULL; LDAP *ld = NULL;
#ifdef HAVE_TLS #ifdef HAVE_TLS
@ -403,7 +407,7 @@ ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, lda
assert( lcp != NULL ); assert( lcp != NULL );
rs->sr_err = ldap_initialize( &ld, li->url ); rs->sr_err = ldap_initialize( &ld, li->li_uri );
if ( rs->sr_err != LDAP_SUCCESS ) { if ( rs->sr_err != LDAP_SUCCESS ) {
goto error_return; goto error_return;
} }
@ -420,7 +424,7 @@ ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, lda
#ifdef HAVE_TLS #ifdef HAVE_TLS
rs->sr_err = ldap_back_start_tls( ld, op->o_protocol, &is_tls, rs->sr_err = ldap_back_start_tls( ld, op->o_protocol, &is_tls,
li->url, li->flags, li->nretries, &rs->sr_text ); li->li_uri, li->li_flags, li->li_nretries, &rs->sr_text );
if ( rs->sr_err != LDAP_SUCCESS ) { if ( rs->sr_err != LDAP_SUCCESS ) {
ldap_unbind_ext( ld, NULL, NULL ); ldap_unbind_ext( ld, NULL, NULL );
goto error_return; goto error_return;
@ -428,8 +432,8 @@ ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, lda
#endif /* HAVE_TLS */ #endif /* HAVE_TLS */
if ( *lcp == NULL ) { if ( *lcp == NULL ) {
*lcp = (struct ldapconn *)ch_calloc( 1, sizeof( struct ldapconn ) ); *lcp = (ldapconn_t *)ch_calloc( 1, sizeof( ldapconn_t ) );
(*lcp)->lc_flags= li->flags; (*lcp)->lc_flags= li->li_flags;
} }
(*lcp)->lc_ld = ld; (*lcp)->lc_ld = ld;
(*lcp)->lc_refcnt = 1; (*lcp)->lc_refcnt = 1;
@ -456,11 +460,11 @@ error_return:;
return rs->sr_err; return rs->sr_err;
} }
struct ldapconn * ldapconn_t *
ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok ) ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
{ {
struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
struct ldapconn *lc, ldapconn_t *lc,
lc_curr = { 0 }; lc_curr = { 0 };
int refcnt = 1; int refcnt = 1;
@ -482,14 +486,14 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
} }
/* Searches for a ldapconn in the avl tree */ /* Searches for a ldapconn in the avl tree */
ldap_pvt_thread_mutex_lock( &li->conn_mutex ); ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
lc = (struct ldapconn *)avl_find( li->conntree, lc = (ldapconn_t *)avl_find( li->li_conninfo.lai_tree,
(caddr_t)&lc_curr, ldap_back_conn_cmp ); (caddr_t)&lc_curr, ldap_back_conn_cmp );
if ( lc != NULL ) { if ( lc != NULL ) {
refcnt = ++lc->lc_refcnt; refcnt = ++lc->lc_refcnt;
} }
ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
/* Looks like we didn't get a bind. Open a new session... */ /* Looks like we didn't get a bind. Open a new session... */
if ( lc == NULL ) { if ( lc == NULL ) {
@ -501,8 +505,8 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
ber_dupbv( &lc->lc_local_ndn, &lc_curr.lc_local_ndn ); ber_dupbv( &lc->lc_local_ndn, &lc_curr.lc_local_ndn );
if ( LDAP_BACK_CONN_ISPRIV( &lc_curr ) ) { if ( LDAP_BACK_CONN_ISPRIV( &lc_curr ) ) {
ber_dupbv( &lc->lc_cred, &li->acl_passwd ); ber_dupbv( &lc->lc_cred, &li->li_acl_passwd );
ber_dupbv( &lc->lc_bound_ndn, &li->acl_authcDN ); ber_dupbv( &lc->lc_bound_ndn, &li->li_acl_authcDN );
LDAP_BACK_CONN_ISPRIV_SET( lc ); LDAP_BACK_CONN_ISPRIV_SET( lc );
} else { } else {
@ -527,18 +531,18 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
if ( lc->lc_conn == LDAP_BACK_PCONN_TLS if ( lc->lc_conn == LDAP_BACK_PCONN_TLS
&& !ldap_tls_inplace( lc->lc_ld ) ) && !ldap_tls_inplace( lc->lc_ld ) )
{ {
struct ldapconn *tmplc; ldapconn_t *tmplc;
lc_curr.lc_conn = LDAP_BACK_PCONN; lc_curr.lc_conn = LDAP_BACK_PCONN;
ldap_pvt_thread_mutex_lock( &li->conn_mutex ); ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
tmplc = (struct ldapconn *)avl_find( li->conntree, tmplc = (ldapconn_t *)avl_find( li->li_conninfo.lai_tree,
(caddr_t)&lc_curr, ldap_back_conn_cmp ); (caddr_t)&lc_curr, ldap_back_conn_cmp );
if ( tmplc != NULL ) { if ( tmplc != NULL ) {
refcnt = ++tmplc->lc_refcnt; refcnt = ++tmplc->lc_refcnt;
ldap_back_conn_free( lc ); ldap_back_conn_free( lc );
lc = tmplc; lc = tmplc;
} }
ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
if ( tmplc != NULL ) { if ( tmplc != NULL ) {
goto done; goto done;
@ -549,17 +553,17 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
LDAP_BACK_CONN_ISBOUND_CLEAR( lc ); LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
/* Inserts the newly created ldapconn in the avl tree */ /* Inserts the newly created ldapconn in the avl tree */
ldap_pvt_thread_mutex_lock( &li->conn_mutex ); ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
assert( lc->lc_refcnt == 1 ); assert( lc->lc_refcnt == 1 );
rs->sr_err = avl_insert( &li->conntree, (caddr_t)lc, rs->sr_err = avl_insert( &li->li_conninfo.lai_tree, (caddr_t)lc,
ldap_back_conn_cmp, ldap_back_conn_dup ); ldap_back_conn_cmp, ldap_back_conn_dup );
#if PRINT_CONNTREE > 0 #if PRINT_CONNTREE > 0
myprint( li->conntree ); myprint( li->li_conninfo.lai_tree );
#endif /* PRINT_CONNTREE */ #endif /* PRINT_CONNTREE */
ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
Debug( LDAP_DEBUG_TRACE, Debug( LDAP_DEBUG_TRACE,
"=>ldap_back_getconn: conn %p inserted (refcnt=%u)\n", "=>ldap_back_getconn: conn %p inserted (refcnt=%u)\n",
@ -590,14 +594,14 @@ void
ldap_back_release_conn( ldap_back_release_conn(
Operation *op, Operation *op,
SlapReply *rs, SlapReply *rs,
struct ldapconn *lc ) ldapconn_t *lc )
{ {
struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
ldap_pvt_thread_mutex_lock( &li->conn_mutex ); ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
assert( lc->lc_refcnt > 0 ); assert( lc->lc_refcnt > 0 );
lc->lc_refcnt--; lc->lc_refcnt--;
ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
} }
/* /*
@ -607,18 +611,18 @@ ldap_back_release_conn(
* it from all the callers, and I made the function return the flag, so * it from all the callers, and I made the function return the flag, so
* it can be used to simplify the check. * it can be used to simplify the check.
* *
* Note: dolock indicates whether li->conn_mutex must be locked or not * Note: dolock indicates whether li->li_conninfo.lai_mutex must be locked or not
*/ */
static int static int
ldap_back_dobind_int( ldap_back_dobind_int(
struct ldapconn *lc, ldapconn_t *lc,
Operation *op, Operation *op,
SlapReply *rs, SlapReply *rs,
ldap_back_send_t sendok, ldap_back_send_t sendok,
int retries, int retries,
int dolock ) int dolock )
{ {
struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
int rc = LDAP_BACK_CONN_ISBOUND( lc ); int rc = LDAP_BACK_CONN_ISBOUND( lc );
ber_int_t msgid; ber_int_t msgid;
@ -654,7 +658,7 @@ ldap_back_dobind_int(
if ( op->o_conn != NULL && if ( op->o_conn != NULL &&
!op->o_do_not_cache && !op->o_do_not_cache &&
( BER_BVISNULL( &lc->lc_bound_ndn ) || ( BER_BVISNULL( &lc->lc_bound_ndn ) ||
( li->idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) ) ( li->li_idassert_flags & LDAP_BACK_AUTH_OVERRIDE ) ) )
{ {
(void)ldap_back_proxy_authz_bind( lc, op, rs ); (void)ldap_back_proxy_authz_bind( lc, op, rs );
goto done; goto done;
@ -662,32 +666,32 @@ ldap_back_dobind_int(
#ifdef HAVE_CYRUS_SASL #ifdef HAVE_CYRUS_SASL
if ( LDAP_BACK_CONN_ISPRIV( lc ) if ( LDAP_BACK_CONN_ISPRIV( lc )
&& li->acl_authmethod == LDAP_AUTH_SASL ) && li->li_acl_authmethod == LDAP_AUTH_SASL )
{ {
void *defaults = NULL; void *defaults = NULL;
if ( li->acl_secprops != NULL ) { if ( li->li_acl_secprops != NULL ) {
rc = ldap_set_option( lc->lc_ld, rc = ldap_set_option( lc->lc_ld,
LDAP_OPT_X_SASL_SECPROPS, li->acl_secprops); LDAP_OPT_X_SASL_SECPROPS, li->li_acl_secprops);
if ( rc != LDAP_OPT_SUCCESS ) { if ( rc != LDAP_OPT_SUCCESS ) {
Debug( LDAP_DEBUG_ANY, "Error: ldap_set_option " Debug( LDAP_DEBUG_ANY, "Error: ldap_set_option "
"(%s,SECPROPS,\"%s\") failed!\n", "(%s,SECPROPS,\"%s\") failed!\n",
li->url, li->acl_secprops, 0 ); li->li_uri, li->li_acl_secprops, 0 );
goto done; goto done;
} }
} }
defaults = lutil_sasl_defaults( lc->lc_ld, defaults = lutil_sasl_defaults( lc->lc_ld,
li->acl_sasl_mech.bv_val, li->li_acl_sasl_mech.bv_val,
li->acl_sasl_realm.bv_val, li->li_acl_sasl_realm.bv_val,
li->acl_authcID.bv_val, li->li_acl_authcID.bv_val,
li->acl_passwd.bv_val, li->li_acl_passwd.bv_val,
NULL ); NULL );
rs->sr_err = ldap_sasl_interactive_bind_s( lc->lc_ld, rs->sr_err = ldap_sasl_interactive_bind_s( lc->lc_ld,
li->acl_authcDN.bv_val, li->li_acl_authcDN.bv_val,
li->acl_sasl_mech.bv_val, NULL, NULL, li->li_acl_sasl_mech.bv_val, NULL, NULL,
LDAP_SASL_QUIET, lutil_sasl_interact, LDAP_SASL_QUIET, lutil_sasl_interact,
defaults ); defaults );
@ -714,7 +718,7 @@ retry:;
if ( rs->sr_err == LDAP_SERVER_DOWN ) { if ( rs->sr_err == LDAP_SERVER_DOWN ) {
if ( retries != LDAP_BACK_RETRY_NEVER ) { if ( retries != LDAP_BACK_RETRY_NEVER ) {
if ( dolock ) { if ( dolock ) {
ldap_pvt_thread_mutex_lock( &li->conn_mutex ); ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
} }
assert( lc->lc_refcnt > 0 ); assert( lc->lc_refcnt > 0 );
@ -726,7 +730,7 @@ retry:;
rs->sr_err = ldap_back_prepare_conn( &lc, op, rs, sendok ); rs->sr_err = ldap_back_prepare_conn( &lc, op, rs, sendok );
} }
if ( dolock ) { if ( dolock ) {
ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
} }
if ( rs->sr_err == LDAP_SUCCESS ) { if ( rs->sr_err == LDAP_SUCCESS ) {
if ( retries > 0 ) { if ( retries > 0 ) {
@ -736,7 +740,7 @@ retry:;
} }
} }
ldap_back_freeconn( op, lc ); ldap_back_freeconn( op, lc, dolock );
rs->sr_err = slap_map_api2result( rs ); rs->sr_err = slap_map_api2result( rs );
return 0; return 0;
@ -757,11 +761,11 @@ done:;
} }
int int
ldap_back_dobind( struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok ) ldap_back_dobind( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok )
{ {
struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
return ldap_back_dobind_int( lc, op, rs, sendok, li->nretries, 1 ); return ldap_back_dobind_int( lc, op, rs, sendok, li->li_nretries, 1 );
} }
/* /*
@ -774,7 +778,7 @@ static int
ldap_back_default_rebind( LDAP *ld, LDAP_CONST char *url, ber_tag_t request, ldap_back_default_rebind( LDAP *ld, LDAP_CONST char *url, ber_tag_t request,
ber_int_t msgid, void *params ) ber_int_t msgid, void *params )
{ {
struct ldapconn *lc = (struct ldapconn *)params; ldapconn_t *lc = (ldapconn_t *)params;
#ifdef HAVE_TLS #ifdef HAVE_TLS
/* ... otherwise we couldn't get here */ /* ... otherwise we couldn't get here */
@ -801,7 +805,7 @@ ldap_back_default_rebind( LDAP *ld, LDAP_CONST char *url, ber_tag_t request,
int int
ldap_back_op_result( ldap_back_op_result(
struct ldapconn *lc, ldapconn_t *lc,
Operation *op, Operation *op,
SlapReply *rs, SlapReply *rs,
ber_int_t msgid, ber_int_t msgid,
@ -862,6 +866,16 @@ retry:;
default: default:
rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err, rc = ldap_parse_result( lc->lc_ld, res, &rs->sr_err,
&match, &text, NULL, NULL, 1 ); &match, &text, NULL, NULL, 1 );
#ifndef LDAP_NULL_IS_NULL
if ( match != NULL && match[ 0 ] == '\0' ) {
ldap_memfree( match );
match = NULL;
}
if ( text != NULL && text[ 0 ] == '\0' ) {
ldap_memfree( text );
text = NULL;
}
#endif /* LDAP_NULL_IS_NULL */
rs->sr_text = text; rs->sr_text = text;
if ( rc != LDAP_SUCCESS ) { if ( rc != LDAP_SUCCESS ) {
rs->sr_err = rc; rs->sr_err = rc;
@ -906,40 +920,43 @@ retry:;
/* return true if bound, false if failed */ /* return true if bound, false if failed */
int int
ldap_back_retry( struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok ) ldap_back_retry( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok )
{ {
int rc = 0; int rc = 0;
struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
ldap_pvt_thread_mutex_lock( &li->conn_mutex );
if ( lc->lc_refcnt == 1 ) { ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
if ( (*lcp)->lc_refcnt == 1 ) {
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"%s ldap_back_retry: retrying URI=\"%s\" DN=\"%s\"\n", "%s ldap_back_retry: retrying URI=\"%s\" DN=\"%s\"\n",
op->o_log_prefix, li->url, op->o_log_prefix, li->li_uri,
BER_BVISNULL( &lc->lc_bound_ndn ) ? BER_BVISNULL( &(*lcp)->lc_bound_ndn ) ?
"" : lc->lc_bound_ndn.bv_val ); "" : (*lcp)->lc_bound_ndn.bv_val );
ldap_unbind_ext( lc->lc_ld, NULL, NULL ); ldap_unbind_ext( (*lcp)->lc_ld, NULL, NULL );
lc->lc_ld = NULL; (*lcp)->lc_ld = NULL;
LDAP_BACK_CONN_ISBOUND_CLEAR( lc ); LDAP_BACK_CONN_ISBOUND_CLEAR( (*lcp) );
/* lc here must be the regular lc, reset and ready for init */ /* lc here must be the regular lc, reset and ready for init */
rc = ldap_back_prepare_conn( &lc, op, rs, sendok ); rc = ldap_back_prepare_conn( lcp, op, rs, sendok );
if ( rc == LDAP_SUCCESS ) { if ( rc == LDAP_SUCCESS ) {
rc = ldap_back_dobind_int( lc, op, rs, sendok, 0, 0 ); rc = ldap_back_dobind_int( *lcp, op, rs, sendok, 0, 0 );
if ( rc == 0 ) {
*lcp = NULL;
}
} }
} }
ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
return rc; return rc;
} }
static int static int
ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs ) ldap_back_proxy_authz_bind( ldapconn_t *lc, Operation *op, SlapReply *rs )
{ {
struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
struct berval binddn = slap_empty_bv; struct berval binddn = slap_empty_bv;
struct berval bindcred = slap_empty_bv; struct berval bindcred = slap_empty_bv;
int dobind = 0; int dobind = 0;
@ -969,13 +986,13 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
/* bind as proxyauthzdn only if no idassert mode /* bind as proxyauthzdn only if no idassert mode
* is requested, or if the client's identity * is requested, or if the client's identity
* is authorized */ * is authorized */
switch ( li->idassert_mode ) { switch ( li->li_idassert_mode ) {
case LDAP_BACK_IDASSERT_LEGACY: case LDAP_BACK_IDASSERT_LEGACY:
if ( !BER_BVISNULL( &op->o_conn->c_ndn ) && !BER_BVISEMPTY( &op->o_conn->c_ndn ) ) { if ( !BER_BVISNULL( &op->o_conn->c_ndn ) && !BER_BVISEMPTY( &op->o_conn->c_ndn ) ) {
if ( !BER_BVISNULL( &li->idassert_authcDN ) && !BER_BVISEMPTY( &li->idassert_authcDN ) ) if ( !BER_BVISNULL( &li->li_idassert_authcDN ) && !BER_BVISEMPTY( &li->li_idassert_authcDN ) )
{ {
binddn = li->idassert_authcDN; binddn = li->li_idassert_authcDN;
bindcred = li->idassert_passwd; bindcred = li->li_idassert_passwd;
dobind = 1; dobind = 1;
} }
} }
@ -983,7 +1000,7 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
default: default:
/* NOTE: rootdn can always idassert */ /* NOTE: rootdn can always idassert */
if ( li->idassert_authz && !be_isroot( op ) ) { if ( li->li_idassert_authz && !be_isroot( op ) ) {
struct berval authcDN; struct berval authcDN;
if ( BER_BVISNULL( &op->o_conn->c_ndn ) ) { if ( BER_BVISNULL( &op->o_conn->c_ndn ) ) {
@ -992,10 +1009,10 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
} else { } else {
authcDN = op->o_conn->c_ndn; authcDN = op->o_conn->c_ndn;
} }
rs->sr_err = slap_sasl_matches( op, li->idassert_authz, rs->sr_err = slap_sasl_matches( op, li->li_idassert_authz,
&authcDN, &authcDN ); &authcDN, &authcDN );
if ( rs->sr_err != LDAP_SUCCESS ) { if ( rs->sr_err != LDAP_SUCCESS ) {
if ( li->idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) { if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) {
send_ldap_result( op, rs ); send_ldap_result( op, rs );
LDAP_BACK_CONN_ISBOUND_CLEAR( lc ); LDAP_BACK_CONN_ISBOUND_CLEAR( lc );
@ -1010,13 +1027,13 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
} }
} }
binddn = li->idassert_authcDN; binddn = li->li_idassert_authcDN;
bindcred = li->idassert_passwd; bindcred = li->li_idassert_passwd;
dobind = 1; dobind = 1;
break; break;
} }
if ( dobind && li->idassert_authmethod == LDAP_AUTH_SASL ) { if ( dobind && li->li_idassert_authmethod == LDAP_AUTH_SASL ) {
#ifdef HAVE_CYRUS_SASL #ifdef HAVE_CYRUS_SASL
void *defaults = NULL; void *defaults = NULL;
struct berval authzID = BER_BVNULL; struct berval authzID = BER_BVNULL;
@ -1024,12 +1041,12 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
/* if SASL supports native authz, prepare for it */ /* if SASL supports native authz, prepare for it */
if ( ( !op->o_do_not_cache || !op->o_is_auth_check ) && if ( ( !op->o_do_not_cache || !op->o_is_auth_check ) &&
( li->idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) ) ( li->li_idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) )
{ {
switch ( li->idassert_mode ) { switch ( li->li_idassert_mode ) {
case LDAP_BACK_IDASSERT_OTHERID: case LDAP_BACK_IDASSERT_OTHERID:
case LDAP_BACK_IDASSERT_OTHERDN: case LDAP_BACK_IDASSERT_OTHERDN:
authzID = li->idassert_authzID; authzID = li->li_idassert_authzID;
break; break;
case LDAP_BACK_IDASSERT_ANONYMOUS: case LDAP_BACK_IDASSERT_ANONYMOUS:
@ -1055,10 +1072,10 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
} }
} }
if ( li->idassert_secprops != NULL ) { if ( li->li_idassert_secprops != NULL ) {
rs->sr_err = ldap_set_option( lc->lc_ld, rs->sr_err = ldap_set_option( lc->lc_ld,
LDAP_OPT_X_SASL_SECPROPS, LDAP_OPT_X_SASL_SECPROPS,
(void *)li->idassert_secprops ); (void *)li->li_idassert_secprops );
if ( rs->sr_err != LDAP_OPT_SUCCESS ) { if ( rs->sr_err != LDAP_OPT_SUCCESS ) {
send_ldap_result( op, rs ); send_ldap_result( op, rs );
@ -1068,14 +1085,14 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
} }
defaults = lutil_sasl_defaults( lc->lc_ld, defaults = lutil_sasl_defaults( lc->lc_ld,
li->idassert_sasl_mech.bv_val, li->li_idassert_sasl_mech.bv_val,
li->idassert_sasl_realm.bv_val, li->li_idassert_sasl_realm.bv_val,
li->idassert_authcID.bv_val, li->li_idassert_authcID.bv_val,
li->idassert_passwd.bv_val, li->li_idassert_passwd.bv_val,
authzID.bv_val ); authzID.bv_val );
rs->sr_err = ldap_sasl_interactive_bind_s( lc->lc_ld, binddn.bv_val, rs->sr_err = ldap_sasl_interactive_bind_s( lc->lc_ld, binddn.bv_val,
li->idassert_sasl_mech.bv_val, NULL, NULL, li->li_idassert_sasl_mech.bv_val, NULL, NULL,
LDAP_SASL_QUIET, lutil_sasl_interact, LDAP_SASL_QUIET, lutil_sasl_interact,
defaults ); defaults );
@ -1097,7 +1114,7 @@ ldap_back_proxy_authz_bind( struct ldapconn *lc, Operation *op, SlapReply *rs )
#endif /* HAVE_CYRUS_SASL */ #endif /* HAVE_CYRUS_SASL */
} }
switch ( li->idassert_authmethod ) { switch ( li->li_idassert_authmethod ) {
case LDAP_AUTH_NONE: case LDAP_AUTH_NONE:
LDAP_BACK_CONN_ISBOUND_SET( lc ); LDAP_BACK_CONN_ISBOUND_SET( lc );
goto done; goto done;
@ -1152,12 +1169,12 @@ done:;
*/ */
int int
ldap_back_proxy_authz_ctrl( ldap_back_proxy_authz_ctrl(
struct ldapconn *lc, ldapconn_t *lc,
Operation *op, Operation *op,
SlapReply *rs, SlapReply *rs,
LDAPControl ***pctrls ) LDAPControl ***pctrls )
{ {
struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private; ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private;
LDAPControl **ctrls = NULL; LDAPControl **ctrls = NULL;
int i = 0, int i = 0,
mode; mode;
@ -1170,8 +1187,8 @@ ldap_back_proxy_authz_ctrl(
/* FIXME: SASL/EXTERNAL over ldapi:// doesn't honor the authcID, /* FIXME: SASL/EXTERNAL over ldapi:// doesn't honor the authcID,
* but if it is not set this test fails. We need a different * but if it is not set this test fails. We need a different
* means to detect if idassert is enabled */ * means to detect if idassert is enabled */
if ( ( BER_BVISNULL( &li->idassert_authcID ) || BER_BVISEMPTY( &li->idassert_authcID ) ) if ( ( BER_BVISNULL( &li->li_idassert_authcID ) || BER_BVISEMPTY( &li->li_idassert_authcID ) )
&& ( BER_BVISNULL( &li->idassert_authcDN ) || BER_BVISEMPTY( &li->idassert_authcDN ) ) ) && ( BER_BVISNULL( &li->li_idassert_authcDN ) || BER_BVISEMPTY( &li->li_idassert_authcDN ) ) )
{ {
goto done; goto done;
} }
@ -1180,7 +1197,7 @@ ldap_back_proxy_authz_ctrl(
goto done; goto done;
} }
if ( li->idassert_mode == LDAP_BACK_IDASSERT_LEGACY ) { if ( li->li_idassert_mode == LDAP_BACK_IDASSERT_LEGACY ) {
if ( op->o_proxy_authz ) { if ( op->o_proxy_authz ) {
/* /*
* FIXME: we do not want to perform proxyAuthz * FIXME: we do not want to perform proxyAuthz
@ -1207,12 +1224,12 @@ ldap_back_proxy_authz_ctrl(
goto done; goto done;
} }
if ( BER_BVISNULL( &li->idassert_authcDN ) ) { if ( BER_BVISNULL( &li->li_idassert_authcDN ) ) {
goto done; goto done;
} }
} else if ( li->idassert_authmethod == LDAP_AUTH_SASL ) { } else if ( li->li_idassert_authmethod == LDAP_AUTH_SASL ) {
if ( ( li->idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ ) if ( ( li->li_idassert_flags & LDAP_BACK_AUTH_NATIVE_AUTHZ )
/* && ( !BER_BVISNULL( &op->o_conn->c_ndn ) /* && ( !BER_BVISNULL( &op->o_conn->c_ndn )
|| LDAP_BACK_CONN_ISBOUND( lc ) ) */ ) || LDAP_BACK_CONN_ISBOUND( lc ) ) */ )
{ {
@ -1223,7 +1240,7 @@ ldap_back_proxy_authz_ctrl(
goto done; goto done;
} }
} else if ( li->idassert_authz && !be_isroot( op ) ) { } else if ( li->li_idassert_authz && !be_isroot( op ) ) {
int rc; int rc;
struct berval authcDN; struct berval authcDN;
@ -1232,10 +1249,10 @@ ldap_back_proxy_authz_ctrl(
} else { } else {
authcDN = op->o_conn->c_ndn; authcDN = op->o_conn->c_ndn;
} }
rc = slap_sasl_matches( op, li->idassert_authz, rc = slap_sasl_matches( op, li->li_idassert_authz,
&authcDN, & authcDN ); &authcDN, & authcDN );
if ( rc != LDAP_SUCCESS ) { if ( rc != LDAP_SUCCESS ) {
if ( li->idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE ) if ( li->li_idassert_flags & LDAP_BACK_AUTH_PRESCRIPTIVE )
{ {
/* op->o_conn->c_ndn is not authorized /* op->o_conn->c_ndn is not authorized
* to use idassert */ * to use idassert */
@ -1271,7 +1288,7 @@ ldap_back_proxy_authz_ctrl(
mode = LDAP_BACK_IDASSERT_NOASSERT; mode = LDAP_BACK_IDASSERT_NOASSERT;
} else { } else {
mode = li->idassert_mode; mode = li->li_idassert_mode;
} }
switch ( mode ) { switch ( mode ) {
@ -1298,7 +1315,7 @@ ldap_back_proxy_authz_ctrl(
case LDAP_BACK_IDASSERT_OTHERID: case LDAP_BACK_IDASSERT_OTHERID:
case LDAP_BACK_IDASSERT_OTHERDN: case LDAP_BACK_IDASSERT_OTHERDN:
/* assert idassert DN */ /* assert idassert DN */
assertedID = li->idassert_authzID; assertedID = li->li_idassert_authzID;
break; break;
default: default:
@ -1320,7 +1337,7 @@ ldap_back_proxy_authz_ctrl(
ctrls[ 0 ]->ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ; ctrls[ 0 ]->ldctl_oid = LDAP_CONTROL_PROXY_AUTHZ;
ctrls[ 0 ]->ldctl_iscritical = 1; ctrls[ 0 ]->ldctl_iscritical = 1;
switch ( li->idassert_mode ) { switch ( li->li_idassert_mode ) {
/* already in u:ID or dn:DN form */ /* already in u:ID or dn:DN form */
case LDAP_BACK_IDASSERT_OTHERID: case LDAP_BACK_IDASSERT_OTHERID:
case LDAP_BACK_IDASSERT_OTHERDN: case LDAP_BACK_IDASSERT_OTHERDN:

File diff suppressed because it is too large Load Diff

@ -36,7 +36,7 @@ ldap_back_compare(
Operation *op, Operation *op,
SlapReply *rs ) SlapReply *rs )
{ {
struct ldapconn *lc; ldapconn_t *lc;
ber_int_t msgid; ber_int_t msgid;
int do_retry = 1; int do_retry = 1;
LDAPControl **ctrls = NULL; LDAPControl **ctrls = NULL;
@ -63,7 +63,7 @@ retry:
rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_SENDRESULT ); rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_SENDRESULT );
if ( rc == LDAP_UNAVAILABLE && do_retry ) { if ( rc == LDAP_UNAVAILABLE && do_retry ) {
do_retry = 0; do_retry = 0;
if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
goto retry; goto retry;
} }
} }

File diff suppressed because it is too large Load Diff

@ -36,9 +36,9 @@ ldap_back_delete(
Operation *op, Operation *op,
SlapReply *rs ) SlapReply *rs )
{ {
struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
struct ldapconn *lc; ldapconn_t *lc;
ber_int_t msgid; ber_int_t msgid;
LDAPControl **ctrls = NULL; LDAPControl **ctrls = NULL;
int do_retry = 1; int do_retry = 1;
@ -62,10 +62,10 @@ retry:
rs->sr_err = ldap_delete_ext( lc->lc_ld, op->o_req_ndn.bv_val, rs->sr_err = ldap_delete_ext( lc->lc_ld, op->o_req_ndn.bv_val,
ctrls, NULL, &msgid ); ctrls, NULL, &msgid );
rc = ldap_back_op_result( lc, op, rs, msgid, rc = ldap_back_op_result( lc, op, rs, msgid,
li->timeout[ LDAP_BACK_OP_DELETE], LDAP_BACK_SENDRESULT ); li->li_timeout[ LDAP_BACK_OP_DELETE], LDAP_BACK_SENDRESULT );
if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) { if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) {
do_retry = 0; do_retry = 0;
if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
goto retry; goto retry;
} }
} }

@ -48,7 +48,7 @@ ldap_back_extended(
for ( i = 0; exop_table[i].extended != NULL; i++ ) { for ( i = 0; exop_table[i].extended != NULL; i++ ) {
if ( bvmatch( &exop_table[i].oid, &op->oq_extended.rs_reqoid ) ) if ( bvmatch( &exop_table[i].oid, &op->oq_extended.rs_reqoid ) )
{ {
struct ldapconn *lc; ldapconn_t *lc;
LDAPControl **oldctrls = NULL; LDAPControl **oldctrls = NULL;
int rc; int rc;
@ -98,7 +98,7 @@ ldap_back_exop_passwd(
Operation *op, Operation *op,
SlapReply *rs ) SlapReply *rs )
{ {
struct ldapconn *lc; ldapconn_t *lc;
req_pwdexop_s *qpw = &op->oq_pwdexop; req_pwdexop_s *qpw = &op->oq_pwdexop;
LDAPMessage *res; LDAPMessage *res;
ber_int_t msgid; ber_int_t msgid;
@ -124,7 +124,7 @@ retry:
if ( rc == LDAP_SUCCESS ) { if ( rc == LDAP_SUCCESS ) {
if ( ldap_result( lc->lc_ld, msgid, 1, NULL, &res ) == -1 ) { if ( ldap_result( lc->lc_ld, msgid, 1, NULL, &res ) == -1 ) {
ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER, &rc ); ldap_get_option( lc->lc_ld, LDAP_OPT_ERROR_NUMBER, &rc );
ldap_back_freeconn( op, lc ); ldap_back_freeconn( op, lc, 0 );
lc = NULL; lc = NULL;
} else { } else {
@ -135,6 +135,7 @@ retry:
(char **)&rs->sr_matched, (char **)&rs->sr_matched,
(char **)&rs->sr_text, (char **)&rs->sr_text,
NULL, NULL, 0 ); NULL, NULL, 0 );
#ifndef LDAP_NULL_IS_NULL
if ( rs->sr_matched && rs->sr_matched[ 0 ] == '\0' ) { if ( rs->sr_matched && rs->sr_matched[ 0 ] == '\0' ) {
free( (char *)rs->sr_matched ); free( (char *)rs->sr_matched );
rs->sr_matched = NULL; rs->sr_matched = NULL;
@ -143,6 +144,7 @@ retry:
free( (char *)rs->sr_text ); free( (char *)rs->sr_text );
rs->sr_text = NULL; rs->sr_text = NULL;
} }
#endif /* LDAP_NULL_IS_NULL */
if ( rc == LDAP_SUCCESS ) { if ( rc == LDAP_SUCCESS ) {
if ( rs->sr_err == LDAP_SUCCESS ) { if ( rs->sr_err == LDAP_SUCCESS ) {
struct berval newpw; struct berval newpw;
@ -168,7 +170,7 @@ retry:
rs->sr_err = slap_map_api2result( rs ); rs->sr_err = slap_map_api2result( rs );
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) { if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
do_retry = 0; do_retry = 0;
if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
goto retry; goto retry;
} }
} }

@ -80,45 +80,45 @@ ldap_back_initialize( BackendInfo *bi )
int int
ldap_back_db_init( Backend *be ) ldap_back_db_init( Backend *be )
{ {
struct ldapinfo *li; ldapinfo_t *li;
li = (struct ldapinfo *)ch_calloc( 1, sizeof( struct ldapinfo ) ); li = (ldapinfo_t *)ch_calloc( 1, sizeof( ldapinfo_t ) );
if ( li == NULL ) { if ( li == NULL ) {
return -1; return -1;
} }
BER_BVZERO( &li->acl_authcID ); BER_BVZERO( &li->li_acl_authcID );
BER_BVZERO( &li->acl_authcDN ); BER_BVZERO( &li->li_acl_authcDN );
BER_BVZERO( &li->acl_passwd ); BER_BVZERO( &li->li_acl_passwd );
li->acl_authmethod = LDAP_AUTH_NONE; li->li_acl_authmethod = LDAP_AUTH_NONE;
BER_BVZERO( &li->acl_sasl_mech ); BER_BVZERO( &li->li_acl_sasl_mech );
li->acl_sb.sb_tls = SB_TLS_DEFAULT; li->li_acl.sb_tls = SB_TLS_DEFAULT;
li->idassert_mode = LDAP_BACK_IDASSERT_LEGACY; li->li_idassert_mode = LDAP_BACK_IDASSERT_LEGACY;
BER_BVZERO( &li->idassert_authcID ); BER_BVZERO( &li->li_idassert_authcID );
BER_BVZERO( &li->idassert_authcDN ); BER_BVZERO( &li->li_idassert_authcDN );
BER_BVZERO( &li->idassert_passwd ); BER_BVZERO( &li->li_idassert_passwd );
BER_BVZERO( &li->idassert_authzID ); BER_BVZERO( &li->li_idassert_authzID );
li->idassert_authmethod = LDAP_AUTH_NONE; li->li_idassert_authmethod = LDAP_AUTH_NONE;
BER_BVZERO( &li->idassert_sasl_mech ); BER_BVZERO( &li->li_idassert_sasl_mech );
li->idassert_sb.sb_tls = SB_TLS_DEFAULT; li->li_idassert.sb_tls = SB_TLS_DEFAULT;
/* by default, use proxyAuthz control on each operation */ /* by default, use proxyAuthz control on each operation */
li->idassert_flags = LDAP_BACK_AUTH_PRESCRIPTIVE; li->li_idassert_flags = LDAP_BACK_AUTH_PRESCRIPTIVE;
li->idassert_authz = NULL; li->li_idassert_authz = NULL;
/* initialize flags */ /* initialize flags */
li->flags = LDAP_BACK_F_CHASE_REFERRALS; li->li_flags = LDAP_BACK_F_CHASE_REFERRALS;
/* initialize version */ /* initialize version */
li->version = LDAP_VERSION3; li->li_version = LDAP_VERSION3;
ldap_pvt_thread_mutex_init( &li->conn_mutex ); ldap_pvt_thread_mutex_init( &li->li_conninfo.lai_mutex );
be->be_private = li; be->be_private = li;
SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_NOLASTMOD; SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_NOLASTMOD;
@ -131,19 +131,19 @@ ldap_back_db_init( Backend *be )
int int
ldap_back_db_open( BackendDB *be ) ldap_back_db_open( BackendDB *be )
{ {
struct ldapinfo *li = (struct ldapinfo *)be->be_private; ldapinfo_t *li = (ldapinfo_t *)be->be_private;
Debug( LDAP_DEBUG_TRACE, Debug( LDAP_DEBUG_TRACE,
"ldap_back_db_open: URI=%s\n", "ldap_back_db_open: URI=%s\n",
li->url != NULL ? li->url : "", 0, 0 ); li->li_uri != NULL ? li->li_uri : "", 0, 0 );
/* by default, use proxyAuthz control on each operation */ /* by default, use proxyAuthz control on each operation */
switch ( li->idassert_mode ) { switch ( li->li_idassert_mode ) {
case LDAP_BACK_IDASSERT_LEGACY: case LDAP_BACK_IDASSERT_LEGACY:
case LDAP_BACK_IDASSERT_SELF: case LDAP_BACK_IDASSERT_SELF:
/* however, since admin connections are pooled and shared, /* however, since admin connections are pooled and shared,
* only static authzIDs can be native */ * only static authzIDs can be native */
li->idassert_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ; li->li_idassert_flags &= ~LDAP_BACK_AUTH_NATIVE_AUTHZ;
break; break;
default: default:
@ -159,7 +159,6 @@ ldap_back_db_open( BackendDB *be )
* the normalized one. See ITS#3406 */ * the normalized one. See ITS#3406 */
struct berval filter, struct berval filter,
base = BER_BVC( "cn=Databases," SLAPD_MONITOR ); base = BER_BVC( "cn=Databases," SLAPD_MONITOR );
struct berval vals[ 2 ];
Attribute a = { 0 }; Attribute a = { 0 };
filter.bv_len = STRLENOF( "(&(namingContexts:distinguishedNameMatch:=)(monitoredInfo=ldap))" ) filter.bv_len = STRLENOF( "(&(namingContexts:distinguishedNameMatch:=)(monitoredInfo=ldap))" )
@ -170,10 +169,8 @@ ldap_back_db_open( BackendDB *be )
be->be_nsuffix[ 0 ].bv_val ); be->be_nsuffix[ 0 ].bv_val );
a.a_desc = slap_schema.si_ad_labeledURI; a.a_desc = slap_schema.si_ad_labeledURI;
ber_str2bv( li->url, 0, 0, &vals[ 0 ] ); a.a_vals = li->li_bvuri;
BER_BVZERO( &vals[ 1 ] ); a.a_nvals = li->li_bvuri;
a.a_vals = vals;
a.a_nvals = vals;
if ( monitor_back_register_entry_attrs( NULL, &a, NULL, &base, LDAP_SCOPE_SUBTREE, &filter ) ) { if ( monitor_back_register_entry_attrs( NULL, &a, NULL, &base, LDAP_SCOPE_SUBTREE, &filter ) ) {
/* error */ /* error */
} }
@ -182,16 +179,16 @@ ldap_back_db_open( BackendDB *be )
} }
#endif /* SLAPD_MONITOR */ #endif /* SLAPD_MONITOR */
if ( li->flags & LDAP_BACK_F_SUPPORT_T_F_DISCOVER ) { if ( li->li_flags & LDAP_BACK_F_SUPPORT_T_F_DISCOVER ) {
int rc; int rc;
li->flags &= ~LDAP_BACK_F_SUPPORT_T_F_DISCOVER; li->li_flags &= ~LDAP_BACK_F_SUPPORT_T_F_DISCOVER;
rc = slap_discover_feature( li->url, li->version, rc = slap_discover_feature( li->li_uri, li->li_version,
slap_schema.si_ad_supportedFeatures->ad_cname.bv_val, slap_schema.si_ad_supportedFeatures->ad_cname.bv_val,
LDAP_FEATURE_ABSOLUTE_FILTERS ); LDAP_FEATURE_ABSOLUTE_FILTERS );
if ( rc == LDAP_COMPARE_TRUE ) { if ( rc == LDAP_COMPARE_TRUE ) {
li->flags |= LDAP_BACK_F_SUPPORT_T_F; li->li_flags |= LDAP_BACK_F_SUPPORT_T_F;
} }
} }
@ -201,7 +198,7 @@ ldap_back_db_open( BackendDB *be )
void void
ldap_back_conn_free( void *v_lc ) ldap_back_conn_free( void *v_lc )
{ {
struct ldapconn *lc = v_lc; ldapconn_t *lc = v_lc;
if ( lc->lc_ld != NULL ) { if ( lc->lc_ld != NULL ) {
ldap_unbind_ext( lc->lc_ld, NULL, NULL ); ldap_unbind_ext( lc->lc_ld, NULL, NULL );
@ -224,75 +221,73 @@ ldap_back_db_destroy(
Backend *be Backend *be
) )
{ {
struct ldapinfo *li;
if ( be->be_private ) { if ( be->be_private ) {
li = ( struct ldapinfo * )be->be_private; ldapinfo_t *li = ( ldapinfo_t * )be->be_private;
ldap_pvt_thread_mutex_lock( &li->conn_mutex ); ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
if ( li->url != NULL ) { if ( li->li_uri != NULL ) {
ch_free( li->url ); ch_free( li->li_uri );
li->url = NULL; li->li_uri = NULL;
assert( li->li_bvuri != NULL );
ber_bvarray_free( li->li_bvuri );
li->li_bvuri = NULL;
} }
if ( li->lud ) { if ( !BER_BVISNULL( &li->li_acl_authcID ) ) {
ldap_free_urldesc( li->lud ); ch_free( li->li_acl_authcID.bv_val );
li->lud = NULL; BER_BVZERO( &li->li_acl_authcID );
} }
if ( !BER_BVISNULL( &li->acl_authcID ) ) { if ( !BER_BVISNULL( &li->li_acl_authcDN ) ) {
ch_free( li->acl_authcID.bv_val ); ch_free( li->li_acl_authcDN.bv_val );
BER_BVZERO( &li->acl_authcID ); BER_BVZERO( &li->li_acl_authcDN );
} }
if ( !BER_BVISNULL( &li->acl_authcDN ) ) { if ( !BER_BVISNULL( &li->li_acl_passwd ) ) {
ch_free( li->acl_authcDN.bv_val ); ch_free( li->li_acl_passwd.bv_val );
BER_BVZERO( &li->acl_authcDN ); BER_BVZERO( &li->li_acl_passwd );
} }
if ( !BER_BVISNULL( &li->acl_passwd ) ) { if ( !BER_BVISNULL( &li->li_acl_sasl_mech ) ) {
ch_free( li->acl_passwd.bv_val ); ch_free( li->li_acl_sasl_mech.bv_val );
BER_BVZERO( &li->acl_passwd ); BER_BVZERO( &li->li_acl_sasl_mech );
} }
if ( !BER_BVISNULL( &li->acl_sasl_mech ) ) { if ( !BER_BVISNULL( &li->li_acl_sasl_realm ) ) {
ch_free( li->acl_sasl_mech.bv_val ); ch_free( li->li_acl_sasl_realm.bv_val );
BER_BVZERO( &li->acl_sasl_mech ); BER_BVZERO( &li->li_acl_sasl_realm );
} }
if ( !BER_BVISNULL( &li->acl_sasl_realm ) ) { if ( !BER_BVISNULL( &li->li_idassert_authcID ) ) {
ch_free( li->acl_sasl_realm.bv_val ); ch_free( li->li_idassert_authcID.bv_val );
BER_BVZERO( &li->acl_sasl_realm ); BER_BVZERO( &li->li_idassert_authcID );
} }
if ( !BER_BVISNULL( &li->idassert_authcID ) ) { if ( !BER_BVISNULL( &li->li_idassert_authcDN ) ) {
ch_free( li->idassert_authcID.bv_val ); ch_free( li->li_idassert_authcDN.bv_val );
BER_BVZERO( &li->idassert_authcID ); BER_BVZERO( &li->li_idassert_authcDN );
} }
if ( !BER_BVISNULL( &li->idassert_authcDN ) ) { if ( !BER_BVISNULL( &li->li_idassert_passwd ) ) {
ch_free( li->idassert_authcDN.bv_val ); ch_free( li->li_idassert_passwd.bv_val );
BER_BVZERO( &li->idassert_authcDN ); BER_BVZERO( &li->li_idassert_passwd );
} }
if ( !BER_BVISNULL( &li->idassert_passwd ) ) { if ( !BER_BVISNULL( &li->li_idassert_authzID ) ) {
ch_free( li->idassert_passwd.bv_val ); ch_free( li->li_idassert_authzID.bv_val );
BER_BVZERO( &li->idassert_passwd ); BER_BVZERO( &li->li_idassert_authzID );
} }
if ( !BER_BVISNULL( &li->idassert_authzID ) ) { if ( !BER_BVISNULL( &li->li_idassert_sasl_mech ) ) {
ch_free( li->idassert_authzID.bv_val ); ch_free( li->li_idassert_sasl_mech.bv_val );
BER_BVZERO( &li->idassert_authzID ); BER_BVZERO( &li->li_idassert_sasl_mech );
} }
if ( !BER_BVISNULL( &li->idassert_sasl_mech ) ) { if ( !BER_BVISNULL( &li->li_idassert_sasl_realm ) ) {
ch_free( li->idassert_sasl_mech.bv_val ); ch_free( li->li_idassert_sasl_realm.bv_val );
BER_BVZERO( &li->idassert_sasl_mech ); BER_BVZERO( &li->li_idassert_sasl_realm );
} }
if ( !BER_BVISNULL( &li->idassert_sasl_realm ) ) { if ( li->li_idassert_authz != NULL ) {
ch_free( li->idassert_sasl_realm.bv_val ); ber_bvarray_free( li->li_idassert_authz );
BER_BVZERO( &li->idassert_sasl_realm ); li->li_idassert_authz = NULL;
} }
if ( li->idassert_authz != NULL ) { if ( li->li_conninfo.lai_tree ) {
ber_bvarray_free( li->idassert_authz ); avl_free( li->li_conninfo.lai_tree, ldap_back_conn_free );
li->idassert_authz = NULL;
}
if ( li->conntree ) {
avl_free( li->conntree, ldap_back_conn_free );
} }
ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
ldap_pvt_thread_mutex_destroy( &li->conn_mutex ); ldap_pvt_thread_mutex_destroy( &li->li_conninfo.lai_mutex );
} }
ch_free( be->be_private ); ch_free( be->be_private );

@ -36,9 +36,9 @@ ldap_back_modify(
Operation *op, Operation *op,
SlapReply *rs ) SlapReply *rs )
{ {
struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
struct ldapconn *lc; ldapconn_t *lc;
LDAPMod **modv = NULL, LDAPMod **modv = NULL,
*mods = NULL; *mods = NULL;
Modifications *ml; Modifications *ml;
@ -110,10 +110,10 @@ retry:
rs->sr_err = ldap_modify_ext( lc->lc_ld, op->o_req_ndn.bv_val, modv, rs->sr_err = ldap_modify_ext( lc->lc_ld, op->o_req_ndn.bv_val, modv,
ctrls, NULL, &msgid ); ctrls, NULL, &msgid );
rc = ldap_back_op_result( lc, op, rs, msgid, rc = ldap_back_op_result( lc, op, rs, msgid,
li->timeout[ LDAP_BACK_OP_MODIFY], LDAP_BACK_SENDRESULT ); li->li_timeout[ LDAP_BACK_OP_MODIFY], LDAP_BACK_SENDRESULT );
if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) { if ( rs->sr_err == LDAP_UNAVAILABLE && do_retry ) {
do_retry = 0; do_retry = 0;
if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
goto retry; goto retry;
} }
} }

@ -36,9 +36,9 @@ ldap_back_modrdn(
Operation *op, Operation *op,
SlapReply *rs ) SlapReply *rs )
{ {
struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private; ldapinfo_t *li = (ldapinfo_t *)op->o_bd->be_private;
struct ldapconn *lc; ldapconn_t *lc;
ber_int_t msgid; ber_int_t msgid;
LDAPControl **ctrls = NULL; LDAPControl **ctrls = NULL;
int do_retry = 1; int do_retry = 1;
@ -70,10 +70,10 @@ retry:
op->orr_newrdn.bv_val, newSup, op->orr_newrdn.bv_val, newSup,
op->orr_deleteoldrdn, ctrls, NULL, &msgid ); op->orr_deleteoldrdn, ctrls, NULL, &msgid );
rc = ldap_back_op_result( lc, op, rs, msgid, rc = ldap_back_op_result( lc, op, rs, msgid,
li->timeout[ LDAP_BACK_OP_MODRDN ], LDAP_BACK_SENDRESULT ); li->li_timeout[ LDAP_BACK_OP_MODRDN ], LDAP_BACK_SENDRESULT );
if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) { if ( rs->sr_err == LDAP_SERVER_DOWN && do_retry ) {
do_retry = 0; do_retry = 0;
if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
goto retry; goto retry;
} }
} }

@ -32,7 +32,6 @@ extern BI_destroy ldap_back_destroy;
extern BI_db_init ldap_back_db_init; extern BI_db_init ldap_back_db_init;
extern BI_db_open ldap_back_db_open; extern BI_db_open ldap_back_db_open;
extern BI_db_destroy ldap_back_db_destroy; extern BI_db_destroy ldap_back_db_destroy;
extern BI_db_config ldap_back_db_config;
extern BI_op_bind ldap_back_bind; extern BI_op_bind ldap_back_bind;
extern BI_op_search ldap_back_search; extern BI_op_search ldap_back_search;
@ -48,15 +47,14 @@ extern BI_connection_destroy ldap_back_conn_destroy;
extern BI_entry_get_rw ldap_back_entry_get; extern BI_entry_get_rw ldap_back_entry_get;
int ldap_back_freeconn( Operation *op, struct ldapconn *lc ); int ldap_back_freeconn( Operation *op, ldapconn_t *lc, int dolock );
struct ldapconn *ldap_back_getconn(struct slap_op *op, struct slap_rep *rs, ldap_back_send_t sendok); ldapconn_t *ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok );
void ldap_back_release_conn( struct slap_op *op, struct slap_rep *rs, struct ldapconn *lc ); void ldap_back_release_conn( Operation *op, SlapReply *rs, ldapconn_t *lc );
int ldap_back_dobind(struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok); int ldap_back_dobind( ldapconn_t *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok );
int ldap_back_retry(struct ldapconn *lc, Operation *op, SlapReply *rs, ldap_back_send_t sendok); int ldap_back_retry( ldapconn_t **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok );
int ldap_back_map_result(SlapReply *rs); int ldap_back_map_result( SlapReply *rs );
int ldap_back_op_result(struct ldapconn *lc, Operation *op, SlapReply *rs, int ldap_back_op_result( ldapconn_t *lc, Operation *op, SlapReply *rs,
ber_int_t msgid, time_t timeout, ldap_back_send_t sendok); ber_int_t msgid, time_t timeout, ldap_back_send_t sendok );
int back_ldap_LTX_init_module(int argc, char *argv[]);
int ldap_back_init_cf( BackendInfo *bi ); int ldap_back_init_cf( BackendInfo *bi );
@ -66,7 +64,7 @@ extern void ldap_back_conn_free( void *c );
extern int extern int
ldap_back_proxy_authz_ctrl( ldap_back_proxy_authz_ctrl(
struct ldapconn *lc, ldapconn_t *lc,
Operation *op, Operation *op,
SlapReply *rs, SlapReply *rs,
LDAPControl ***pctrls ); LDAPControl ***pctrls );

@ -49,7 +49,7 @@ ldap_back_munge_filter(
Operation *op, Operation *op,
struct berval *filter ) struct berval *filter )
{ {
struct ldapinfo *li = (struct ldapinfo *) op->o_bd->be_private; ldapinfo_t *li = (ldapinfo_t *) op->o_bd->be_private;
char *ptr; char *ptr;
int gotit = 0; int gotit = 0;
@ -75,7 +75,7 @@ ldap_back_munge_filter(
if ( strncmp( ptr, bv_true.bv_val, bv_true.bv_len ) == 0 ) { if ( strncmp( ptr, bv_true.bv_val, bv_true.bv_len ) == 0 ) {
oldbv = &bv_true; oldbv = &bv_true;
if ( li->flags & LDAP_BACK_F_SUPPORT_T_F ) { if ( li->li_flags & LDAP_BACK_F_SUPPORT_T_F ) {
newbv = &bv_t; newbv = &bv_t;
} else { } else {
@ -85,7 +85,7 @@ ldap_back_munge_filter(
} else if ( strncmp( ptr, bv_false.bv_val, bv_false.bv_len ) == 0 ) } else if ( strncmp( ptr, bv_false.bv_val, bv_false.bv_len ) == 0 )
{ {
oldbv = &bv_false; oldbv = &bv_false;
if ( li->flags & LDAP_BACK_F_SUPPORT_T_F ) { if ( li->li_flags & LDAP_BACK_F_SUPPORT_T_F ) {
newbv = &bv_f; newbv = &bv_f;
} else { } else {
@ -141,7 +141,7 @@ ldap_back_search(
Operation *op, Operation *op,
SlapReply *rs ) SlapReply *rs )
{ {
struct ldapconn *lc; ldapconn_t *lc;
struct timeval tv; struct timeval tv;
time_t stoptime = (time_t)-1; time_t stoptime = (time_t)-1;
LDAPMessage *res, LDAPMessage *res,
@ -216,18 +216,24 @@ retry:
op->ors_slimit, &msgid ); op->ors_slimit, &msgid );
if ( rs->sr_err != LDAP_SUCCESS ) { if ( rs->sr_err != LDAP_SUCCESS ) {
fail:;
switch ( rs->sr_err ) { switch ( rs->sr_err ) {
case LDAP_SERVER_DOWN: case LDAP_SERVER_DOWN:
if ( do_retry ) { if ( do_retry ) {
do_retry = 0; do_retry = 0;
if ( ldap_back_retry( lc, op, rs, LDAP_BACK_DONTSEND ) ) { if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_DONTSEND ) ) {
goto retry; goto retry;
} }
} }
rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_DONTSEND ); if ( lc == NULL ) {
ldap_back_freeconn( op, lc ); /* reset by ldap_back_retry ... */
lc = NULL; rs->sr_err = slap_map_api2result( rs );
} else {
rc = ldap_back_op_result( lc, op, rs, msgid, 0, LDAP_BACK_DONTSEND );
ldap_back_freeconn( op, lc, 0 );
lc = NULL;
}
goto finish; goto finish;
case LDAP_FILTER_ERROR: case LDAP_FILTER_ERROR:
@ -280,7 +286,6 @@ fail:;
} else if ( rc == LDAP_RES_SEARCH_ENTRY ) { } else if ( rc == LDAP_RES_SEARCH_ENTRY ) {
Entry ent = { 0 }; Entry ent = { 0 };
struct berval bdn = BER_BVNULL; struct berval bdn = BER_BVNULL;
int abort = 0;
do_retry = 0; do_retry = 0;
@ -291,7 +296,7 @@ fail:;
rs->sr_attrs = op->ors_attrs; rs->sr_attrs = op->ors_attrs;
rs->sr_operational_attrs = NULL; rs->sr_operational_attrs = NULL;
rs->sr_flags = 0; rs->sr_flags = 0;
abort = send_search_entry( op, rs ); rc = rs->sr_err = send_search_entry( op, rs );
if ( !BER_BVISNULL( &ent.e_name ) ) { if ( !BER_BVISNULL( &ent.e_name ) ) {
assert( ent.e_name.bv_val != bdn.bv_val ); assert( ent.e_name.bv_val != bdn.bv_val );
free( ent.e_name.bv_val ); free( ent.e_name.bv_val );
@ -304,8 +309,12 @@ fail:;
entry_clean( &ent ); entry_clean( &ent );
} }
ldap_msgfree( res ); ldap_msgfree( res );
if ( abort ) { if ( rc != LDAP_SUCCESS ) {
ldap_abandon_ext( lc->lc_ld, msgid, NULL, NULL ); if ( rc == LDAP_UNAVAILABLE ) {
rc = rs->sr_err = LDAP_OTHER;
} else {
ldap_abandon_ext( lc->lc_ld, msgid, NULL, NULL );
}
goto finish; goto finish;
} }
@ -396,13 +405,22 @@ fail:;
} }
if ( match.bv_val != NULL ) { if ( match.bv_val != NULL ) {
#ifndef LDAP_NULL_IS_NULL
if ( match.bv_val[ 0 ] == '\0' ) { if ( match.bv_val[ 0 ] == '\0' ) {
LDAP_FREE( match.bv_val ); LDAP_FREE( match.bv_val );
BER_BVZERO( &match ); BER_BVZERO( &match );
} else { } else
#endif /* LDAP_NULL_IS_NULL */
{
match.bv_len = strlen( match.bv_val ); match.bv_len = strlen( match.bv_val );
} }
} }
#ifndef LDAP_NULL_IS_NULL
if ( rs->sr_text != NULL && rs->sr_text[ 0 ] == '\0' ) {
LDAP_FREE( (char *)rs->sr_text );
rs->sr_text = NULL;
}
#endif /* LDAP_NULL_IS_NULL */
/* cleanup */ /* cleanup */
if ( references ) { if ( references ) {
@ -417,12 +435,13 @@ fail:;
if ( rc == -1 ) { if ( rc == -1 ) {
if ( do_retry ) { if ( do_retry ) {
do_retry = 0; do_retry = 0;
if ( ldap_back_retry( lc, op, rs, LDAP_BACK_SENDERR ) ) { if ( ldap_back_retry( &lc, op, rs, LDAP_BACK_SENDERR ) ) {
goto retry; goto retry;
} }
} }
rs->sr_err = LDAP_SERVER_DOWN; rs->sr_err = LDAP_SERVER_DOWN;
goto fail; rs->sr_err = slap_map_api2result( rs );
goto finish;
} }
/* /*
@ -688,7 +707,7 @@ ldap_back_entry_get(
Entry **ent Entry **ent
) )
{ {
struct ldapconn *lc; ldapconn_t *lc;
int rc = 1, int rc = 1,
do_not_cache; do_not_cache;
struct berval bdn; struct berval bdn;
@ -746,7 +765,7 @@ retry:
if ( rc != LDAP_SUCCESS ) { if ( rc != LDAP_SUCCESS ) {
if ( rc == LDAP_SERVER_DOWN && do_retry ) { if ( rc == LDAP_SERVER_DOWN && do_retry ) {
do_retry = 0; do_retry = 0;
if ( ldap_back_retry( lc, op, &rs, LDAP_BACK_DONTSEND ) ) { if ( ldap_back_retry( &lc, op, &rs, LDAP_BACK_DONTSEND ) ) {
goto retry; goto retry;
} }
} }

@ -38,8 +38,8 @@ ldap_back_conn_destroy(
Connection *conn Connection *conn
) )
{ {
struct ldapinfo *li = (struct ldapinfo *) be->be_private; ldapinfo_t *li = (ldapinfo_t *) be->be_private;
struct ldapconn *lc = NULL, lc_curr; ldapconn_t *lc = NULL, lc_curr;
Debug( LDAP_DEBUG_TRACE, Debug( LDAP_DEBUG_TRACE,
"=>ldap_back_conn_destroy: fetching conn %ld\n", "=>ldap_back_conn_destroy: fetching conn %ld\n",
@ -48,9 +48,9 @@ ldap_back_conn_destroy(
lc_curr.lc_conn = conn; lc_curr.lc_conn = conn;
lc_curr.lc_local_ndn = conn->c_ndn; lc_curr.lc_local_ndn = conn->c_ndn;
ldap_pvt_thread_mutex_lock( &li->conn_mutex ); ldap_pvt_thread_mutex_lock( &li->li_conninfo.lai_mutex );
lc = avl_delete( &li->conntree, (caddr_t)&lc_curr, ldap_back_conn_cmp ); lc = avl_delete( &li->li_conninfo.lai_tree, (caddr_t)&lc_curr, ldap_back_conn_cmp );
ldap_pvt_thread_mutex_unlock( &li->conn_mutex ); ldap_pvt_thread_mutex_unlock( &li->li_conninfo.lai_mutex );
if ( lc ) { if ( lc ) {
Debug( LDAP_DEBUG_TRACE, Debug( LDAP_DEBUG_TRACE,

@ -23,6 +23,7 @@
#include "slap.h" #include "slap.h"
#include "back-ldbm.h" #include "back-ldbm.h"
#include "lutil.h"
int int
ldbm_back_db_config( ldbm_back_db_config(
@ -62,7 +63,12 @@ ldbm_back_db_config(
fname, lineno ); fname, lineno );
return( 1 ); return( 1 );
} }
li->li_mode = strtol( argv[1], NULL, 0 ); if ( lutil_atoix( &li->li_mode, argv[1], 0 ) != 0 ) {
fprintf( stderr,
"%s: line %d: unable to parse mode=\"%s\" in \"mode <mode>\" line\n",
fname, lineno, argv[1] );
return( 1 );
}
/* attribute to index */ /* attribute to index */
} else if ( strcasecmp( argv[0], "index" ) == 0 ) { } else if ( strcasecmp( argv[0], "index" ) == 0 ) {
@ -91,7 +97,12 @@ ldbm_back_db_config(
fname, lineno ); fname, lineno );
return( 1 ); return( 1 );
} }
li->li_cache.c_maxsize = atoi( argv[1] ); if ( lutil_atoi( &li->li_cache.c_maxsize, argv[1] ) != 0 ) {
fprintf( stderr,
"%s: line %d: unable to parse cachesize \"%s\"\n",
fname, lineno, argv[1] );
return( 1 );
}
/* size of each dbcache in bytes */ /* size of each dbcache in bytes */
} else if ( strcasecmp( argv[0], "dbcachesize" ) == 0 ) { } else if ( strcasecmp( argv[0], "dbcachesize" ) == 0 ) {
@ -101,7 +112,12 @@ ldbm_back_db_config(
fname, lineno ); fname, lineno );
return( 1 ); return( 1 );
} }
li->li_dbcachesize = atoi( argv[1] ); if ( lutil_atoi( &li->li_dbcachesize, argv[1] ) ) {
fprintf( stderr,
"%s: line %d: unable to parse dbcachesize \"%s\"\n",
fname, lineno, argv[1] );
return( 1 );
}
/* no locking (not safe) */ /* no locking (not safe) */
} else if ( strcasecmp( argv[0], "dbnolocking" ) == 0 ) { } else if ( strcasecmp( argv[0], "dbnolocking" ) == 0 ) {
@ -124,9 +140,7 @@ ldbm_back_db_config(
return 1; return 1;
} }
i = atoi( argv[1] ); if ( lutil_atoi( &i, argv[1] ) != 0 || i < 0 ) {
if( i < 0 ) {
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"%s: line %d: frquency value (%d) invalid \"dbsync <frequency> [<wait-times> [wait-interval]]\" line\n", "%s: line %d: frquency value (%d) invalid \"dbsync <frequency> [<wait-times> [wait-interval]]\" line\n",
fname, lineno, i ); fname, lineno, i );
@ -136,8 +150,7 @@ ldbm_back_db_config(
li->li_dbsyncfreq = i; li->li_dbsyncfreq = i;
if ( argc > 2 ) { if ( argc > 2 ) {
i = atoi( argv[2] ); if ( lutil_atoi( &i, argv[2] ) != 0 || i < 0 ) {
if ( i < 0 ) {
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"%s: line %d: frquency value (%d) invalid \"dbsync <frequency> [<wait-times> [wait-interval]]\" line\n", "%s: line %d: frquency value (%d) invalid \"dbsync <frequency> [<wait-times> [wait-interval]]\" line\n",
fname, lineno, i ); fname, lineno, i );
@ -147,8 +160,7 @@ ldbm_back_db_config(
} }
if ( argc > 3 ) { if ( argc > 3 ) {
i = atoi( argv[3] ); if ( lutil_atoi( &i, argv[3] ) != 0 || i <= 0 ) {
if ( i <= 0 ) {
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"%s: line %d: frquency value (%d) invalid \"dbsync <frequency> [<wait-times> [wait-interval]]\" line\n", "%s: line %d: frquency value (%d) invalid \"dbsync <frequency> [<wait-times> [wait-interval]]\" line\n",
fname, lineno, i ); fname, lineno, i );

@ -32,9 +32,7 @@ ldbm_back_initialize(
{ {
static char *controls[] = { static char *controls[] = {
LDAP_CONTROL_MANAGEDSAIT, LDAP_CONTROL_MANAGEDSAIT,
#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
LDAP_CONTROL_X_PERMISSIVE_MODIFY, LDAP_CONTROL_X_PERMISSIVE_MODIFY,
#endif
NULL NULL
}; };

@ -417,42 +417,33 @@ searchit:
{ {
scopeok = dnIsSuffix( &e->e_nname, &realbase ); scopeok = dnIsSuffix( &e->e_nname, &realbase );
#ifdef LDAP_SCOPE_SUBORDINATE
} else if ( !scopeok && } else if ( !scopeok &&
op->ors_scope == LDAP_SCOPE_SUBORDINATE ) op->ors_scope == LDAP_SCOPE_SUBORDINATE )
{ {
scopeok = !dn_match( &e->e_nname, &realbase ) scopeok = !dn_match( &e->e_nname, &realbase )
&& dnIsSuffix( &e->e_nname, &realbase ); && dnIsSuffix( &e->e_nname, &realbase );
#endif
} else { } else {
scopeok = 1; scopeok = 1;
} }
if ( scopeok ) { if ( scopeok ) {
/* check size limit */
if ( --op->ors_slimit == -1 ) {
cache_return_entry_r( &li->li_cache, e );
rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;
rs->sr_entry = NULL;
send_ldap_result( op, rs );
rc = LDAP_SUCCESS;
goto done;
}
if (e) { if (e) {
rs->sr_flags = 0; rs->sr_flags = 0;
result = send_search_entry( op, rs ); rs->sr_err = send_search_entry( op, rs );
switch (result) { switch ( rs->sr_err ) {
case 0: /* entry sent ok */ case LDAP_UNAVAILABLE: /* connection closed */
break;
case 1: /* entry not sent */
break;
case -1: /* connection closed */
cache_return_entry_r( &li->li_cache, e ); cache_return_entry_r( &li->li_cache, e );
rc = LDAP_SUCCESS; rc = LDAP_SUCCESS;
goto done; goto done;
case LDAP_SIZELIMIT_EXCEEDED:
cache_return_entry_r( &li->li_cache, e );
rc = rs->sr_err;
rs->sr_entry = NULL;
send_ldap_result( op, rs );
rc = LDAP_SUCCESS;
goto done;
} }
} }

@ -236,8 +236,8 @@ typedef struct metadncache_t {
Avlnode *tree; Avlnode *tree;
#define META_DNCACHE_DISABLED (0) #define META_DNCACHE_DISABLED (0)
#define META_DNCACHE_FOREVER (-1) #define META_DNCACHE_FOREVER ((time_t)(-1))
long int ttl; /* seconds; 0: no cache, -1: no expiry */ time_t ttl; /* seconds; 0: no cache, -1: no expiry */
} metadncache_t; } metadncache_t;
typedef struct metacandidates_t { typedef struct metacandidates_t {
@ -257,18 +257,18 @@ typedef struct metainfo_t {
metadncache_t mi_cache; metadncache_t mi_cache;
ldap_pvt_thread_mutex_t mi_conn_mutex; ldap_avl_info_t mi_conninfo;
Avlnode *mi_conntree;
unsigned flags; unsigned mi_flags;
#define li_flags mi_flags
/* uses flags as defined in <back-ldap/back-ldap.h> */ /* uses flags as defined in <back-ldap/back-ldap.h> */
#define META_BACK_F_ONERR_STOP 0x00010000U #define META_BACK_F_ONERR_STOP 0x00010000U
#define META_BACK_F_DEFER_ROOTDN_BIND 0x00020000U #define META_BACK_F_DEFER_ROOTDN_BIND 0x00020000U
#define META_BACK_ONERR_STOP(mi) ( (mi)->flags & META_BACK_F_ONERR_STOP ) #define META_BACK_ONERR_STOP(mi) ( (mi)->mi_flags & META_BACK_F_ONERR_STOP )
#define META_BACK_ONERR_CONTINUE(mi) ( !META_BACK_ONERR_CONTINUE( (mi) ) ) #define META_BACK_ONERR_CONTINUE(mi) ( !META_BACK_ONERR_CONTINUE( (mi) ) )
#define META_BACK_DEFER_ROOTDN_BIND(mi) ( (mi)->flags & META_BACK_F_DEFER_ROOTDN_BIND ) #define META_BACK_DEFER_ROOTDN_BIND(mi) ( (mi)->mi_flags & META_BACK_F_DEFER_ROOTDN_BIND )
int mi_version; int mi_version;
time_t mi_timeout[ LDAP_BACK_OP_LAST ]; time_t mi_timeout[ LDAP_BACK_OP_LAST ];

@ -206,22 +206,22 @@ meta_back_bind( Operation *op, SlapReply *rs )
/* wait for all other ops to release the connection */ /* wait for all other ops to release the connection */
retry_lock:; retry_lock:;
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
if ( mc->mc_refcnt > 1 ) { if ( mc->mc_refcnt > 1 ) {
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
ldap_pvt_thread_yield(); ldap_pvt_thread_yield();
goto retry_lock; goto retry_lock;
} }
assert( mc->mc_refcnt == 1 ); assert( mc->mc_refcnt == 1 );
mc = avl_delete( &mi->mi_conntree, (caddr_t)mc, mc = avl_delete( &mi->mi_conninfo.lai_tree, (caddr_t)mc,
meta_back_conn_cmp ); meta_back_conn_cmp );
assert( mc != NULL ); assert( mc != NULL );
ber_bvreplace( &mc->mc_local_ndn, &op->o_req_ndn ); ber_bvreplace( &mc->mc_local_ndn, &op->o_req_ndn );
lerr = avl_insert( &mi->mi_conntree, (caddr_t)mc, lerr = avl_insert( &mi->mi_conninfo.lai_tree, (caddr_t)mc,
meta_back_conn_cmp, meta_back_conn_dup ); meta_back_conn_cmp, meta_back_conn_dup );
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
if ( lerr == -1 ) { if ( lerr == -1 ) {
for ( i = 0; i < mi->mi_ntargets; ++i ) { for ( i = 0; i < mi->mi_ntargets; ++i ) {
if ( mc->mc_conns[ i ].msc_ld != NULL ) { if ( mc->mc_conns[ i ].msc_ld != NULL ) {
@ -548,7 +548,7 @@ retry:;
* to avoid circular loops; mc_mutex is set * to avoid circular loops; mc_mutex is set
* by the caller */ * by the caller */
if ( dolock ) { if ( dolock ) {
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
} }
if ( mc->mc_refcnt == 1 ) { if ( mc->mc_refcnt == 1 ) {
@ -571,7 +571,7 @@ retry:;
} }
if ( dolock ) { if ( dolock ) {
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
} }
if ( rc == LDAP_SUCCESS ) { if ( rc == LDAP_SUCCESS ) {

@ -70,13 +70,11 @@ meta_back_is_candidate(
default: default:
return META_CANDIDATE; return META_CANDIDATE;
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE: case LDAP_SCOPE_SUBORDINATE:
if ( ndn->bv_len > nsuffix->bv_len ) { if ( ndn->bv_len > nsuffix->bv_len ) {
return META_CANDIDATE; return META_CANDIDATE;
} }
break; break;
#endif /* LDAP_SCOPE_SUBORDINATE */
/* nearly useless; not allowed by config */ /* nearly useless; not allowed by config */
case LDAP_SCOPE_ONELEVEL: case LDAP_SCOPE_ONELEVEL:

@ -95,12 +95,7 @@ meta_back_db_config(
{ {
metainfo_t *mi = ( metainfo_t * )be->be_private; metainfo_t *mi = ( metainfo_t * )be->be_private;
if ( mi == NULL ) { assert( mi != NULL );
fprintf( stderr,
"%s: line %d: meta backend info is null!\n",
fname, lineno );
return 1;
}
/* URI of server to query */ /* URI of server to query */
if ( strcasecmp( argv[ 0 ], "uri" ) == 0 ) { if ( strcasecmp( argv[ 0 ], "uri" ) == 0 ) {
@ -115,27 +110,27 @@ meta_back_db_config(
switch ( argc ) { switch ( argc ) {
case 1: case 1:
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: missing URI " "%s: line %d: missing URI "
"in \"uri <protocol>://<server>[:port]/<naming context>\" line\n", "in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
case 2: case 2:
break; break;
default: default:
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: too many args " "%s: line %d: too many args "
"in \"uri <protocol>://<server>[:port]/<naming context>\" line\n", "in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
if ( be->be_nsuffix == NULL ) { if ( be->be_nsuffix == NULL ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: the suffix must be defined before any target.\n", "%s: line %d: the suffix must be defined before any target.\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
@ -144,23 +139,23 @@ meta_back_db_config(
mi->mi_targets = ( metatarget_t * )ch_realloc( mi->mi_targets, mi->mi_targets = ( metatarget_t * )ch_realloc( mi->mi_targets,
sizeof( metatarget_t ) * mi->mi_ntargets ); sizeof( metatarget_t ) * mi->mi_ntargets );
if ( mi->mi_targets == NULL ) { if ( mi->mi_targets == NULL ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: out of memory while storing server name" "%s: line %d: out of memory while storing server name"
" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n", " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
if ( new_target( &mi->mi_targets[ i ] ) != 0 ) { if ( new_target( &mi->mi_targets[ i ] ) != 0 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: unable to init server" "%s: line %d: unable to init server"
" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n", " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
mi->mi_targets[ i ].mt_nretries = mi->mi_nretries; mi->mi_targets[ i ].mt_nretries = mi->mi_nretries;
mi->mi_targets[ i ].mt_flags = mi->flags; mi->mi_targets[ i ].mt_flags = mi->mi_flags;
mi->mi_targets[ i ].mt_version = mi->mi_version; mi->mi_targets[ i ].mt_version = mi->mi_version;
for ( c = 0; c < LDAP_BACK_OP_LAST; c++ ) { for ( c = 0; c < LDAP_BACK_OP_LAST; c++ ) {
@ -171,10 +166,10 @@ meta_back_db_config(
* uri MUST be legal! * uri MUST be legal!
*/ */
if ( ldap_url_parselist_ext( &ludp, argv[ 1 ], "\t" ) != LDAP_SUCCESS ) { if ( ldap_url_parselist_ext( &ludp, argv[ 1 ], "\t" ) != LDAP_SUCCESS ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: unable to parse URI" "%s: line %d: unable to parse URI"
" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n", " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
@ -182,10 +177,10 @@ meta_back_db_config(
* uri MUST have the <dn> part! * uri MUST have the <dn> part!
*/ */
if ( ludp->lud_dn == NULL ) { if ( ludp->lud_dn == NULL ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: missing <naming context> " "%s: line %d: missing <naming context> "
" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n", " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} else if ( ludp->lud_dn[ 0 ] == '\0' ) { } else if ( ludp->lud_dn[ 0 ] == '\0' ) {
@ -198,10 +193,10 @@ meta_back_db_config(
} }
if ( BER_BVISNULL( &be->be_nsuffix[ j ] ) ) { if ( BER_BVISNULL( &be->be_nsuffix[ j ] ) ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: missing <naming context> " "%s: line %d: missing <naming context> "
" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n", " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
} }
@ -213,9 +208,9 @@ meta_back_db_config(
rc = dnPrettyNormal( NULL, &dn, &mi->mi_targets[ i ].mt_psuffix, rc = dnPrettyNormal( NULL, &dn, &mi->mi_targets[ i ].mt_psuffix,
&mi->mi_targets[ i ].mt_nsuffix, NULL ); &mi->mi_targets[ i ].mt_nsuffix, NULL );
if( rc != LDAP_SUCCESS ) { if( rc != LDAP_SUCCESS ) {
fprintf( stderr, "%s: line %d: " Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"target '%s' DN is invalid\n", "target \"%s\" DN is invalid\n",
fname, lineno, argv[ 1 ] ); fname, lineno, argv[ 1 ] );
return( 1 ); return( 1 );
} }
@ -227,26 +222,24 @@ meta_back_db_config(
break; break;
case LDAP_SCOPE_SUBTREE: case LDAP_SCOPE_SUBTREE:
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE: case LDAP_SCOPE_SUBORDINATE:
#endif /* LDAP_SCOPE_SUBORDINATE */
mi->mi_targets[ i ].mt_scope = ludp->lud_scope; mi->mi_targets[ i ].mt_scope = ludp->lud_scope;
break; break;
default: default:
fprintf( stderr, "%s: line %d: " Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"invalid scope for target '%s'\n", "invalid scope for target \"%s\"\n",
fname, lineno, argv[ 1 ] ); fname, lineno, argv[ 1 ] );
return( 1 ); return( 1 );
} }
/* check all, to apply the scope check on the first one */ /* check all, to apply the scope check on the first one */
for ( tmpludp = ludp; tmpludp; tmpludp = tmpludp->lud_next ) { for ( tmpludp = ludp; tmpludp; tmpludp = tmpludp->lud_next ) {
if ( tmpludp->lud_dn != NULL && tmpludp->lud_dn[ 0 ] != '\0' ) { if ( tmpludp->lud_dn != NULL && tmpludp->lud_dn[ 0 ] != '\0' ) {
fprintf( stderr, "%s: line %d: " Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"multiple URIs must have " "multiple URIs must have "
"no DN part\n", "no DN part\n",
fname, lineno ); fname, lineno, 0 );
return( 1 ); return( 1 );
} }
@ -255,8 +248,8 @@ meta_back_db_config(
mi->mi_targets[ i ].mt_uri = ldap_url_list2urls( ludp ); mi->mi_targets[ i ].mt_uri = ldap_url_list2urls( ludp );
ldap_free_urllist( ludp ); ldap_free_urllist( ludp );
if ( mi->mi_targets[ i ].mt_uri == NULL) { if ( mi->mi_targets[ i ].mt_uri == NULL) {
fprintf( stderr, "%s: line %d: no memory?\n", Debug( LDAP_DEBUG_ANY, "%s: line %d: no memory?\n",
fname, lineno ); fname, lineno, 0 );
return( 1 ); return( 1 );
} }
@ -265,10 +258,10 @@ meta_back_db_config(
*/ */
#if 0 /* too strict a constraint */ #if 0 /* too strict a constraint */
if ( select_backend( &mi->mi_targets[ i ].suffix, 0, 0 ) != be ) { if ( select_backend( &mi->mi_targets[ i ].suffix, 0, 0 ) != be ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: <naming context> of URI does not refer to current backend" "%s: line %d: <naming context> of URI does not refer to current backend"
" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n", " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
#else #else
@ -276,10 +269,10 @@ meta_back_db_config(
* uri MUST be a branch of a suffix! * uri MUST be a branch of a suffix!
*/ */
if ( select_backend( &mi->mi_targets[ i ].mt_nsuffix, 0, 0 ) == NULL ) { if ( select_backend( &mi->mi_targets[ i ].mt_nsuffix, 0, 0 ) == NULL ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: <naming context> of URI does not resolve to a backend" "%s: line %d: <naming context> of URI does not resolve to a backend"
" in \"uri <protocol>://<server>[:port]/<naming context>\" line\n", " in \"uri <protocol>://<server>[:port]/<naming context>\" line\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
#endif #endif
@ -290,62 +283,85 @@ meta_back_db_config(
if ( argc == 1 ) { if ( argc == 1 ) {
if ( i < 0 ) { if ( i < 0 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: \"default-target\" alone need be" "%s: line %d: \"default-target\" alone need be"
" inside a \"uri\" directive\n", " inside a \"uri\" directive\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
mi->mi_defaulttarget = i; mi->mi_defaulttarget = i;
} else { } else {
if ( strcasecmp( argv[ 1 ], "none" ) == 0 ) { if ( strcasecmp( argv[ 1 ], "none" ) == 0 ) {
if ( i >= 0 ) { if ( i >= 0 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: \"default-target none\"" "%s: line %d: \"default-target none\""
" should go before uri definitions\n", " should go before uri definitions\n",
fname, lineno ); fname, lineno, 0 );
} }
mi->mi_defaulttarget = META_DEFAULT_TARGET_NONE; mi->mi_defaulttarget = META_DEFAULT_TARGET_NONE;
} else { } else {
char *next;
int n = strtol( argv[ 1 ], &next, 10 ); if ( lutil_atoi( &mi->mi_defaulttarget, argv[ 1 ] ) != 0
if ( n < 0 || n >= i - 1 ) { || mi->mi_defaulttarget < 0
fprintf( stderr, || mi->mi_defaulttarget >= i - 1 )
{
Debug( LDAP_DEBUG_ANY,
"%s: line %d: illegal target number %d\n", "%s: line %d: illegal target number %d\n",
fname, lineno, n ); fname, lineno, mi->mi_defaulttarget );
return 1; return 1;
} }
mi->mi_defaulttarget = n;
} }
} }
/* ttl of dn cache */ /* ttl of dn cache */
} else if ( strcasecmp( argv[ 0 ], "dncache-ttl" ) == 0 ) { } else if ( strcasecmp( argv[ 0 ], "dncache-ttl" ) == 0 ) {
if ( argc != 2 ) { if ( argc != 2 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: missing ttl in \"dncache-ttl <ttl>\" line\n", "%s: line %d: missing ttl in \"dncache-ttl <ttl>\" line\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
if ( strcasecmp( argv[ 1 ], "forever" ) == 0 ) { if ( strcasecmp( argv[ 1 ], "forever" ) == 0 ) {
mi->mi_cache.ttl = META_DNCACHE_FOREVER; mi->mi_cache.ttl = META_DNCACHE_FOREVER;
} else if ( strcasecmp( argv[ 1 ], "disabled" ) == 0 ) { } else if ( strcasecmp( argv[ 1 ], "disabled" ) == 0 ) {
mi->mi_cache.ttl = META_DNCACHE_DISABLED; mi->mi_cache.ttl = META_DNCACHE_DISABLED;
} else { } else {
mi->mi_cache.ttl = atol( argv[ 1 ] ); unsigned long t;
if ( lutil_parse_time( argv[ 1 ], &t ) != 0 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: unable to parse ttl \"%s\" in \"dncache-ttl <ttl>\" line\n",
fname, lineno, argv[ 1 ] );
return 1;
}
mi->mi_cache.ttl = (time_t)t;
} }
/* network timeout when connecting to ldap servers */ /* network timeout when connecting to ldap servers */
} else if ( strcasecmp( argv[ 0 ], "network-timeout" ) == 0 ) { } else if ( strcasecmp( argv[ 0 ], "network-timeout" ) == 0 ) {
unsigned long t;
if ( argc != 2 ) { if ( argc != 2 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: missing network timeout in \"network-timeout <seconds>\" line\n", "%s: line %d: missing network timeout in \"network-timeout <seconds>\" line\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
mi->mi_network_timeout = atol(argv[ 1 ]);
if ( lutil_parse_time( argv[ 1 ], &t ) ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: unable to parse timeout \"%s\" in \"network-timeout <seconds>\" line\n",
fname, lineno, argv[ 1 ] );
return 1;
}
mi->mi_network_timeout = (int)t;
/* name to use for meta_back_group */ /* name to use for meta_back_group */
} else if ( strcasecmp( argv[ 0 ], "acl-authcDN" ) == 0 } else if ( strcasecmp( argv[ 0 ], "acl-authcDN" ) == 0
@ -355,24 +371,24 @@ meta_back_db_config(
struct berval dn; struct berval dn;
if ( i < 0 ) { if ( i < 0 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: need \"uri\" directive first\n", "%s: line %d: need \"uri\" directive first\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
if ( argc != 2 ) { if ( argc != 2 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: missing name in \"binddn <name>\" line\n", "%s: line %d: missing name in \"binddn <name>\" line\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
if ( strcasecmp( argv[ 0 ], "binddn" ) == 0 ) { if ( strcasecmp( argv[ 0 ], "binddn" ) == 0 ) {
fprintf( stderr, "%s: line %d: " Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"\"binddn\" statement is deprecated; " "\"binddn\" statement is deprecated; "
"use \"acl-authcDN\" instead\n", "use \"acl-authcDN\" instead\n",
fname, lineno ); fname, lineno, 0 );
/* FIXME: some day we'll need to throw an error */ /* FIXME: some day we'll need to throw an error */
} }
@ -381,7 +397,7 @@ meta_back_db_config(
if ( dnNormalize( 0, NULL, NULL, &dn, &mi->mi_targets[ i ].mt_binddn, if ( dnNormalize( 0, NULL, NULL, &dn, &mi->mi_targets[ i ].mt_binddn,
NULL ) != LDAP_SUCCESS ) NULL ) != LDAP_SUCCESS )
{ {
fprintf( stderr, "%s: line %d: " Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"bind DN '%s' is invalid\n", "bind DN '%s' is invalid\n",
fname, lineno, argv[ 1 ] ); fname, lineno, argv[ 1 ] );
return( 1 ); return( 1 );
@ -394,24 +410,24 @@ meta_back_db_config(
int i = mi->mi_ntargets - 1; int i = mi->mi_ntargets - 1;
if ( i < 0 ) { if ( i < 0 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: need \"uri\" directive first\n", "%s: line %d: need \"uri\" directive first\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
if ( argc != 2 ) { if ( argc != 2 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: missing password in \"bindpw <password>\" line\n", "%s: line %d: missing password in \"bindpw <password>\" line\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
if ( strcasecmp( argv[ 0 ], "bindpw" ) == 0 ) { if ( strcasecmp( argv[ 0 ], "bindpw" ) == 0 ) {
fprintf( stderr, "%s: line %d: " Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"\"bindpw\" statement is deprecated; " "\"bindpw\" statement is deprecated; "
"use \"acl-passwd\" instead\n", "use \"acl-passwd\" instead\n",
fname, lineno ); fname, lineno, 0 );
/* FIXME: some day we'll need to throw an error */ /* FIXME: some day we'll need to throw an error */
} }
@ -420,30 +436,30 @@ meta_back_db_config(
/* save bind creds for referral rebinds? */ /* save bind creds for referral rebinds? */
} else if ( strcasecmp( argv[ 0 ], "rebind-as-user" ) == 0 ) { } else if ( strcasecmp( argv[ 0 ], "rebind-as-user" ) == 0 ) {
if ( argc > 2 ) { if ( argc > 2 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: \"rebind-as-user {NO|yes}\" takes 1 argument.\n", "%s: line %d: \"rebind-as-user {NO|yes}\" takes 1 argument.\n",
fname, lineno ); fname, lineno, 0 );
return( 1 ); return( 1 );
} }
if ( argc == 1 ) { if ( argc == 1 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: deprecated use of \"rebind-as-user {FALSE|true}\" with no arguments.\n", "%s: line %d: deprecated use of \"rebind-as-user {FALSE|true}\" with no arguments.\n",
fname, lineno ); fname, lineno, 0 );
mi->flags |= LDAP_BACK_F_SAVECRED; mi->mi_flags |= LDAP_BACK_F_SAVECRED;
} else { } else {
switch ( check_true_false( argv[ 1 ] ) ) { switch ( check_true_false( argv[ 1 ] ) ) {
case 0: case 0:
mi->flags &= ~LDAP_BACK_F_SAVECRED; mi->mi_flags &= ~LDAP_BACK_F_SAVECRED;
break; break;
case 1: case 1:
mi->flags |= LDAP_BACK_F_SAVECRED; mi->mi_flags |= LDAP_BACK_F_SAVECRED;
break; break;
default: default:
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: \"rebind-as-user {FALSE|true}\" unknown argument \"%s\".\n", "%s: line %d: \"rebind-as-user {FALSE|true}\" unknown argument \"%s\".\n",
fname, lineno, argv[ 1 ] ); fname, lineno, argv[ 1 ] );
return 1; return 1;
@ -453,12 +469,12 @@ meta_back_db_config(
} else if ( strcasecmp( argv[ 0 ], "chase-referrals" ) == 0 ) { } else if ( strcasecmp( argv[ 0 ], "chase-referrals" ) == 0 ) {
unsigned *flagsp = mi->mi_ntargets ? unsigned *flagsp = mi->mi_ntargets ?
&mi->mi_targets[ mi->mi_ntargets - 1 ].mt_flags &mi->mi_targets[ mi->mi_ntargets - 1 ].mt_flags
: &mi->flags; : &mi->mi_flags;
if ( argc != 2 ) { if ( argc != 2 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: \"chase-referrals {TRUE|false}\" needs 1 argument.\n", "%s: line %d: \"chase-referrals {TRUE|false}\" needs 1 argument.\n",
fname, lineno ); fname, lineno, 0 );
return( 1 ); return( 1 );
} }
@ -473,21 +489,21 @@ meta_back_db_config(
break; break;
default: default:
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: \"chase-referrals {TRUE|false}\": unknown argument \"%s\".\n", "%s: line %d: \"chase-referrals {TRUE|false}\": unknown argument \"%s\".\n",
fname, lineno, argv[ 1 ] ); fname, lineno, argv[ 1 ] );
return( 1 ); return( 1 );
} }
} else if ( strcasecmp( argv[ 0 ], "tls" ) == 0 ) { } else if ( strcasecmp( argv[ 0 ], "tls" ) == 0 ) {
unsigned *flagsp = mi->mi_ntargets ? unsigned *flagsp = mi->mi_ntargets ?
&mi->mi_targets[ mi->mi_ntargets - 1 ].mt_flags &mi->mi_targets[ mi->mi_ntargets - 1 ].mt_flags
: &mi->flags; : &mi->mi_flags;
if ( argc != 2 ) { if ( argc != 2 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: \"tls <what>\" needs 1 argument.\n", "%s: line %d: \"tls <what>\" needs 1 argument.\n",
fname, lineno ); fname, lineno, 0 );
return( 1 ); return( 1 );
} }
@ -510,21 +526,21 @@ meta_back_db_config(
*flagsp |= LDAP_BACK_F_PROPAGATE_TLS; *flagsp |= LDAP_BACK_F_PROPAGATE_TLS;
} else { } else {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: \"tls <what>\": unknown argument \"%s\".\n", "%s: line %d: \"tls <what>\": unknown argument \"%s\".\n",
fname, lineno, argv[ 1 ] ); fname, lineno, argv[ 1 ] );
return( 1 ); return( 1 );
} }
} else if ( strcasecmp( argv[ 0 ], "t-f-support" ) == 0 ) { } else if ( strcasecmp( argv[ 0 ], "t-f-support" ) == 0 ) {
unsigned *flagsp = mi->mi_ntargets ? unsigned *flagsp = mi->mi_ntargets ?
&mi->mi_targets[ mi->mi_ntargets - 1 ].mt_flags &mi->mi_targets[ mi->mi_ntargets - 1 ].mt_flags
: &mi->flags; : &mi->mi_flags;
if ( argc != 2 ) { if ( argc != 2 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: \"t-f-support {FALSE|true|discover}\" needs 1 argument.\n", "%s: line %d: \"t-f-support {FALSE|true|discover}\" needs 1 argument.\n",
fname, lineno ); fname, lineno, 0 );
return( 1 ); return( 1 );
} }
@ -542,7 +558,7 @@ meta_back_db_config(
*flagsp |= LDAP_BACK_F_SUPPORT_T_F_DISCOVER; *flagsp |= LDAP_BACK_F_SUPPORT_T_F_DISCOVER;
} else { } else {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: unknown value \"%s\" for \"t-f-support {no|yes|discover}\".\n", "%s: line %d: unknown value \"%s\" for \"t-f-support {no|yes|discover}\".\n",
fname, lineno, argv[ 1 ] ); fname, lineno, argv[ 1 ] );
return 1; return 1;
@ -553,20 +569,20 @@ meta_back_db_config(
/* onerr? */ /* onerr? */
} else if ( strcasecmp( argv[ 0 ], "onerr" ) == 0 ) { } else if ( strcasecmp( argv[ 0 ], "onerr" ) == 0 ) {
if ( argc != 2 ) { if ( argc != 2 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: \"onerr {CONTINUE|stop}\" takes 1 argument\n", "%s: line %d: \"onerr {CONTINUE|stop}\" takes 1 argument\n",
fname, lineno ); fname, lineno, 0 );
return( 1 ); return( 1 );
} }
if ( strcasecmp( argv[ 1 ], "continue" ) == 0 ) { if ( strcasecmp( argv[ 1 ], "continue" ) == 0 ) {
mi->flags &= ~META_BACK_F_ONERR_STOP; mi->mi_flags &= ~META_BACK_F_ONERR_STOP;
} else if ( strcasecmp( argv[ 1 ], "stop" ) == 0 ) { } else if ( strcasecmp( argv[ 1 ], "stop" ) == 0 ) {
mi->flags |= META_BACK_F_ONERR_STOP; mi->mi_flags |= META_BACK_F_ONERR_STOP;
} else { } else {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: \"onerr {CONTINUE|stop}\": invalid arg \"%s\".\n", "%s: line %d: \"onerr {CONTINUE|stop}\": invalid arg \"%s\".\n",
fname, lineno, argv[ 1 ] ); fname, lineno, argv[ 1 ] );
return 1; return 1;
@ -575,44 +591,45 @@ meta_back_db_config(
/* bind-defer? */ /* bind-defer? */
} else if ( strcasecmp( argv[ 0 ], "pseudoroot-bind-defer" ) == 0 ) { } else if ( strcasecmp( argv[ 0 ], "pseudoroot-bind-defer" ) == 0 ) {
if ( argc != 2 ) { if ( argc != 2 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: \"pseudoroot-bind-defer {FALSE|true}\" takes 1 argument\n", "%s: line %d: \"pseudoroot-bind-defer {FALSE|true}\" takes 1 argument\n",
fname, lineno ); fname, lineno, 0 );
return( 1 ); return( 1 );
} }
switch ( check_true_false( argv[ 1 ] ) ) { switch ( check_true_false( argv[ 1 ] ) ) {
case 0: case 0:
mi->flags &= ~META_BACK_F_DEFER_ROOTDN_BIND; mi->mi_flags &= ~META_BACK_F_DEFER_ROOTDN_BIND;
break; break;
case 1: case 1:
mi->flags |= META_BACK_F_DEFER_ROOTDN_BIND; mi->mi_flags |= META_BACK_F_DEFER_ROOTDN_BIND;
break; break;
default: default:
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: \"pseudoroot-bind-defer {FALSE|true}\": invalid arg \"%s\".\n", "%s: line %d: \"pseudoroot-bind-defer {FALSE|true}\": invalid arg \"%s\".\n",
fname, lineno, argv[ 1 ] ); fname, lineno, argv[ 1 ] );
return 1; return 1;
} }
} else if ( strcasecmp( argv[ 0 ], "timeout" ) == 0 ) { } else if ( strcasecmp( argv[ 0 ], "timeout" ) == 0 ) {
char *sep, *next; char *sep;
time_t *tv = mi->mi_ntargets ? time_t *tv = mi->mi_ntargets ?
mi->mi_targets[ mi->mi_ntargets - 1 ].mt_timeout mi->mi_targets[ mi->mi_ntargets - 1 ].mt_timeout
: mi->mi_timeout; : mi->mi_timeout;
int c; int c;
if ( argc < 2 ) { if ( argc < 2 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: \"timeout [{add|delete|modify|modrdn}=]<val> [...]\" takes at least 1 argument\n", "%s: line %d: \"timeout [{add|delete|modify|modrdn}=]<val> [...]\" takes at least 1 argument\n",
fname, lineno ); fname, lineno, 0 );
return( 1 ); return( 1 );
} }
for ( c = 1; c < argc; c++ ) { for ( c = 1; c < argc; c++ ) {
time_t *t = NULL, val; time_t *t = NULL;
unsigned long val;
sep = strchr( argv[ c ], '=' ); sep = strchr( argv[ c ], '=' );
if ( sep != NULL ) { if ( sep != NULL ) {
@ -627,9 +644,13 @@ meta_back_db_config(
} else if ( strncasecmp( argv[ c ], "modrdn", len ) == 0 ) { } else if ( strncasecmp( argv[ c ], "modrdn", len ) == 0 ) {
t = &tv[ LDAP_BACK_OP_MODRDN ]; t = &tv[ LDAP_BACK_OP_MODRDN ];
} else { } else {
fprintf( stderr, char buf[ SLAP_TEXT_BUFLEN ];
"%s: line %d: unknown operation \"%s\" for timeout #%d.\n", snprintf( buf, sizeof( buf ),
fname, lineno, argv[ c ], c ); "unknown operation \"%s\" for timeout #%d",
argv[ c ], c );
Debug( LDAP_DEBUG_ANY,
"%s: line %d: %s.\n",
fname, lineno, buf );
return 1; return 1;
} }
sep++; sep++;
@ -638,22 +659,21 @@ meta_back_db_config(
sep = argv[ c ]; sep = argv[ c ];
} }
val = strtoul( sep, &next, 10 ); if ( lutil_parse_time( sep, &val ) != 0 ) {
if ( next == sep || next[ 0 ] != '\0' ) { Debug( LDAP_DEBUG_ANY,
fprintf( stderr,
"%s: line %d: unable to parse value \"%s\" for timeout.\n", "%s: line %d: unable to parse value \"%s\" for timeout.\n",
fname, lineno, sep ); fname, lineno, sep );
return 1; return 1;
} }
if ( t ) { if ( t ) {
*t = val; *t = (time_t)val;
} else { } else {
int i; int i;
for ( i = 0; i < LDAP_BACK_OP_LAST; i++ ) { for ( i = 0; i < LDAP_BACK_OP_LAST; i++ ) {
tv[ i ] = val; tv[ i ] = (time_t)val;
} }
} }
} }
@ -664,16 +684,16 @@ meta_back_db_config(
struct berval dn; struct berval dn;
if ( i < 0 ) { if ( i < 0 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: need \"uri\" directive first\n", "%s: line %d: need \"uri\" directive first\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
if ( argc != 2 ) { if ( argc != 2 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: missing name in \"pseudorootdn <name>\" line\n", "%s: line %d: missing name in \"pseudorootdn <name>\" line\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
@ -682,7 +702,7 @@ meta_back_db_config(
if ( dnNormalize( 0, NULL, NULL, &dn, if ( dnNormalize( 0, NULL, NULL, &dn,
&mi->mi_targets[ i ].mt_pseudorootdn, NULL ) != LDAP_SUCCESS ) &mi->mi_targets[ i ].mt_pseudorootdn, NULL ) != LDAP_SUCCESS )
{ {
fprintf( stderr, "%s: line %d: " Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"pseudoroot DN '%s' is invalid\n", "pseudoroot DN '%s' is invalid\n",
fname, lineno, argv[ 1 ] ); fname, lineno, argv[ 1 ] );
return( 1 ); return( 1 );
@ -693,16 +713,16 @@ meta_back_db_config(
int i = mi->mi_ntargets - 1; int i = mi->mi_ntargets - 1;
if ( i < 0 ) { if ( i < 0 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: need \"uri\" directive first\n", "%s: line %d: need \"uri\" directive first\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
if ( argc != 2 ) { if ( argc != 2 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: missing password in \"pseudorootpw <password>\" line\n", "%s: line %d: missing password in \"pseudorootpw <password>\" line\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
ber_str2bv( argv[ 1 ], 0L, 1, &mi->mi_targets[ i ].mt_pseudorootpw ); ber_str2bv( argv[ 1 ], 0L, 1, &mi->mi_targets[ i ].mt_pseudorootpw );
@ -714,9 +734,9 @@ meta_back_db_config(
struct berval dn, nvnc, pvnc, nrnc, prnc; struct berval dn, nvnc, pvnc, nrnc, prnc;
if ( i < 0 ) { if ( i < 0 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: need \"uri\" directive first\n", "%s: line %d: need \"uri\" directive first\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
@ -732,15 +752,15 @@ meta_back_db_config(
* current server * current server
*/ */
if ( argc != 3 ) { if ( argc != 3 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: syntax is \"suffixMassage <suffix> <massaged suffix>\"\n", "%s: line %d: syntax is \"suffixMassage <suffix> <massaged suffix>\"\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
ber_str2bv( argv[ 1 ], 0, 0, &dn ); ber_str2bv( argv[ 1 ], 0, 0, &dn );
if ( dnPrettyNormal( NULL, &dn, &pvnc, &nvnc, NULL ) != LDAP_SUCCESS ) { if ( dnPrettyNormal( NULL, &dn, &pvnc, &nvnc, NULL ) != LDAP_SUCCESS ) {
fprintf( stderr, "%s: line %d: " Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"suffix '%s' is invalid\n", "suffix '%s' is invalid\n",
fname, lineno, argv[ 1 ] ); fname, lineno, argv[ 1 ] );
return 1; return 1;
@ -748,10 +768,10 @@ meta_back_db_config(
tmp_be = select_backend( &nvnc, 0, 0 ); tmp_be = select_backend( &nvnc, 0, 0 );
if ( tmp_be != NULL && tmp_be != be ) { if ( tmp_be != NULL && tmp_be != be ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: suffix already in use by another backend in" "%s: line %d: suffix already in use by another backend in"
" \"suffixMassage <suffix> <massaged suffix>\"\n", " \"suffixMassage <suffix> <massaged suffix>\"\n",
fname, lineno ); fname, lineno, 0 );
free( pvnc.bv_val ); free( pvnc.bv_val );
free( nvnc.bv_val ); free( nvnc.bv_val );
return 1; return 1;
@ -759,9 +779,9 @@ meta_back_db_config(
ber_str2bv( argv[ 2 ], 0, 0, &dn ); ber_str2bv( argv[ 2 ], 0, 0, &dn );
if ( dnPrettyNormal( NULL, &dn, &prnc, &nrnc, NULL ) != LDAP_SUCCESS ) { if ( dnPrettyNormal( NULL, &dn, &prnc, &nrnc, NULL ) != LDAP_SUCCESS ) {
fprintf( stderr, "%s: line %d: " Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"massaged suffix '%s' is invalid\n", "massaged suffix '%s' is invalid\n",
fname, lineno, argv[ 2 ] ); fname, lineno, argv[ 2 ] );
free( pvnc.bv_val ); free( pvnc.bv_val );
free( nvnc.bv_val ); free( nvnc.bv_val );
return 1; return 1;
@ -770,10 +790,10 @@ meta_back_db_config(
#if 0 #if 0
tmp_be = select_backend( &nrnc, 0, 0 ); tmp_be = select_backend( &nrnc, 0, 0 );
if ( tmp_be != NULL ) { if ( tmp_be != NULL ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: massaged suffix already in use by another backend in" "%s: line %d: massaged suffix already in use by another backend in"
" \"suffixMassage <suffix> <massaged suffix>\"\n", " \"suffixMassage <suffix> <massaged suffix>\"\n",
fname, lineno ); fname, lineno, 0 );
free( pvnc.bv_val ); free( pvnc.bv_val );
free( nvnc.bv_val ); free( nvnc.bv_val );
free( prnc.bv_val ); free( prnc.bv_val );
@ -803,9 +823,9 @@ meta_back_db_config(
int i = mi->mi_ntargets - 1; int i = mi->mi_ntargets - 1;
if ( i < 0 ) { if ( i < 0 ) {
fprintf( stderr, "%s: line %d: \"rewrite\" " Debug( LDAP_DEBUG_ANY, "%s: line %d: \"rewrite\" "
"statement outside target definition.\n", "statement outside target definition.\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
@ -817,9 +837,9 @@ meta_back_db_config(
int i = mi->mi_ntargets - 1; int i = mi->mi_ntargets - 1;
if ( i < 0 ) { if ( i < 0 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: need \"uri\" directive first\n", "%s: line %d: need \"uri\" directive first\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
@ -832,9 +852,9 @@ meta_back_db_config(
int nretries = META_RETRY_UNDEFINED; int nretries = META_RETRY_UNDEFINED;
if ( argc != 2 ) { if ( argc != 2 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: need value in \"nretries <value>\"\n", "%s: line %d: need value in \"nretries <value>\"\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
@ -845,11 +865,8 @@ meta_back_db_config(
nretries = META_RETRY_NEVER; nretries = META_RETRY_NEVER;
} else { } else {
char *next; if ( lutil_atoi( &nretries, argv[ 1 ] ) != 0 ) {
Debug( LDAP_DEBUG_ANY,
nretries = strtol( argv[ 1 ], &next, 10 );
if ( next == argv[ 1 ] || next[ 0 ] != '\0' ) {
fprintf( stderr,
"%s: line %d: unable to parse value \"%s\" in \"nretries <value>\"\n", "%s: line %d: unable to parse value \"%s\" in \"nretries <value>\"\n",
fname, lineno, argv[ 1 ] ); fname, lineno, argv[ 1 ] );
return 1; return 1;
@ -885,9 +902,9 @@ ldap_back_map_config(
int is_oc = 0; int is_oc = 0;
if ( argc < 3 || argc > 4 ) { if ( argc < 3 || argc > 4 ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: syntax is \"map {objectclass | attribute} [<local> | *] {<foreign> | *}\"\n", "%s: line %d: syntax is \"map {objectclass | attribute} [<local> | *] {<foreign> | *}\"\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
@ -899,10 +916,10 @@ ldap_back_map_config(
map = at_map; map = at_map;
} else { } else {
fprintf( stderr, "%s: line %d: syntax is " Debug( LDAP_DEBUG_ANY, "%s: line %d: syntax is "
"\"map {objectclass | attribute} [<local> | *] " "\"map {objectclass | attribute} [<local> | *] "
"{<foreign> | *}\"\n", "{<foreign> | *}\"\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
@ -926,17 +943,17 @@ ldap_back_map_config(
&& ( strcasecmp( src, "objectclass" ) == 0 && ( strcasecmp( src, "objectclass" ) == 0
|| strcasecmp( dst, "objectclass" ) == 0 ) ) || strcasecmp( dst, "objectclass" ) == 0 ) )
{ {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: objectclass attribute cannot be mapped\n", "%s: line %d: objectclass attribute cannot be mapped\n",
fname, lineno ); fname, lineno, 0 );
} }
mapping = (struct ldapmapping *)ch_calloc( 2, mapping = (struct ldapmapping *)ch_calloc( 2,
sizeof(struct ldapmapping) ); sizeof(struct ldapmapping) );
if ( mapping == NULL ) { if ( mapping == NULL ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: out of memory\n", "%s: line %d: out of memory\n",
fname, lineno ); fname, lineno, 0 );
return 1; return 1;
} }
ber_str2bv( src, 0, 1, &mapping[ 0 ].src ); ber_str2bv( src, 0, 1, &mapping[ 0 ].src );
@ -950,7 +967,7 @@ ldap_back_map_config(
if ( is_oc ) { if ( is_oc ) {
if ( src[ 0 ] != '\0' ) { if ( src[ 0 ] != '\0' ) {
if ( oc_bvfind( &mapping[ 0 ].src ) == NULL ) { if ( oc_bvfind( &mapping[ 0 ].src ) == NULL ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: warning, source objectClass '%s' " "%s: line %d: warning, source objectClass '%s' "
"should be defined in schema\n", "should be defined in schema\n",
fname, lineno, src ); fname, lineno, src );
@ -963,7 +980,7 @@ ldap_back_map_config(
} }
if ( oc_bvfind( &mapping[ 0 ].dst ) == NULL ) { if ( oc_bvfind( &mapping[ 0 ].dst ) == NULL ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: warning, destination objectClass '%s' " "%s: line %d: warning, destination objectClass '%s' "
"is not defined in schema\n", "is not defined in schema\n",
fname, lineno, dst ); fname, lineno, dst );
@ -976,7 +993,7 @@ ldap_back_map_config(
if ( src[ 0 ] != '\0' ) { if ( src[ 0 ] != '\0' ) {
rc = slap_bv2ad( &mapping[ 0 ].src, &ad, &text ); rc = slap_bv2ad( &mapping[ 0 ].src, &ad, &text );
if ( rc != LDAP_SUCCESS ) { if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: warning, source attributeType '%s' " "%s: line %d: warning, source attributeType '%s' "
"should be defined in schema\n", "should be defined in schema\n",
fname, lineno, src ); fname, lineno, src );
@ -992,10 +1009,14 @@ ldap_back_map_config(
rc = slap_bv2undef_ad( &mapping[ 0 ].src, rc = slap_bv2undef_ad( &mapping[ 0 ].src,
&ad, &text, SLAP_AD_PROXIED ); &ad, &text, SLAP_AD_PROXIED );
if ( rc != LDAP_SUCCESS ) { if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, char buf[ SLAP_TEXT_BUFLEN ];
"%s: line %d: source attributeType '%s': %d (%s)\n",
fname, lineno, src, snprintf( buf, sizeof( buf ),
rc, text ? text : "" ); "source attributeType \"%s\": %d (%s)",
src, rc, text ? text : "" );
Debug( LDAP_DEBUG_ANY,
"%s: line %d: %s\n",
fname, lineno, buf );
goto error_return; goto error_return;
} }
} }
@ -1005,7 +1026,7 @@ ldap_back_map_config(
rc = slap_bv2ad( &mapping[ 0 ].dst, &ad, &text ); rc = slap_bv2ad( &mapping[ 0 ].dst, &ad, &text );
if ( rc != LDAP_SUCCESS ) { if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: warning, destination attributeType '%s' " "%s: line %d: warning, destination attributeType '%s' "
"is not defined in schema\n", "is not defined in schema\n",
fname, lineno, dst ); fname, lineno, dst );
@ -1018,10 +1039,14 @@ ldap_back_map_config(
rc = slap_bv2undef_ad( &mapping[ 0 ].dst, rc = slap_bv2undef_ad( &mapping[ 0 ].dst,
&ad, &text, SLAP_AD_PROXIED ); &ad, &text, SLAP_AD_PROXIED );
if ( rc != LDAP_SUCCESS ) { if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, char buf[ SLAP_TEXT_BUFLEN ];
"%s: line %d: source attributeType '%s': %d (%s)\n",
fname, lineno, dst, snprintf( buf, sizeof( buf ),
rc, text ? text : "" ); "source attributeType \"%s\": %d (%s)\n",
dst, rc, text ? text : "" );
Debug( LDAP_DEBUG_ANY,
"%s: line %d: %s\n",
fname, lineno, buf );
return 1; return 1;
} }
} }
@ -1030,9 +1055,9 @@ ldap_back_map_config(
if ( (src[ 0 ] != '\0' && avl_find( map->map, (caddr_t)&mapping[ 0 ], mapping_cmp ) != NULL) if ( (src[ 0 ] != '\0' && avl_find( map->map, (caddr_t)&mapping[ 0 ], mapping_cmp ) != NULL)
|| avl_find( map->remap, (caddr_t)&mapping[ 1 ], mapping_cmp ) != NULL) || avl_find( map->remap, (caddr_t)&mapping[ 1 ], mapping_cmp ) != NULL)
{ {
fprintf( stderr, Debug( LDAP_DEBUG_ANY,
"%s: line %d: duplicate mapping found" SLAPD_CONF_UNKNOWN_IGNORED ".\n", "%s: line %d: duplicate mapping found" SLAPD_CONF_UNKNOWN_IGNORED ".\n",
fname, lineno ); fname, lineno, 0 );
goto error_return; goto error_return;
} }

@ -186,13 +186,13 @@ meta_back_freeconn(
assert( mc != NULL ); assert( mc != NULL );
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
if ( --mc->mc_refcnt == 0 ) { if ( --mc->mc_refcnt == 0 ) {
meta_back_conn_free( mc ); meta_back_conn_free( mc );
} }
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
} }
/* /*
@ -444,13 +444,13 @@ meta_back_retry(
metasingleconn_t *msc = &mc->mc_conns[ candidate ]; metasingleconn_t *msc = &mc->mc_conns[ candidate ];
retry_lock:; retry_lock:;
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
assert( mc->mc_refcnt > 0 ); assert( mc->mc_refcnt > 0 );
if ( mc->mc_refcnt == 1 ) { if ( mc->mc_refcnt == 1 ) {
while ( ldap_pvt_thread_mutex_trylock( &mc->mc_mutex ) ) { while ( ldap_pvt_thread_mutex_trylock( &mc->mc_mutex ) ) {
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
ldap_pvt_thread_yield(); ldap_pvt_thread_yield();
goto retry_lock; goto retry_lock;
} }
@ -483,7 +483,7 @@ retry_lock:;
mc->mc_tainted = 1; mc->mc_tainted = 1;
} }
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
return rc == LDAP_SUCCESS ? 1 : 0; return rc == LDAP_SUCCESS ? 1 : 0;
} }
@ -734,20 +734,20 @@ meta_back_getconn(
} }
/* Searches for a metaconn in the avl tree */ /* Searches for a metaconn in the avl tree */
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
mc = (metaconn_t *)avl_find( mi->mi_conntree, mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree,
(caddr_t)&mc_curr, meta_back_conn_cmp ); (caddr_t)&mc_curr, meta_back_conn_cmp );
if ( mc ) { if ( mc ) {
if ( mc->mc_tainted ) { if ( mc->mc_tainted ) {
rs->sr_err = LDAP_UNAVAILABLE; rs->sr_err = LDAP_UNAVAILABLE;
rs->sr_text = "remote server unavailable"; rs->sr_text = "remote server unavailable";
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
return NULL; return NULL;
} }
mc->mc_refcnt++; mc->mc_refcnt++;
} }
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
switch ( op->o_tag ) { switch ( op->o_tag ) {
case LDAP_REQ_ADD: case LDAP_REQ_ADD:
@ -927,13 +927,13 @@ meta_back_getconn(
/* Retries searching for a metaconn in the avl tree /* Retries searching for a metaconn in the avl tree
* the reason is that the connection might have been * the reason is that the connection might have been
* created by meta_back_get_candidate() */ * created by meta_back_get_candidate() */
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
mc = (metaconn_t *)avl_find( mi->mi_conntree, mc = (metaconn_t *)avl_find( mi->mi_conninfo.lai_tree,
(caddr_t)&mc_curr, meta_back_conn_cmp ); (caddr_t)&mc_curr, meta_back_conn_cmp );
if ( mc != NULL ) { if ( mc != NULL ) {
mc->mc_refcnt++; mc->mc_refcnt++;
} }
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
/* Looks like we didn't get a bind. Open a new session... */ /* Looks like we didn't get a bind. Open a new session... */
if ( mc == NULL ) { if ( mc == NULL ) {
@ -1088,15 +1088,15 @@ done:;
/* /*
* Inserts the newly created metaconn in the avl tree * Inserts the newly created metaconn in the avl tree
*/ */
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
err = avl_insert( &mi->mi_conntree, ( caddr_t )mc, err = avl_insert( &mi->mi_conninfo.lai_tree, ( caddr_t )mc,
meta_back_conn_cmp, meta_back_conn_dup ); meta_back_conn_cmp, meta_back_conn_dup );
#if PRINT_CONNTREE > 0 #if PRINT_CONNTREE > 0
myprint( mi->mi_conntree ); myprint( mi->mi_conninfo.lai_tree );
#endif /* PRINT_CONNTREE */ #endif /* PRINT_CONNTREE */
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
/* /*
* Err could be -1 in case a duplicate metaconn is inserted * Err could be -1 in case a duplicate metaconn is inserted
@ -1144,13 +1144,13 @@ meta_back_release_conn(
assert( mc != NULL ); assert( mc != NULL );
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
assert( mc->mc_refcnt > 0 ); assert( mc->mc_refcnt > 0 );
mc->mc_refcnt--; mc->mc_refcnt--;
if ( mc->mc_refcnt == 0 && mc->mc_tainted ) { if ( mc->mc_refcnt == 0 && mc->mc_tainted ) {
(void)avl_delete( &mi->mi_conntree, ( caddr_t )mc, (void)avl_delete( &mi->mi_conninfo.lai_tree, ( caddr_t )mc,
meta_back_conn_cmp ); meta_back_conn_cmp );
meta_back_conn_free( mc ); meta_back_conn_free( mc );
} }
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
} }

@ -94,7 +94,6 @@ meta_dncache_get_target(
{ {
metadncacheentry_t tmp_entry, metadncacheentry_t tmp_entry,
*entry; *entry;
time_t curr_time;
int target = META_TARGET_NONE; int target = META_TARGET_NONE;
assert( cache != NULL ); assert( cache != NULL );
@ -116,13 +115,7 @@ meta_dncache_get_target(
target = entry->target; target = entry->target;
} else { } else {
if ( entry->lastupdated+cache->ttl > slap_get_time() ) {
/*
* Need mutex?
*/
curr_time = time( NULL );
if ( entry->lastupdated+cache->ttl > curr_time ) {
target = entry->target; target = entry->target;
} }
} }
@ -158,11 +151,7 @@ meta_dncache_update_entry(
* else, cache is used with ttl * else, cache is used with ttl
*/ */
if ( cache->ttl > 0 ) { if ( cache->ttl > 0 ) {
curr_time = slap_get_time();
/*
* Need mutex?
*/
curr_time = time( NULL );
} }
tmp_entry.dn = *ndn; tmp_entry.dn = *ndn;
@ -178,18 +167,23 @@ meta_dncache_update_entry(
} else { } else {
entry = ch_malloc( sizeof( metadncacheentry_t ) + ndn->bv_len + 1 ); entry = ch_malloc( sizeof( metadncacheentry_t ) + ndn->bv_len + 1 );
if ( entry == NULL ) { if ( entry == NULL ) {
ldap_pvt_thread_mutex_unlock( &cache->mutex ); err = -1;
return -1; goto error_return;
} }
entry->dn.bv_len = ndn->bv_len;
entry->dn.bv_val = (char *)&entry[ 1 ]; entry->dn.bv_val = (char *)&entry[ 1 ];
AC_MEMCPY( entry->dn.bv_val, ndn->bv_val, ndn->bv_len + 1 ); AC_MEMCPY( entry->dn.bv_val, ndn->bv_val, ndn->bv_len );
entry->dn.bv_val[ ndn->bv_len ] = '\0';
entry->target = target; entry->target = target;
entry->lastupdated = curr_time; entry->lastupdated = curr_time;
err = avl_insert( &cache->tree, ( caddr_t )entry, err = avl_insert( &cache->tree, ( caddr_t )entry,
meta_dncache_cmp, meta_dncache_dup ); meta_dncache_cmp, meta_dncache_dup );
} }
error_return:;
ldap_pvt_thread_mutex_unlock( &cache->mutex ); ldap_pvt_thread_mutex_unlock( &cache->mutex );
return err; return err;

@ -77,11 +77,10 @@ meta_back_db_init(
{ {
metainfo_t *mi; metainfo_t *mi;
mi = ch_malloc( sizeof( metainfo_t ) ); mi = ch_calloc( 1, sizeof( metainfo_t ) );
if ( mi == NULL ) { if ( mi == NULL ) {
return -1; return -1;
} }
memset( mi, 0, sizeof( metainfo_t ) );
/* /*
* At present the default is no default target; * At present the default is no default target;
@ -89,7 +88,7 @@ meta_back_db_init(
*/ */
mi->mi_defaulttarget = META_DEFAULT_TARGET_NONE; mi->mi_defaulttarget = META_DEFAULT_TARGET_NONE;
ldap_pvt_thread_mutex_init( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_init( &mi->mi_conninfo.lai_mutex );
ldap_pvt_thread_mutex_init( &mi->mi_cache.mutex ); ldap_pvt_thread_mutex_init( &mi->mi_cache.mutex );
/* safe default */ /* safe default */
@ -222,10 +221,10 @@ meta_back_db_destroy(
/* /*
* Destroy the connection tree * Destroy the connection tree
*/ */
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
if ( mi->mi_conntree ) { if ( mi->mi_conninfo.lai_tree ) {
avl_free( mi->mi_conntree, meta_back_conn_free ); avl_free( mi->mi_conninfo.lai_tree, meta_back_conn_free );
} }
/* /*
@ -248,8 +247,8 @@ meta_back_db_destroy(
ldap_pvt_thread_mutex_unlock( &mi->mi_cache.mutex ); ldap_pvt_thread_mutex_unlock( &mi->mi_cache.mutex );
ldap_pvt_thread_mutex_destroy( &mi->mi_cache.mutex ); ldap_pvt_thread_mutex_destroy( &mi->mi_cache.mutex );
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
ldap_pvt_thread_mutex_destroy( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_destroy( &mi->mi_conninfo.lai_mutex );
if ( mi->mi_candidates != NULL ) { if ( mi->mi_candidates != NULL ) {
ber_memfree_x( mi->mi_candidates, NULL ); ber_memfree_x( mi->mi_candidates, NULL );

@ -102,11 +102,9 @@ meta_back_search_start(
&op->o_req_ndn ) ) &op->o_req_ndn ) )
{ {
realbase = mi->mi_targets[ candidate ].mt_nsuffix; realbase = mi->mi_targets[ candidate ].mt_nsuffix;
#ifdef LDAP_SCOPE_SUBORDINATE
if ( mi->mi_targets[ candidate ].mt_scope == LDAP_SCOPE_SUBORDINATE ) { if ( mi->mi_targets[ candidate ].mt_scope == LDAP_SCOPE_SUBORDINATE ) {
realscope = LDAP_SCOPE_SUBORDINATE; realscope = LDAP_SCOPE_SUBORDINATE;
} }
#endif /* LDAP_SCOPE_SUBORDINATE */
} else { } else {
/* /*
@ -116,9 +114,7 @@ meta_back_search_start(
} }
break; break;
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE: case LDAP_SCOPE_SUBORDINATE:
#endif /* LDAP_SCOPE_SUBORDINATE */
case LDAP_SCOPE_ONELEVEL: case LDAP_SCOPE_ONELEVEL:
{ {
struct berval rdn = mi->mi_targets[ candidate ].mt_nsuffix; struct berval rdn = mi->mi_targets[ candidate ].mt_nsuffix;
@ -132,16 +128,13 @@ meta_back_search_start(
* base, and make scope "base" * base, and make scope "base"
*/ */
realbase = mi->mi_targets[ candidate ].mt_nsuffix; realbase = mi->mi_targets[ candidate ].mt_nsuffix;
#ifdef LDAP_SCOPE_SUBORDINATE
if ( op->ors_scope == LDAP_SCOPE_SUBORDINATE ) { if ( op->ors_scope == LDAP_SCOPE_SUBORDINATE ) {
if ( mi->mi_targets[ candidate ].mt_scope == LDAP_SCOPE_SUBORDINATE ) { if ( mi->mi_targets[ candidate ].mt_scope == LDAP_SCOPE_SUBORDINATE ) {
realscope = LDAP_SCOPE_SUBORDINATE; realscope = LDAP_SCOPE_SUBORDINATE;
} else { } else {
realscope = LDAP_SCOPE_SUBTREE; realscope = LDAP_SCOPE_SUBTREE;
} }
} else } else {
#endif /* LDAP_SCOPE_SUBORDINATE */
{
realscope = LDAP_SCOPE_BASE; realscope = LDAP_SCOPE_BASE;
} }
break; break;
@ -451,29 +444,30 @@ really_bad:;
candidates[ i ].sr_type = REP_RESULT; candidates[ i ].sr_type = REP_RESULT;
} }
if ( --op->ors_slimit == -1 ) {
ldap_msgfree( res );
res = NULL;
rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;
savepriv = op->o_private;
op->o_private = (void *)i;
send_ldap_result( op, rs );
op->o_private = savepriv;
goto finish;
}
is_ok++; is_ok++;
e = ldap_first_entry( msc->msc_ld, res ); e = ldap_first_entry( msc->msc_ld, res );
savepriv = op->o_private; savepriv = op->o_private;
op->o_private = (void *)i; op->o_private = (void *)i;
meta_send_entry( op, rs, mc, i, e ); rs->sr_err = meta_send_entry( op, rs, mc, i, e );
op->o_private = savepriv;
ldap_msgfree( res ); ldap_msgfree( res );
res = NULL; res = NULL;
switch ( rc ) {
case LDAP_SIZELIMIT_EXCEEDED:
savepriv = op->o_private;
op->o_private = (void *)i;
send_ldap_result( op, rs );
op->o_private = savepriv;
rs->sr_err = LDAP_SUCCESS;
goto finish;
case LDAP_UNAVAILABLE:
rs->sr_err = LDAP_OTHER;
goto finish;
}
op->o_private = savepriv;
gotit = 1; gotit = 1;
#if 0 #if 0
@ -595,19 +589,22 @@ really_bad:;
/* massage matchedDN if need be */ /* massage matchedDN if need be */
if ( candidates[ i ].sr_matched != NULL ) { if ( candidates[ i ].sr_matched != NULL ) {
#ifndef LDAP_NULL_IS_NULL
if ( candidates[ i ].sr_matched[ 0 ] == '\0' ) { if ( candidates[ i ].sr_matched[ 0 ] == '\0' ) {
ldap_memfree( (char *)candidates[ i ].sr_matched ); ldap_memfree( (char *)candidates[ i ].sr_matched );
candidates[ i ].sr_matched = NULL; candidates[ i ].sr_matched = NULL;
} else { } else
#endif /* LDAP_NULL_IS_NULL */
{
struct berval match, mmatch; struct berval match, mmatch;
ber_str2bv( candidates[ i ].sr_matched, ber_str2bv( candidates[ i ].sr_matched,
0, 0, &match ); 0, 0, &match );
candidates[ i ].sr_matched = NULL;
dc.ctx = "matchedDN"; dc.ctx = "matchedDN";
dc.target = &mi->mi_targets[ i ]; dc.target = &mi->mi_targets[ i ];
if ( !ldap_back_dn_massage( &dc, &match, &mmatch ) ) { if ( !ldap_back_dn_massage( &dc, &match, &mmatch ) ) {
if ( mmatch.bv_val == match.bv_val ) { if ( mmatch.bv_val == match.bv_val ) {
candidates[ i ].sr_matched = ch_strdup( mmatch.bv_val ); candidates[ i ].sr_matched = ch_strdup( mmatch.bv_val );
@ -622,12 +619,14 @@ really_bad:;
} }
} }
#ifndef LDAP_NULL_IS_NULL
/* just get rid of the error message, if any */ /* just get rid of the error message, if any */
if ( candidates[ i ].sr_text && candidates[ i ].sr_text[ 0 ] == '\0' ) if ( candidates[ i ].sr_text && candidates[ i ].sr_text[ 0 ] == '\0' )
{ {
ldap_memfree( (char *)candidates[ i ].sr_text ); ldap_memfree( (char *)candidates[ i ].sr_text );
candidates[ i ].sr_text = NULL; candidates[ i ].sr_text = NULL;
} }
#endif /* LDAP_NULL_IS_NULL */
/* add references to array */ /* add references to array */
if ( references ) { if ( references ) {
@ -766,11 +765,24 @@ really_bad:;
/* we use the first one */ /* we use the first one */
for ( i = 0; i < mi->mi_ntargets; i++ ) { for ( i = 0; i < mi->mi_ntargets; i++ ) {
if ( candidates[ i ].sr_tag == META_CANDIDATE if ( candidates[ i ].sr_tag == META_CANDIDATE
&& candidates[ i ].sr_matched ) && candidates[ i ].sr_matched != NULL )
{ {
struct berval bv, pbv; struct berval bv, pbv;
int rc; int rc;
/* if we got success, and this target
* returned noSuchObject, and its suffix
* is a superior of the searchBase,
* ignore the matchedDN */
if ( sres == LDAP_SUCCESS
&& candidates[ i ].sr_err == LDAP_NO_SUCH_OBJECT
&& op->o_req_ndn.bv_len > mi->mi_targets[ i ].mt_nsuffix.bv_len )
{
free( (char *)candidates[ i ].sr_matched );
candidates[ i ].sr_matched = NULL;
continue;
}
ber_str2bv( candidates[ i ].sr_matched, 0, 0, &bv ); ber_str2bv( candidates[ i ].sr_matched, 0, 0, &bv );
rc = dnPretty( NULL, &bv, &pbv, op->o_tmpmemctx ); rc = dnPretty( NULL, &bv, &pbv, op->o_tmpmemctx );
@ -1137,7 +1149,12 @@ next_attr:;
rs->sr_entry = &ent; rs->sr_entry = &ent;
rs->sr_attrs = op->ors_attrs; rs->sr_attrs = op->ors_attrs;
rs->sr_flags = 0; rs->sr_flags = 0;
send_search_entry( op, rs ); rc = send_search_entry( op, rs );
switch ( rc ) {
case LDAP_UNAVAILABLE:
rc = LDAP_OTHER;
break;
}
rs->sr_entry = NULL; rs->sr_entry = NULL;
rs->sr_attrs = NULL; rs->sr_attrs = NULL;
@ -1151,6 +1168,6 @@ next_attr:;
} }
entry_clean( &ent ); entry_clean( &ent );
return LDAP_SUCCESS; return rc;
} }

@ -50,10 +50,10 @@ meta_back_conn_destroy(
mc_curr.mc_conn = conn; mc_curr.mc_conn = conn;
mc_curr.mc_local_ndn = conn->c_ndn; mc_curr.mc_local_ndn = conn->c_ndn;
ldap_pvt_thread_mutex_lock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_lock( &mi->mi_conninfo.lai_mutex );
mc = avl_delete( &mi->mi_conntree, ( caddr_t )&mc_curr, mc = avl_delete( &mi->mi_conninfo.lai_tree, ( caddr_t )&mc_curr,
meta_back_conn_cmp ); meta_back_conn_cmp );
ldap_pvt_thread_mutex_unlock( &mi->mi_conn_mutex ); ldap_pvt_thread_mutex_unlock( &mi->mi_conninfo.lai_mutex );
if ( mc ) { if ( mc ) {
Debug( LDAP_DEBUG_TRACE, Debug( LDAP_DEBUG_TRACE,

@ -45,6 +45,9 @@ static int monitor_back_add_plugin( monitor_info_t *mi, Backend *be, Entry *e );
#if 0 && defined(SLAPD_LDBM) #if 0 && defined(SLAPD_LDBM)
#include "../back-ldbm/back-ldbm.h" #include "../back-ldbm/back-ldbm.h"
#endif /* defined(SLAPD_LDBM) */ #endif /* defined(SLAPD_LDBM) */
#if defined(SLAPD_META)
#include "../back-meta/back-meta.h"
#endif /* defined(SLAPD_META) */
/* for PATH_MAX on some systems (e.g. Solaris) */ /* for PATH_MAX on some systems (e.g. Solaris) */
#ifdef HAVE_LIMITS_H #ifdef HAVE_LIMITS_H
@ -300,34 +303,19 @@ monitor_subsys_database_init(
} }
} }
if ( 0 ) {
assert( 0 );
#if defined(SLAPD_BDB) || defined(SLAPD_HDB) #if defined(SLAPD_BDB) || defined(SLAPD_HDB)
if ( strcmp( bi->bi_type, "bdb" ) == 0 } else if ( strcmp( bi->bi_type, "bdb" ) == 0
|| strcmp( bi->bi_type, "hdb" ) == 0 ) || strcmp( bi->bi_type, "hdb" ) == 0 )
{ {
struct berval bv; struct berval bv;
ber_len_t pathlen = 0, len = 0; ber_len_t pathlen = 0, len = 0;
char path[ PATH_MAX ] = { '\0' }; char path[ PATH_MAX ] = { '\0' };
char *fname = NULL; struct bdb_info *bdb = (struct bdb_info *) be->be_private;
char *fname = bdb->bi_dbenv_home;
if ( strcmp( bi->bi_type, "bdb" ) == 0
|| strcmp( bi->bi_type, "hdb" ) == 0 )
{
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
fname = bdb->bi_dbenv_home;
#if 0
} else if ( strcmp( bi->bi_type, "ldbm" ) == 0 ) {
struct ldbminfo *ldbm = (struct ldbminfo *) be->be_private;
/* FIXME: there's a conflict
* between back-bdb.h and back.ldbm.h;
* anyway, this code will be moved
* to the backends as soon as the
* issue with filtering on namingContexts
* is fixed */
fname = ldbm->li_directory;
#endif
}
len = strlen( fname ); len = strlen( fname );
if ( fname[ 0 ] != '/' ) { if ( fname[ 0 ] != '/' ) {
@ -363,22 +351,54 @@ monitor_subsys_database_init(
&bv, NULL ); &bv, NULL );
ch_free( bv.bv_val ); ch_free( bv.bv_val );
}
#endif /* defined(SLAPD_LDAP) || defined(SLAPD_HDB) */
#endif /* defined(SLAPD_BDB) || defined(SLAPD_HDB) */
#if defined(SLAPD_LDAP) #if defined(SLAPD_LDAP)
if ( strcmp( bi->bi_type, "ldap" ) == 0 ) { } else if ( strcmp( bi->bi_type, "ldap" ) == 0 ) {
struct ldapinfo *li = ldapinfo_t *li = (ldapinfo_t *)be->be_private;
(struct ldapinfo *)be->be_private; #if 0
struct berval bv; attr_merge_normalize( e, slap_schema.si_ad_labeledURI,
li->li_bvuri, NULL );
#else
char **urls = ldap_str2charray( li->li_uri, " " );
int u;
ber_str2bv( li->url, 0, 0, &bv ); for ( u = 0; urls[ u ] != NULL; u++ ) {
struct berval bv;
ber_str2bv( urls[ u ], 0, 0, &bv );
attr_merge_normalize_one( e,
slap_schema.si_ad_labeledURI,
&bv, NULL );
}
ldap_charray_free( urls );
#endif
attr_merge_normalize_one( e,
slap_schema.si_ad_labeledURI,
&bv, NULL );
}
#endif /* defined(SLAPD_LDAP) */ #endif /* defined(SLAPD_LDAP) */
#if defined(SLAPD_META)
} else if ( strcmp( bi->bi_type, "meta" ) == 0 ) {
metainfo_t *mi = (metainfo_t *)be->be_private;
int t;
for ( t = 0; t < mi->mi_ntargets; t++ ) {
char **urls = ldap_str2charray( mi->mi_targets[ t ].mt_uri, " " );
int u;
for ( u = 0; urls[ u ] != NULL; u++ ) {
struct berval bv;
ber_str2bv( urls[ u ], 0, 0, &bv );
attr_merge_normalize_one( e,
slap_schema.si_ad_labeledURI,
&bv, NULL );
}
ldap_charray_free( urls );
}
#endif /* defined(SLAPD_META) */
}
j = -1; j = -1;
LDAP_STAILQ_FOREACH( bi2, &backendInfo, bi_next ) { LDAP_STAILQ_FOREACH( bi2, &backendInfo, bi_next ) {

@ -1366,7 +1366,9 @@ monitor_back_initialize(
bi->bi_destroy = 0; bi->bi_destroy = 0;
bi->bi_db_init = monitor_back_db_init; bi->bi_db_init = monitor_back_db_init;
#if 0
bi->bi_db_config = monitor_back_db_config; bi->bi_db_config = monitor_back_db_config;
#endif
bi->bi_db_open = monitor_back_db_open; bi->bi_db_open = monitor_back_db_open;
bi->bi_db_close = 0; bi->bi_db_close = 0;
bi->bi_db_destroy = monitor_back_db_destroy; bi->bi_db_destroy = monitor_back_db_destroy;
@ -1812,6 +1814,7 @@ monitor_back_config(
return SLAP_CONF_UNKNOWN; return SLAP_CONF_UNKNOWN;
} }
#if 0
int int
monitor_back_db_config( monitor_back_db_config(
Backend *be, Backend *be,
@ -1820,15 +1823,14 @@ monitor_back_db_config(
int argc, int argc,
char **argv ) char **argv )
{ {
#if 0
monitor_info_t *mi = ( monitor_info_t * )be->be_private; monitor_info_t *mi = ( monitor_info_t * )be->be_private;
#endif
/* /*
* eventually, will hold database specific configuration parameters * eventually, will hold database specific configuration parameters
*/ */
return SLAP_CONF_UNKNOWN; return SLAP_CONF_UNKNOWN;
} }
#endif
int int
monitor_back_db_destroy( monitor_back_db_destroy(

@ -113,7 +113,7 @@ monitor_send_children(
if ( rc == LDAP_COMPARE_TRUE ) { if ( rc == LDAP_COMPARE_TRUE ) {
rs->sr_entry = e; rs->sr_entry = e;
rs->sr_flags = 0; rs->sr_flags = 0;
send_search_entry( op, rs ); rc = send_search_entry( op, rs );
rs->sr_entry = NULL; rs->sr_entry = NULL;
} }

@ -84,10 +84,17 @@ perl_back_search(
send_entry = 1; send_entry = 1;
if (send_entry) { if (send_entry) {
int rc;
rs->sr_entry = e; rs->sr_entry = e;
rs->sr_attrs = op->ors_attrs; rs->sr_attrs = op->ors_attrs;
rs->sr_flags = REP_ENTRY_MODIFIABLE; rs->sr_flags = REP_ENTRY_MODIFIABLE;
send_search_entry( op, rs ); rs->sr_err = LDAP_SUCCESS;
rs->sr_err = send_search_entry( op, rs );
if ( rs->sr_err == LDAP_SIZELIMIT_EXCEEDED ) {
rs->sr_entry = NULL;
goto done;
}
} }
entry_free( e ); entry_free( e );
@ -106,8 +113,7 @@ perl_back_search(
rs->sr_err = POPi; rs->sr_err = POPi;
done:;
PUTBACK; FREETMPS; LEAVE; PUTBACK; FREETMPS; LEAVE;
} }

@ -27,6 +27,7 @@
#include <sys/types.h> #include <sys/types.h>
#include "ac/string.h" #include "ac/string.h"
#include "lutil.h"
#include "slap.h" #include "slap.h"
#include "proto-sql.h" #include "proto-sql.h"
@ -250,43 +251,52 @@ backsql_dn2id(
if ( id != NULL ) { if ( id != NULL ) {
struct berval dn; struct berval dn;
id->eid_next = NULL;
#ifdef BACKSQL_ARBITRARY_KEY #ifdef BACKSQL_ARBITRARY_KEY
ber_str2bv_x( row.cols[ 0 ], 0, 1, &id->eid_id, ber_str2bv_x( row.cols[ 0 ], 0, 1, &id->eid_id,
op->o_tmpmemctx ); op->o_tmpmemctx );
ber_str2bv_x( row.cols[ 1 ], 0, 1, &id->eid_keyval, ber_str2bv_x( row.cols[ 1 ], 0, 1, &id->eid_keyval,
op->o_tmpmemctx ); op->o_tmpmemctx );
#else /* ! BACKSQL_ARBITRARY_KEY */ #else /* ! BACKSQL_ARBITRARY_KEY */
id->eid_id = strtol( row.cols[ 0 ], NULL, 0 ); if ( lutil_atoulx( &id->eid_id, row.cols[ 0 ], 0 ) != 0 ) {
id->eid_keyval = strtol( row.cols[ 1 ], NULL, 0 ); res = LDAP_OTHER;
goto done;
}
if ( lutil_atoulx( &id->eid_keyval, row.cols[ 1 ], 0 ) != 0 ) {
res = LDAP_OTHER;
goto done;
}
#endif /* ! BACKSQL_ARBITRARY_KEY */ #endif /* ! BACKSQL_ARBITRARY_KEY */
id->eid_oc_id = strtol( row.cols[ 2 ], NULL, 0 ); if ( lutil_atoulx( &id->eid_oc_id, row.cols[ 2 ], 0 ) != 0 ) {
res = LDAP_OTHER;
goto done;
}
ber_str2bv( row.cols[ 3 ], 0, 0, &dn ); ber_str2bv( row.cols[ 3 ], 0, 0, &dn );
if ( backsql_api_odbc2dn( op, rs, &dn ) ) { if ( backsql_api_odbc2dn( op, rs, &dn ) ) {
res = LDAP_OTHER; res = LDAP_OTHER;
goto done;
}
res = dnPrettyNormal( NULL, &dn,
&id->eid_dn, &id->eid_ndn,
op->o_tmpmemctx );
if ( res != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
" backsql_dn2id(\"%s\"): "
"dnPrettyNormal failed (%d: %s)\n",
realndn.bv_val, res,
ldap_err2string( res ) );
} else { /* cleanup... */
res = dnPrettyNormal( NULL, &dn, (void)backsql_free_entryID( op, id, 0 );
&id->eid_dn, &id->eid_ndn,
op->o_tmpmemctx );
if ( res != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_TRACE,
" backsql_dn2id(\"%s\"): "
"dnPrettyNormal failed (%d: %s)\n",
realndn.bv_val, res,
ldap_err2string( res ) );
/* cleanup... */
(void)backsql_free_entryID( op, id, 0 );
}
if ( dn.bv_val != row.cols[ 3 ] ) {
free( dn.bv_val );
}
} }
id->eid_next = NULL; if ( dn.bv_val != row.cols[ 3 ] ) {
free( dn.bv_val );
}
} }
} else { } else {
@ -408,11 +418,28 @@ backsql_count_children(
char *end; char *end;
*nchildren = strtol( row.cols[ 0 ], &end, 0 ); *nchildren = strtol( row.cols[ 0 ], &end, 0 );
if ( end[ 0 ] != '\0' && end[0] != '.' ) { if ( end == row.cols[ 0 ] ) {
/* FIXME: braindead RDBMSes return
* a fractional number from COUNT!
*/
res = LDAP_OTHER; res = LDAP_OTHER;
} else {
switch ( end[ 0 ] ) {
case '\0':
break;
case '.': {
unsigned long ul;
/* FIXME: braindead RDBMSes return
* a fractional number from COUNT!
*/
if ( lutil_atoul( &ul, end + 1 ) != 0 || ul != 0 ) {
res = LDAP_OTHER;
}
} break;
default:
res = LDAP_OTHER;
}
} }
} else { } else {

@ -27,6 +27,7 @@
#include <sys/types.h> #include <sys/types.h>
#include "ac/string.h" #include "ac/string.h"
#include "lutil.h"
#include "slap.h" #include "slap.h"
#include "proto-sql.h" #include "proto-sql.h"
@ -316,7 +317,6 @@ backsql_oc_get_attr_mapping( void *v_oc, void *v_bas )
backsql_BindRowAsStrings( bas->bas_sth, &at_row ); backsql_BindRowAsStrings( bas->bas_sth, &at_row );
for ( ; rc = SQLFetch( bas->bas_sth ), BACKSQL_SUCCESS( rc ); ) { for ( ; rc = SQLFetch( bas->bas_sth ), BACKSQL_SUCCESS( rc ); ) {
const char *text = NULL; const char *text = NULL;
char *next = NULL;
struct berval bv; struct berval bv;
struct berbuf bb = BB_NULL; struct berbuf bb = BB_NULL;
@ -377,14 +377,10 @@ backsql_oc_get_attr_mapping( void *v_oc, void *v_bas )
if ( at_row.value_len[ 5 ] > 0 ) { if ( at_row.value_len[ 5 ] > 0 ) {
at_map->bam_delete_proc = ch_strdup( at_row.cols[ 5 ] ); at_map->bam_delete_proc = ch_strdup( at_row.cols[ 5 ] );
} }
at_map->bam_param_order = strtol( at_row.cols[ 6 ], if ( lutil_atoix( &at_map->bam_param_order, at_row.cols[ 6 ], 0 ) != 0 ) {
&next, 0 );
if ( next == at_row.cols[ 6 ] || next[0] != '\0' ) {
/* error */ /* error */
} }
at_map->bam_expect_return = strtol( at_row.cols[ 7 ], if ( lutil_atoix( &at_map->bam_expect_return, at_row.cols[ 7 ], 0 ) != 0 ) {
&next, 0 );
if ( next == at_row.cols[ 7 ] || next[0] != '\0' ) {
/* error */ /* error */
} }
backsql_make_attr_query( bas->bas_bi, oc_map, at_map ); backsql_make_attr_query( bas->bas_bi, oc_map, at_map );
@ -485,7 +481,12 @@ backsql_load_schema_map( backsql_info *bi, SQLHDBC dbh )
oc_map = (backsql_oc_map_rec *)ch_calloc( 1, oc_map = (backsql_oc_map_rec *)ch_calloc( 1,
sizeof( backsql_oc_map_rec ) ); sizeof( backsql_oc_map_rec ) );
oc_map->bom_id = strtol( oc_row.cols[ 0 ], NULL, 0 ); if ( lutil_atoulx( &oc_map->bom_id, oc_row.cols[ 0 ], 0 ) != 0 ) {
Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): "
"unable to parse id=\"%s\"\n",
oc_row.cols[ 0 ], 0, 0 );
return LDAP_OTHER;
}
oc_map->bom_oc = oc_find( oc_row.cols[ 1 ] ); oc_map->bom_oc = oc_find( oc_row.cols[ 1 ] );
if ( oc_map->bom_oc == NULL ) { if ( oc_map->bom_oc == NULL ) {
@ -508,8 +509,12 @@ backsql_load_schema_map( backsql_info *bi, SQLHDBC dbh )
} }
oc_map->bom_delete_proc = ( oc_row.value_len[ colnum ] < 0 ) ? NULL oc_map->bom_delete_proc = ( oc_row.value_len[ colnum ] < 0 ) ? NULL
: ch_strdup( oc_row.cols[ colnum ] ); : ch_strdup( oc_row.cols[ colnum ] );
oc_map->bom_expect_return = strtol( oc_row.cols[ colnum + 1 ], if ( lutil_atoix( &oc_map->bom_expect_return, oc_row.cols[ colnum + 1 ], 0 ) != 0 ) {
NULL, 0 ); Debug( LDAP_DEBUG_TRACE, "backsql_load_schema_map(): "
"unable to parse expect_return=\"%s\" for objectClass \"%s\"\n",
oc_row.cols[ colnum + 1 ], oc_row.cols[ 1 ], 0 );
return LDAP_OTHER;
}
colnum += 2; colnum += 2;
if ( ( oc_row.ncols > colnum ) && if ( ( oc_row.ncols > colnum ) &&

@ -28,6 +28,7 @@
#include "ac/string.h" #include "ac/string.h"
#include "ac/ctype.h" #include "ac/ctype.h"
#include "lutil.h"
#include "slap.h" #include "slap.h"
#include "proto-sql.h" #include "proto-sql.h"
@ -1435,9 +1436,7 @@ backsql_srch_query( backsql_srch_info *bsi, struct berval *query )
"ldap_entries.parent=?" ); "ldap_entries.parent=?" );
break; break;
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE: case LDAP_SCOPE_SUBORDINATE:
#endif /* LDAP_SCOPE_SUBORDINATE */
case LDAP_SCOPE_SUBTREE: case LDAP_SCOPE_SUBTREE:
if ( BACKSQL_USE_SUBTREE_SHORTCUT( bi ) ) { if ( BACKSQL_USE_SUBTREE_SHORTCUT( bi ) ) {
int i; int i;
@ -1678,9 +1677,7 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
} }
break; break;
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE: case LDAP_SCOPE_SUBORDINATE:
#endif /* LDAP_SCOPE_SUBORDINATE */
case LDAP_SCOPE_SUBTREE: case LDAP_SCOPE_SUBTREE:
{ {
/* if short-cutting the search base, /* if short-cutting the search base,
@ -1719,11 +1716,9 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
tmp_base_ndn[ i ] = bsi->bsi_base_ndn->bv_val[ j ]; tmp_base_ndn[ i ] = bsi->bsi_base_ndn->bv_val[ j ];
} }
#ifdef LDAP_SCOPE_SUBORDINATE
if ( bsi->bsi_scope == LDAP_SCOPE_SUBORDINATE ) { if ( bsi->bsi_scope == LDAP_SCOPE_SUBORDINATE ) {
tmp_base_ndn[ i++ ] = ','; tmp_base_ndn[ i++ ] = ',';
} }
#endif /* LDAP_SCOPE_SUBORDINATE */
tmp_base_ndn[ i ] = '%'; tmp_base_ndn[ i ] = '%';
tmp_base_ndn[ i + 1 ] = '\0'; tmp_base_ndn[ i + 1 ] = '\0';
@ -1733,11 +1728,9 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
tmp_base_ndn[ i++ ] = '%'; tmp_base_ndn[ i++ ] = '%';
#ifdef LDAP_SCOPE_SUBORDINATE
if ( bsi->bsi_scope == LDAP_SCOPE_SUBORDINATE ) { if ( bsi->bsi_scope == LDAP_SCOPE_SUBORDINATE ) {
tmp_base_ndn[ i++ ] = ','; tmp_base_ndn[ i++ ] = ',';
} }
#endif /* LDAP_SCOPE_SUBORDINATE */
AC_MEMCPY( &tmp_base_ndn[ i ], bsi->bsi_base_ndn->bv_val, AC_MEMCPY( &tmp_base_ndn[ i ], bsi->bsi_base_ndn->bv_val,
bsi->bsi_base_ndn->bv_len + 1 ); bsi->bsi_base_ndn->bv_len + 1 );
@ -1749,13 +1742,10 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
ldap_pvt_str2upper( tmp_base_ndn ); ldap_pvt_str2upper( tmp_base_ndn );
} }
#ifdef LDAP_SCOPE_SUBORDINATE
if ( bsi->bsi_scope == LDAP_SCOPE_SUBORDINATE ) { if ( bsi->bsi_scope == LDAP_SCOPE_SUBORDINATE ) {
Debug( LDAP_DEBUG_TRACE, "(children)dn: \"%s\"\n", Debug( LDAP_DEBUG_TRACE, "(children)dn: \"%s\"\n",
tmp_base_ndn, 0, 0 ); tmp_base_ndn, 0, 0 );
} else } else {
#endif /* LDAP_SCOPE_SUBORDINATE */
{
Debug( LDAP_DEBUG_TRACE, "(sub)dn: \"%s\"\n", Debug( LDAP_DEBUG_TRACE, "(sub)dn: \"%s\"\n",
tmp_base_ndn, 0, 0 ); tmp_base_ndn, 0, 0 );
} }
@ -1828,21 +1818,23 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
} }
if ( bi->sql_baseObject && dn_match( &ndn, &bi->sql_baseObject->e_nname ) ) { if ( bi->sql_baseObject && dn_match( &ndn, &bi->sql_baseObject->e_nname ) ) {
op->o_tmpfree( pdn.bv_val, op->o_tmpmemctx ); goto cleanup;
op->o_tmpfree( ndn.bv_val, op->o_tmpmemctx );
continue;
} }
c_id = (backsql_entryID *)ch_calloc( 1, c_id = (backsql_entryID *)op->o_tmpcalloc( 1,
sizeof( backsql_entryID ) ); sizeof( backsql_entryID ), op->o_tmpmemctx );
#ifdef BACKSQL_ARBITRARY_KEY #ifdef BACKSQL_ARBITRARY_KEY
ber_str2bv_x( row.cols[ 0 ], 0, 1, &c_id->eid_id, ber_str2bv_x( row.cols[ 0 ], 0, 1, &c_id->eid_id,
op->o_tmpmemctx ); op->o_tmpmemctx );
ber_str2bv_x( row.cols[ 1 ], 0, 1, &c_id->eid_keyval, ber_str2bv_x( row.cols[ 1 ], 0, 1, &c_id->eid_keyval,
op->o_tmpmemctx ); op->o_tmpmemctx );
#else /* ! BACKSQL_ARBITRARY_KEY */ #else /* ! BACKSQL_ARBITRARY_KEY */
c_id->eid_id = strtol( row.cols[ 0 ], NULL, 0 ); if ( lutil_atoulx( &c_id->eid_id, row.cols[ 0 ], 0 ) != 0 ) {
c_id->eid_keyval = strtol( row.cols[ 1 ], NULL, 0 ); goto cleanup;
}
if ( lutil_atoulx( &c_id->eid_keyval, row.cols[ 1 ], 0 ) != 0 ) {
goto cleanup;
}
#endif /* ! BACKSQL_ARBITRARY_KEY */ #endif /* ! BACKSQL_ARBITRARY_KEY */
c_id->eid_oc_id = bsi->bsi_oc->bom_id; c_id->eid_oc_id = bsi->bsi_oc->bom_id;
@ -1870,6 +1862,18 @@ backsql_oc_get_candidates( void *v_oc, void *v_bsi )
if ( bsi->bsi_n_candidates == -1 ) { if ( bsi->bsi_n_candidates == -1 ) {
break; break;
} }
continue;
cleanup:;
if ( !BER_BVISNULL( &pdn ) ) {
op->o_tmpfree( pdn.bv_val, op->o_tmpmemctx );
}
if ( !BER_BVISNULL( &ndn ) ) {
op->o_tmpfree( ndn.bv_val, op->o_tmpmemctx );
}
if ( c_id != NULL ) {
ch_free( c_id );
}
} }
backsql_FreeRow_x( &row, bsi->bsi_op->o_tmpmemctx ); backsql_FreeRow_x( &row, bsi->bsi_op->o_tmpmemctx );
SQLFreeStmt( sth, SQL_DROP ); SQLFreeStmt( sth, SQL_DROP );
@ -1897,7 +1901,7 @@ backsql_search( Operation *op, SlapReply *rs )
Debug( LDAP_DEBUG_TRACE, "==>backsql_search(): " Debug( LDAP_DEBUG_TRACE, "==>backsql_search(): "
"base=\"%s\", filter=\"%s\", scope=%d,", "base=\"%s\", filter=\"%s\", scope=%d,",
op->o_req_ndn.bv_val, op->o_req_ndn.bv_val,
op->ors_filterstr.bv_val ? op->ors_filterstr.bv_val : "(no filter)", op->ors_filterstr.bv_val,
op->ors_scope ); op->ors_scope );
Debug( LDAP_DEBUG_TRACE, " deref=%d, attrsonly=%d, " Debug( LDAP_DEBUG_TRACE, " deref=%d, attrsonly=%d, "
"attributes to load: %s\n", "attributes to load: %s\n",
@ -2142,15 +2146,12 @@ backsql_search( Operation *op, SlapReply *rs )
/* fall thru */ /* fall thru */
} }
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE: case LDAP_SCOPE_SUBORDINATE:
/* discard the baseObject entry */ /* discard the baseObject entry */
if ( dn_match( &eid->eid_ndn, &op->o_req_ndn ) ) { if ( dn_match( &eid->eid_ndn, &op->o_req_ndn ) ) {
goto next_entry2; goto next_entry2;
} }
/* FALLTHRU */ /* FALLTHRU */
#endif /* LDAP_SCOPE_SUBORDINATE */
case LDAP_SCOPE_SUBTREE: case LDAP_SCOPE_SUBTREE:
/* FIXME: this should never fail... */ /* FIXME: this should never fail... */
if ( !dnIsSuffix( &eid->eid_ndn, &op->o_req_ndn ) ) { if ( !dnIsSuffix( &eid->eid_ndn, &op->o_req_ndn ) ) {
@ -2305,24 +2306,18 @@ backsql_search( Operation *op, SlapReply *rs )
if ( test_filter( op, e, op->ors_filter ) == LDAP_COMPARE_TRUE ) if ( test_filter( op, e, op->ors_filter ) == LDAP_COMPARE_TRUE )
{ {
if ( --op->ors_slimit == -1 ) {
rs->sr_err = LDAP_SIZELIMIT_EXCEEDED;
goto send_results;
}
rs->sr_attrs = op->ors_attrs; rs->sr_attrs = op->ors_attrs;
rs->sr_operational_attrs = NULL; rs->sr_operational_attrs = NULL;
rs->sr_entry = e; rs->sr_entry = e;
if ( e == &user_entry ) { rs->sr_flags = ( e == &user_entry ) ? REP_ENTRY_MODIFIABLE : 0;
rs->sr_flags = REP_ENTRY_MODIFIABLE;
}
/* FIXME: need the whole entry (ITS#3480) */ /* FIXME: need the whole entry (ITS#3480) */
sres = send_search_entry( op, rs ); rs->sr_err = send_search_entry( op, rs );
rs->sr_entry = NULL; rs->sr_entry = NULL;
rs->sr_attrs = NULL; rs->sr_attrs = NULL;
rs->sr_operational_attrs = NULL; rs->sr_operational_attrs = NULL;
if ( sres == -1 ) { switch ( rs->sr_err ) {
case LDAP_UNAVAILABLE:
/* /*
* FIXME: send_search_entry failed; * FIXME: send_search_entry failed;
* better stop * better stop
@ -2330,6 +2325,9 @@ backsql_search( Operation *op, SlapReply *rs )
Debug( LDAP_DEBUG_TRACE, "backsql_search(): " Debug( LDAP_DEBUG_TRACE, "backsql_search(): "
"connection lost\n", 0, 0, 0 ); "connection lost\n", 0, 0, 0 );
goto end_of_search; goto end_of_search;
case LDAP_SIZELIMIT_EXCEEDED:
goto send_results;
} }
} }

@ -544,7 +544,9 @@ backsql_entryUUID_decode(
#endif /* ! BACKSQL_ARBITRARY_KEY */ #endif /* ! BACKSQL_ARBITRARY_KEY */
) )
{ {
#if 0
fprintf( stderr, "==> backsql_entryUUID_decode()\n" ); fprintf( stderr, "==> backsql_entryUUID_decode()\n" );
#endif
*oc_id = ( entryUUID->bv_val[0] << 030 /* 24 */ ) *oc_id = ( entryUUID->bv_val[0] << 030 /* 24 */ )
+ ( entryUUID->bv_val[1] << 020 /* 16 */ ) + ( entryUUID->bv_val[1] << 020 /* 16 */ )
@ -560,8 +562,10 @@ backsql_entryUUID_decode(
+ entryUUID->bv_val[7]; + entryUUID->bv_val[7];
#endif /* ! BACKSQL_ARBITRARY_KEY */ #endif /* ! BACKSQL_ARBITRARY_KEY */
#if 0
fprintf( stderr, "<== backsql_entryUUID_decode(): oc=%lu id=%lu\n", fprintf( stderr, "<== backsql_entryUUID_decode(): oc=%lu id=%lu\n",
*oc_id, *keyval ); *oc_id, *keyval );
#endif
return LDAP_SUCCESS; return LDAP_SUCCESS;
} }

@ -1311,14 +1311,12 @@ fe_acl_group(
goto loopit; goto loopit;
} }
break; break;
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE: case LDAP_SCOPE_SUBORDINATE:
if ( dn_match( &nbase, op_ndn ) || if ( dn_match( &nbase, op_ndn ) ||
!dnIsSuffix( op_ndn, &nbase ) ) !dnIsSuffix( op_ndn, &nbase ) )
{ {
goto loopit; goto loopit;
} }
#endif
} }
filter = str2filter_x( op, ludp->lud_filter ); filter = str2filter_x( op, ludp->lud_filter );
if ( filter ) { if ( filter ) {

@ -79,7 +79,6 @@ glue_back_select (
typedef struct glue_state { typedef struct glue_state {
int err; int err;
int slimit;
int matchlen; int matchlen;
char *matched; char *matched;
int nrefs; int nrefs;
@ -93,13 +92,6 @@ glue_op_response ( Operation *op, SlapReply *rs )
switch(rs->sr_type) { switch(rs->sr_type) {
case REP_SEARCH: case REP_SEARCH:
if ( gs->slimit != SLAP_NO_LIMIT
&& rs->sr_nentries >= gs->slimit )
{
rs->sr_err = gs->err = LDAP_SIZELIMIT_EXCEEDED;
return -1;
}
/* fallthru */
case REP_SEARCHREF: case REP_SEARCHREF:
return SLAP_CB_CONTINUE; return SLAP_CB_CONTINUE;
@ -242,9 +234,9 @@ glue_op_search ( Operation *op, SlapReply *rs )
BackendInfo *bi0 = op->o_bd->bd_info; BackendInfo *bi0 = op->o_bd->bd_info;
int i; int i;
long stoptime = 0; long stoptime = 0;
glue_state gs = {0, 0, 0, NULL, 0, NULL}; glue_state gs = {0, 0, NULL, 0, NULL};
slap_callback cb = { NULL, glue_op_response, NULL, NULL }; slap_callback cb = { NULL, glue_op_response, NULL, NULL };
int scope0, slimit0, tlimit0; int scope0, tlimit0;
struct berval dn, ndn, *pdn; struct berval dn, ndn, *pdn;
cb.sc_private = &gs; cb.sc_private = &gs;
@ -266,9 +258,7 @@ glue_op_search ( Operation *op, SlapReply *rs )
case LDAP_SCOPE_ONELEVEL: case LDAP_SCOPE_ONELEVEL:
case LDAP_SCOPE_SUBTREE: case LDAP_SCOPE_SUBTREE:
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE: /* FIXME */ case LDAP_SCOPE_SUBORDINATE: /* FIXME */
#endif
#if 0 #if 0
if ( op->o_sync ) { if ( op->o_sync ) {
@ -285,7 +275,6 @@ glue_op_search ( Operation *op, SlapReply *rs )
op->o_callback = &cb; op->o_callback = &cb;
rs->sr_err = gs.err = LDAP_UNWILLING_TO_PERFORM; rs->sr_err = gs.err = LDAP_UNWILLING_TO_PERFORM;
scope0 = op->ors_scope; scope0 = op->ors_scope;
slimit0 = gs.slimit = op->ors_slimit;
tlimit0 = op->ors_tlimit; tlimit0 = op->ors_tlimit;
dn = op->o_req_dn; dn = op->o_req_dn;
ndn = op->o_req_ndn; ndn = op->o_req_ndn;
@ -313,13 +302,6 @@ glue_op_search ( Operation *op, SlapReply *rs )
break; break;
} }
} }
if (slimit0 != SLAP_NO_LIMIT) {
op->ors_slimit = slimit0 - rs->sr_nentries;
if (op->ors_slimit < 0) {
rs->sr_err = gs.err = LDAP_SIZELIMIT_EXCEEDED;
break;
}
}
rs->sr_err = 0; rs->sr_err = 0;
/* /*
* check for abandon * check for abandon
@ -380,7 +362,6 @@ glue_op_search ( Operation *op, SlapReply *rs )
} }
end_of_loop:; end_of_loop:;
op->ors_scope = scope0; op->ors_scope = scope0;
op->ors_slimit = slimit0;
op->ors_tlimit = tlimit0; op->ors_tlimit = tlimit0;
op->o_req_dn = dn; op->o_req_dn = dn;
op->o_req_ndn = ndn; op->o_req_ndn = ndn;

@ -137,6 +137,9 @@ over_db_config(
ca.fname = fname; ca.fname = fname;
ca.lineno = lineno; ca.lineno = lineno;
ca.be = be; ca.be = be;
snprintf( ca.log, sizeof( ca.log ), "%s: line %d",
ca.fname, ca.lineno );
for (; on; on=on->on_next) { for (; on; on=on->on_next) {
rc = SLAP_CONF_UNKNOWN; rc = SLAP_CONF_UNKNOWN;
if (on->on_bi.bi_cf_ocs) { if (on->on_bi.bi_cf_ocs) {
@ -249,7 +252,7 @@ over_access_allowed(
{ {
slap_overinfo *oi; slap_overinfo *oi;
slap_overinst *on; slap_overinst *on;
BackendInfo *bi = op->o_bd->bd_info; BackendInfo *bi;
BackendDB *be = op->o_bd, db; BackendDB *be = op->o_bd, db;
int rc = SLAP_CB_CONTINUE; int rc = SLAP_CB_CONTINUE;
@ -257,7 +260,13 @@ over_access_allowed(
* when global overlays are used... */ * when global overlays are used... */
assert( op->o_bd != NULL ); assert( op->o_bd != NULL );
oi = op->o_bd->bd_info->bi_private; bi = op->o_bd->bd_info;
/* Were we invoked on the frontend? */
if ( !bi->bi_access_allowed ) {
oi = frontendDB->bd_info->bi_private;
} else {
oi = op->o_bd->bd_info->bi_private;
}
on = oi->oi_list; on = oi->oi_list;
for ( ; on; on = on->on_next ) { for ( ; on; on = on->on_next ) {
@ -795,7 +804,6 @@ overlay_is_inst( BackendDB *be, const char *over_type )
int int
overlay_register_control( BackendDB *be, const char *oid ) overlay_register_control( BackendDB *be, const char *oid )
{ {
int rc = 0;
int gotit = 0; int gotit = 0;
int cid; int cid;
@ -818,12 +826,12 @@ overlay_register_control( BackendDB *be, const char *oid )
} }
if ( rc == 0 && !gotit ) { if ( !gotit ) {
be->be_ctrls[ cid ] = 1; be->be_ctrls[ cid ] = 1;
be->be_ctrls[ SLAP_MAX_CIDS ] = 1; be->be_ctrls[ SLAP_MAX_CIDS ] = 1;
} }
return rc; return 0;
} }
void void

@ -1489,7 +1489,6 @@ config_schema_dn(ConfigArgs *c) {
static int static int
config_sizelimit(ConfigArgs *c) { config_sizelimit(ConfigArgs *c) {
int i, rc = 0; int i, rc = 0;
char *next;
struct slap_limits_set *lim = &c->be->be_def_limit; struct slap_limits_set *lim = &c->be->be_def_limit;
if (c->op == SLAP_CONFIG_EMIT) { if (c->op == SLAP_CONFIG_EMIT) {
char buf[8192]; char buf[8192];
@ -1525,20 +1524,11 @@ config_sizelimit(ConfigArgs *c) {
if(!strcasecmp(c->argv[i], "unlimited")) { if(!strcasecmp(c->argv[i], "unlimited")) {
lim->lms_s_soft = -1; lim->lms_s_soft = -1;
} else { } else {
lim->lms_s_soft = strtol(c->argv[i], &next, 0); if ( lutil_atoix( &lim->lms_s_soft, c->argv[i], 0 ) != 0 ) {
if(next == c->argv[i]) {
snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse limit", c->argv[0]); snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse limit", c->argv[0]);
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
c->log, c->msg, c->argv[i]); c->log, c->msg, c->argv[i]);
return(1); return(1);
} else if(next[0] != '\0') {
Debug( SLAPD_DEBUG_CONFIG_ERROR, "%s: "
"trailing chars \"%s\" in \"sizelimit <limit>\" line"
SLAPD_CONF_UNKNOWN_IGNORED ".\n",
c->log, next, 0);
#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
return 1;
#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
} }
} }
lim->lms_s_hard = 0; lim->lms_s_hard = 0;
@ -1550,7 +1540,6 @@ config_sizelimit(ConfigArgs *c) {
static int static int
config_timelimit(ConfigArgs *c) { config_timelimit(ConfigArgs *c) {
int i, rc = 0; int i, rc = 0;
char *next;
struct slap_limits_set *lim = &c->be->be_def_limit; struct slap_limits_set *lim = &c->be->be_def_limit;
if (c->op == SLAP_CONFIG_EMIT) { if (c->op == SLAP_CONFIG_EMIT) {
char buf[8192]; char buf[8192];
@ -1582,20 +1571,11 @@ config_timelimit(ConfigArgs *c) {
if(!strcasecmp(c->argv[i], "unlimited")) { if(!strcasecmp(c->argv[i], "unlimited")) {
lim->lms_t_soft = -1; lim->lms_t_soft = -1;
} else { } else {
lim->lms_t_soft = strtol(c->argv[i], &next, 0); if ( lutil_atoix( &lim->lms_t_soft, c->argv[i], 0 ) != 0 ) {
if(next == c->argv[i]) {
snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse limit", c->argv[0]); snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse limit", c->argv[0]);
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
c->log, c->msg, c->argv[i]); c->log, c->msg, c->argv[i]);
return(1); return(1);
} else if(next[0] != '\0') {
Debug( SLAPD_DEBUG_CONFIG_ERROR, "%s: "
"trailing chars \"%s\" in \"timelimit <limit>\" line"
SLAPD_CONF_UNKNOWN_IGNORED ".\n",
c->log, next, 0);
#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
return 1;
#endif /* SLAPD_CONF_UNKNOWN_BAILOUT */
} }
} }
lim->lms_t_hard = 0; lim->lms_t_hard = 0;
@ -2155,7 +2135,6 @@ static int config_syslog;
static int static int
config_loglevel(ConfigArgs *c) { config_loglevel(ConfigArgs *c) {
int i; int i;
char *next;
if ( loglevel_ops == NULL ) { if ( loglevel_ops == NULL ) {
loglevel_init(); loglevel_init();
@ -2186,8 +2165,7 @@ config_loglevel(ConfigArgs *c) {
int level; int level;
if ( isdigit( c->argv[i][0] ) || c->argv[i][0] == '-' ) { if ( isdigit( c->argv[i][0] ) || c->argv[i][0] == '-' ) {
level = strtol( c->argv[i], &next, 10 ); if( lutil_atoi( &level, c->argv[i] ) != 0 ) {
if ( next == NULL || next[0] != '\0' ) {
snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse level", c->argv[0] ); snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse level", c->argv[0] );
Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
c->log, c->msg, c->argv[i]); c->log, c->msg, c->argv[i]);
@ -2308,8 +2286,7 @@ config_security(ConfigArgs *c) {
return(1); return(1);
} }
*tgt = strtol(src, &next, 10); if ( lutil_atou( tgt, src ) != 0 ) {
if(next == NULL || next[0] != '\0' ) {
snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse factor", c->argv[0] ); snprintf( c->msg, sizeof( c->msg ), "<%s> unable to parse factor", c->argv[0] );
Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n", Debug(LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
c->log, c->msg, c->argv[i]); c->log, c->msg, c->argv[i]);
@ -2568,8 +2545,32 @@ config_updatedn(ConfigArgs *c) {
BER_BVZERO( &c->value_dn ); BER_BVZERO( &c->value_dn );
BER_BVZERO( &c->value_ndn ); BER_BVZERO( &c->value_ndn );
SLAP_DBFLAGS(c->be) |= (SLAP_DBFLAG_SHADOW | SLAP_DBFLAG_SLURP_SHADOW); return config_slurp_shadow( c );
return(0); }
int
config_shadow( ConfigArgs *c, int flag )
{
char *notallowed = NULL;
if ( c->be == frontendDB ) {
notallowed = "frontend";
} else if ( SLAP_MONITOR(c->be) ) {
notallowed = "monitor";
} else if ( SLAP_CONFIG(c->be) ) {
notallowed = "config";
}
if ( notallowed != NULL ) {
Debug( LDAP_DEBUG_ANY, "%s: %s database cannot be shadow.\n", c->log, notallowed, 0 );
return 1;
}
SLAP_DBFLAGS(c->be) |= (SLAP_DBFLAG_SHADOW | flag);
return 0;
} }
static int static int
@ -2718,8 +2719,13 @@ config_tls_config(ConfigArgs *c) {
return ldap_pvt_tls_set_option( NULL, flag, &i ); return ldap_pvt_tls_set_option( NULL, flag, &i );
} }
ch_free( c->value_string ); ch_free( c->value_string );
if(isdigit((unsigned char)c->argv[1][0])) { if ( isdigit( (unsigned char)c->argv[1][0] ) ) {
i = atoi(c->argv[1]); if ( lutil_atoi( &i, c->argv[1] ) != 0 ) {
Debug(LDAP_DEBUG_ANY, "%s: "
"unable to parse %s \"%s\"\n",
c->log, c->argv[0], c->argv[1] );
return 1;
}
return(ldap_pvt_tls_set_option(NULL, flag, &i)); return(ldap_pvt_tls_set_option(NULL, flag, &i));
} else { } else {
return(ldap_int_tls_config(NULL, flag, c->argv[1])); return(ldap_int_tls_config(NULL, flag, c->argv[1]));
@ -2822,8 +2828,12 @@ config_setup_ldif( BackendDB *be, const char *dir, int readit ) {
cfb->cb_db.be_suffix = be->be_suffix; cfb->cb_db.be_suffix = be->be_suffix;
cfb->cb_db.be_nsuffix = be->be_nsuffix; cfb->cb_db.be_nsuffix = be->be_nsuffix;
cfb->cb_db.be_rootdn = be->be_rootdn;
cfb->cb_db.be_rootndn = be->be_rootndn; /* The suffix is always "cn=config". The underlying DB's rootdn
* is always the same as the suffix.
*/
cfb->cb_db.be_rootdn = be->be_suffix[0];
cfb->cb_db.be_rootndn = be->be_nsuffix[0];
ber_str2bv( dir, 0, 1, &cfdir ); ber_str2bv( dir, 0, 1, &cfdir );
@ -2859,8 +2869,8 @@ config_setup_ldif( BackendDB *be, const char *dir, int readit ) {
op->ors_filterstr = filterstr; op->ors_filterstr = filterstr;
op->ors_scope = LDAP_SCOPE_SUBTREE; op->ors_scope = LDAP_SCOPE_SUBTREE;
op->o_dn = be->be_rootdn; op->o_dn = c.be->be_rootdn;
op->o_ndn = be->be_rootndn; op->o_ndn = c.be->be_rootndn;
op->o_req_dn = be->be_suffix[0]; op->o_req_dn = be->be_suffix[0];
op->o_req_ndn = be->be_nsuffix[0]; op->o_req_ndn = be->be_nsuffix[0];
@ -2882,7 +2892,9 @@ config_setup_ldif( BackendDB *be, const char *dir, int readit ) {
ldap_pvt_thread_pool_context_reset( thrctx ); ldap_pvt_thread_pool_context_reset( thrctx );
} }
cfb->cb_use_ldif = 1; /* ITS#4194 - only use if it's present, or we're converting. */
if ( !readit || rc == LDAP_SUCCESS )
cfb->cb_use_ldif = 1;
return rc; return rc;
} }
@ -2950,9 +2962,16 @@ read_config(const char *fname, const char *dir) {
/* if fname is defaulted, try reading .d */ /* if fname is defaulted, try reading .d */
rc = config_setup_ldif( be, cfdir, !fname ); rc = config_setup_ldif( be, cfdir, !fname );
/* It's OK if the base object doesn't exist yet */ if ( rc ) {
if ( rc && rc != LDAP_NO_SUCH_OBJECT ) /* It may be OK if the base object doesn't exist yet. */
return 1; if ( rc != LDAP_NO_SUCH_OBJECT )
return 1;
/* ITS#4194: But if dir was specified and no fname,
* then we were supposed to read the dir.
*/
if ( dir && !fname )
return 1;
}
/* If we read the config from back-ldif, nothing to do here */ /* If we read the config from back-ldif, nothing to do here */
if ( cfb->cb_got_ldif ) { if ( cfb->cb_got_ldif ) {
@ -3030,6 +3049,7 @@ config_send( Operation *op, SlapReply *rs, CfEntryInfo *ce, int depth )
{ {
rs->sr_attrs = op->ors_attrs; rs->sr_attrs = op->ors_attrs;
rs->sr_entry = ce->ce_entry; rs->sr_entry = ce->ce_entry;
rs->sr_flags = 0;
rc = send_search_entry( op, rs ); rc = send_search_entry( op, rs );
} }
if ( op->ors_scope == LDAP_SCOPE_SUBTREE ) { if ( op->ors_scope == LDAP_SCOPE_SUBTREE ) {
@ -3183,13 +3203,17 @@ check_name_index( CfEntryInfo *parent, ConfigType ce_type, Entry *e,
dnRdn( &e->e_name, &rdn ); dnRdn( &e->e_name, &rdn );
ptr1 = ber_bvchr( &e->e_name, '{' ); ptr1 = ber_bvchr( &e->e_name, '{' );
if ( ptr1 && ptr1 - e->e_name.bv_val < rdn.bv_len ) { if ( ptr1 && ptr1 - e->e_name.bv_val < rdn.bv_len ) {
char *next;
ptr2 = strchr( ptr1, '}' ); ptr2 = strchr( ptr1, '}' );
if (!ptr2 || ptr2 - e->e_name.bv_val > rdn.bv_len) if (!ptr2 || ptr2 - e->e_name.bv_val > rdn.bv_len)
return LDAP_NAMING_VIOLATION; return LDAP_NAMING_VIOLATION;
if ( ptr2-ptr1 == 1) if ( ptr2-ptr1 == 1)
return LDAP_NAMING_VIOLATION; return LDAP_NAMING_VIOLATION;
gotindex = 1; gotindex = 1;
index = atoi(ptr1+1); index = strtol( ptr1 + 1, &next, 10 );
if ( next == ptr1 + 1 || next[ 0 ] != '}' ) {
return LDAP_NAMING_VIOLATION;
}
if ( index < 0 ) { if ( index < 0 ) {
/* Special case, we allow -1 for the frontendDB */ /* Special case, we allow -1 for the frontendDB */
if ( index != -1 || ce_type != Cft_Database || if ( index != -1 || ce_type != Cft_Database ||
@ -3612,17 +3636,23 @@ config_back_add( Operation *op, SlapReply *rs )
} else if ( cfb->cb_use_ldif ) { } else if ( cfb->cb_use_ldif ) {
BackendDB *be = op->o_bd; BackendDB *be = op->o_bd;
slap_callback sc = { NULL, slap_null_cb, NULL, NULL }; slap_callback sc = { NULL, slap_null_cb, NULL, NULL };
struct berval dn, ndn;
op->o_bd = &cfb->cb_db; op->o_bd = &cfb->cb_db;
/* FIXME: there must be a better way. */
if ( ber_bvcmp( &op->o_bd->be_rootndn, &be->be_rootndn )) { /* Save current rootdn; use the underlying DB's rootdn */
op->o_bd->be_rootdn = be->be_rootdn; dn = op->o_dn;
op->o_bd->be_rootndn= be->be_rootndn; ndn = op->o_ndn;
} op->o_dn = op->o_bd->be_rootdn;
op->o_ndn = op->o_bd->be_rootndn;
sc.sc_next = op->o_callback; sc.sc_next = op->o_callback;
op->o_callback = &sc; op->o_callback = &sc;
op->o_bd->be_add( op, rs ); op->o_bd->be_add( op, rs );
op->o_bd = be; op->o_bd = be;
op->o_callback = sc.sc_next; op->o_callback = sc.sc_next;
op->o_dn = dn;
op->o_ndn = ndn;
} }
if ( renumber ) { if ( renumber ) {
} }
@ -3731,9 +3761,13 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs,
} }
for ( i=0; !BER_BVISNULL( &ml->sml_values[i] ); i++ ) { for ( i=0; !BER_BVISNULL( &ml->sml_values[i] ); i++ ) {
if ( ml->sml_values[i].bv_val[0] == '{' && if ( ml->sml_values[i].bv_val[0] == '{' &&
navals >= 0 ) { navals >= 0 )
int j = strtol( ml->sml_values[i].bv_val+1, NULL, 0 ); {
if ( j < navals ) { char *next, *val = ml->sml_values[i].bv_val + 1;
int j;
j = strtol( val, &next, 0 );
if ( next == val || next[ 0 ] != '}' || j < navals ) {
rc = LDAP_OTHER; rc = LDAP_OTHER;
snprintf(ca->msg, sizeof(ca->msg), "cannot insert %s", snprintf(ca->msg, sizeof(ca->msg), "cannot insert %s",
ml->sml_desc->ad_cname.bv_val ); ml->sml_desc->ad_cname.bv_val );
@ -3851,10 +3885,17 @@ config_modify_internal( CfEntryInfo *ce, Operation *op, SlapReply *rs,
ca->line = ml->sml_values[i].bv_val; ca->line = ml->sml_values[i].bv_val;
ca->valx = -1; ca->valx = -1;
if ( ml->sml_desc->ad_type->sat_flags & SLAP_AT_ORDERED && if ( ml->sml_desc->ad_type->sat_flags & SLAP_AT_ORDERED &&
ca->line[0] == '{' ) { ca->line[0] == '{' )
ptr = strchr( ca->line, '}' ); {
ptr = strchr( ca->line + 1, '}' );
if ( ptr ) { if ( ptr ) {
ca->valx = strtol( ca->line+1, NULL, 0 ); char *next;
ca->valx = strtol( ca->line + 1, &next, 0 );
if ( next == ca->line + 1 || next[ 0 ] != '}' ) {
rc = LDAP_OTHER;
goto out;
}
ca->line = ptr+1; ca->line = ptr+1;
} }
} }
@ -3941,16 +3982,22 @@ config_back_modify( Operation *op, SlapReply *rs )
} else if ( cfb->cb_use_ldif ) { } else if ( cfb->cb_use_ldif ) {
BackendDB *be = op->o_bd; BackendDB *be = op->o_bd;
slap_callback sc = { NULL, slap_null_cb, NULL, NULL }; slap_callback sc = { NULL, slap_null_cb, NULL, NULL };
struct berval dn, ndn;
op->o_bd = &cfb->cb_db; op->o_bd = &cfb->cb_db;
if ( ber_bvcmp( &op->o_bd->be_rootndn, &be->be_rootndn )) {
op->o_bd->be_rootdn = be->be_rootdn; dn = op->o_dn;
op->o_bd->be_rootndn= be->be_rootndn; ndn = op->o_ndn;
} op->o_dn = op->o_bd->be_rootdn;
op->o_ndn = op->o_bd->be_rootndn;
sc.sc_next = op->o_callback; sc.sc_next = op->o_callback;
op->o_callback = &sc; op->o_callback = &sc;
op->o_bd->be_modify( op, rs ); op->o_bd->be_modify( op, rs );
op->o_bd = be; op->o_bd = be;
op->o_callback = sc.sc_next; op->o_callback = sc.sc_next;
op->o_dn = dn;
op->o_ndn = ndn;
} }
ldap_pvt_thread_pool_resume( &connection_pool ); ldap_pvt_thread_pool_resume( &connection_pool );
@ -4247,7 +4294,7 @@ config_back_db_open( BackendDB *be )
struct berval rdn; struct berval rdn;
Entry *e, *parent; Entry *e, *parent;
CfEntryInfo *ce, *ceparent; CfEntryInfo *ce, *ceparent;
int i; int i, unsupp = 0;
BackendInfo *bi; BackendInfo *bi;
ConfigArgs c; ConfigArgs c;
Connection conn = {0}; Connection conn = {0};
@ -4266,12 +4313,11 @@ config_back_db_open( BackendDB *be )
op = (Operation *) &opbuf; op = (Operation *) &opbuf;
connection_fake_init( &conn, op, thrctx ); connection_fake_init( &conn, op, thrctx );
op->o_dn = be->be_rootdn;
op->o_ndn = be->be_rootndn;
op->o_tag = LDAP_REQ_ADD; op->o_tag = LDAP_REQ_ADD;
op->o_callback = &cb; op->o_callback = &cb;
op->o_bd = &cfb->cb_db; op->o_bd = &cfb->cb_db;
op->o_dn = op->o_bd->be_rootdn;
op->o_ndn = op->o_bd->be_rootndn;
} else { } else {
op = NULL; op = NULL;
} }
@ -4323,7 +4369,16 @@ config_back_db_open( BackendDB *be )
c.line = 0; c.line = 0;
LDAP_STAILQ_FOREACH( bi, &backendInfo, bi_next) { LDAP_STAILQ_FOREACH( bi, &backendInfo, bi_next) {
if (!bi->bi_cf_ocs) continue; if (!bi->bi_cf_ocs) {
/* If it only supports the old config mech, complain. */
if ( bi->bi_config ) {
Debug( LDAP_DEBUG_ANY,
"WARNING: No dynamic config support for backend %s.\n",
bi->bi_type, 0, 0 );
unsupp++;
}
continue;
}
if (!bi->bi_private) continue; if (!bi->bi_private) continue;
rdn.bv_val = c.log; rdn.bv_val = c.log;
@ -4350,6 +4405,16 @@ config_back_db_open( BackendDB *be )
} else { } else {
bi = be->bd_info; bi = be->bd_info;
} }
/* If this backend supports the old config mechanism, but not
* the new mech, complain.
*/
if ( !be->be_cf_ocs && bi->bi_db_config ) {
Debug( LDAP_DEBUG_ANY,
"WARNING: No dynamic config support for database %s.\n",
bi->bi_type, 0, 0 );
unsupp++;
}
rdn.bv_val = c.log; rdn.bv_val = c.log;
rdn.bv_len = snprintf(rdn.bv_val, sizeof( c.log ), rdn.bv_len = snprintf(rdn.bv_val, sizeof( c.log ),
"%s=" SLAP_X_ORDERED_FMT "%s", cfAd_database->ad_cname.bv_val, "%s=" SLAP_X_ORDERED_FMT "%s", cfAd_database->ad_cname.bv_val,
@ -4371,6 +4436,12 @@ config_back_db_open( BackendDB *be )
int j; int j;
for (j=0,on=oi->oi_list; on; j++,on=on->on_next) { for (j=0,on=oi->oi_list; on; j++,on=on->on_next) {
if ( on->on_bi.bi_db_config && !on->on_bi.bi_cf_ocs ) {
Debug( LDAP_DEBUG_ANY,
"WARNING: No dynamic config support for overlay %s.\n",
on->on_bi.bi_type, 0, 0 );
unsupp++;
}
rdn.bv_val = c.log; rdn.bv_val = c.log;
rdn.bv_len = snprintf(rdn.bv_val, sizeof( c.log ), rdn.bv_len = snprintf(rdn.bv_val, sizeof( c.log ),
"%s=" SLAP_X_ORDERED_FMT "%s", "%s=" SLAP_X_ORDERED_FMT "%s",
@ -4390,6 +4461,11 @@ config_back_db_open( BackendDB *be )
if ( thrctx ) if ( thrctx )
ldap_pvt_thread_pool_context_reset( thrctx ); ldap_pvt_thread_pool_context_reset( thrctx );
if ( unsupp && cfb->cb_use_ldif ) {
Debug( LDAP_DEBUG_ANY, "\nWARNING: The converted cn=config "
"directory is incomplete and may not work.\n\n", 0, 0, 0 );
}
return 0; return 0;
} }

@ -191,17 +191,50 @@ int config_check_vals(ConfigTable *Conf, ConfigArgs *c, int check_only ) {
int j; int j;
iarg = 0; larg = 0; barg = 0; iarg = 0; larg = 0; barg = 0;
switch(arg_type & ARGS_NUMERIC) { switch(arg_type & ARGS_NUMERIC) {
case ARG_INT: iarg = strtol(c->argv[1], NULL, 0); break; case ARG_INT:
case ARG_LONG: larg = strtol(c->argv[1], NULL, 0); break; if ( lutil_atoi( &iarg, c->argv[1] ) != 0 ) {
case ARG_BER_LEN_T: barg = (ber_len_t)atol(c->argv[1]); break; snprintf( c->msg, sizeof( c->msg ),
"<%s> unable to parse \"%s\" as int",
c->argv[0], c->argv[1] );
Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
c->log, c->msg, 0);
return(ARG_BAD_CONF);
}
break;
case ARG_LONG:
if ( lutil_atol( &larg, c->argv[1] ) != 0 ) {
snprintf( c->msg, sizeof( c->msg ),
"<%s> unable to parse \"%s\" as long",
c->argv[0], c->argv[1] );
Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
c->log, c->msg, 0);
return(ARG_BAD_CONF);
}
break;
case ARG_BER_LEN_T: {
unsigned long l;
if ( lutil_atoul( &l, c->argv[1] ) != 0 ) {
snprintf( c->msg, sizeof( c->msg ),
"<%s> unable to parse \"%s\" as ber_len_t",
c->argv[0], c->argv[1] );
Debug(LDAP_DEBUG_CONFIG, "%s: %s\n",
c->log, c->msg, 0);
return(ARG_BAD_CONF);
}
barg = (ber_len_t)l;
} break;
case ARG_ON_OFF: case ARG_ON_OFF:
if(c->argc == 1) { if (c->argc == 1) {
iarg = 1; iarg = 1;
} else if(!strcasecmp(c->argv[1], "on") || } else if ( !strcasecmp(c->argv[1], "on") ||
!strcasecmp(c->argv[1], "true")) { !strcasecmp(c->argv[1], "true") ||
!strcasecmp(c->argv[1], "yes") )
{
iarg = 1; iarg = 1;
} else if(!strcasecmp(c->argv[1], "off") || } else if ( !strcasecmp(c->argv[1], "off") ||
!strcasecmp(c->argv[1], "false")) { !strcasecmp(c->argv[1], "false") ||
!strcasecmp(c->argv[1], "no") )
{
iarg = 0; iarg = 0;
} else { } else {
snprintf( c->msg, sizeof( c->msg ), "<%s> invalid value, ignored", snprintf( c->msg, sizeof( c->msg ), "<%s> invalid value, ignored",
@ -448,6 +481,7 @@ init_config_attrs(ConfigTable *ct) {
freeit = 1; freeit = 1;
} else { } else {
ldap_attributetype_free( at );
fprintf( stderr, "init_config_attrs: AttributeType \"%s\": %s, %s\n", fprintf( stderr, "init_config_attrs: AttributeType \"%s\": %s, %s\n",
ct[i].attribute, scherr2str(code), err ); ct[i].attribute, scherr2str(code), err );
return code; return code;
@ -1013,9 +1047,11 @@ slap_cf_aux_table_parse( const char *word, void *dst, slap_cf_aux_table *tab0, L
for (tab = tab0; !BER_BVISNULL(&tab->key); tab++ ) { for (tab = tab0; !BER_BVISNULL(&tab->key); tab++ ) {
if ( !strncasecmp( word, tab->key.bv_val, tab->key.bv_len )) { if ( !strncasecmp( word, tab->key.bv_val, tab->key.bv_len )) {
char **cptr, *next; char **cptr;
int *iptr, j; int *iptr, j;
unsigned *uptr; unsigned *uptr;
long *lptr;
unsigned long *ulptr;
struct berval *bptr; struct berval *bptr;
const char *val = word + tab->key.bv_len; const char *val = word + tab->key.bv_len;
@ -1046,19 +1082,25 @@ slap_cf_aux_table_parse( const char *word, void *dst, slap_cf_aux_table *tab0, L
case 'i': case 'i':
iptr = (int *)((char *)dst + tab->off); iptr = (int *)((char *)dst + tab->off);
*iptr = strtol( val, &next, 0 ); rc = lutil_atoix( iptr, val, 0 );
if ( next == val || next[ 0 ] != '\0' ) {
rc = 1;
}
break; break;
case 'u': case 'u':
uptr = (unsigned *)((char *)dst + tab->off); uptr = (unsigned *)((char *)dst + tab->off);
*uptr = strtoul( val, &next, 0 ); rc = lutil_atoux( uptr, val, 0 );
if ( next == val || next[ 0 ] != '\0' ) { break;
rc = 1;
} case 'I':
lptr = (long *)((char *)dst + tab->off);
rc = lutil_atolx( lptr, val, 0 );
break;
case 'U':
ulptr = (unsigned long *)((char *)dst + tab->off);
rc = lutil_atoulx( ulptr, val, 0 );
break; break;
} }
@ -1086,6 +1128,8 @@ slap_cf_aux_table_unparse( void *src, struct berval *bv, slap_cf_aux_table *tab0
char **cptr; char **cptr;
int *iptr, i; int *iptr, i;
unsigned *uptr; unsigned *uptr;
long *lptr;
unsigned long *ulptr;
struct berval *bptr; struct berval *bptr;
cptr = (char **)((char *)src + tab->off); cptr = (char **)((char *)src + tab->off);
@ -1131,6 +1175,23 @@ slap_cf_aux_table_unparse( void *src, struct berval *bv, slap_cf_aux_table *tab0
ptr = lutil_strcopy( ptr, tab->key.bv_val ); ptr = lutil_strcopy( ptr, tab->key.bv_val );
ptr += snprintf( ptr, sizeof( buf ) - ( ptr - buf ), "%u", *uptr ); ptr += snprintf( ptr, sizeof( buf ) - ( ptr - buf ), "%u", *uptr );
break; break;
case 'I':
lptr = (long *)((char *)src + tab->off);
*ptr++ = ' ';
ptr = lutil_strcopy( ptr, tab->key.bv_val );
ptr += snprintf( ptr, sizeof( buf ) - ( ptr - buf ), "%ld", *lptr );
break;
case 'U':
ulptr = (unsigned long *)((char *)src + tab->off);
*ptr++ = ' ';
ptr = lutil_strcopy( ptr, tab->key.bv_val );
ptr += snprintf( ptr, sizeof( buf ) - ( ptr - buf ), "%lu", *ulptr );
break;
default:
assert( 0 );
} }
} }
tmp.bv_val = buf; tmp.bv_val = buf;

@ -14,6 +14,9 @@
* <http://www.OpenLDAP.org/license.html>. * <http://www.OpenLDAP.org/license.html>.
*/ */
#ifndef CONFIG_H
#define CONFIG_H
typedef struct ConfigTable { typedef struct ConfigTable {
char *name; char *name;
char *what; char *what;
@ -169,3 +172,13 @@ int read_config_file(const char *fname, int depth, ConfigArgs *cf,
ConfigTable * config_find_keyword(ConfigTable *ct, ConfigArgs *c); ConfigTable * config_find_keyword(ConfigTable *ct, ConfigArgs *c);
Entry * config_build_entry( Operation *op, SlapReply *rs, CfEntryInfo *parent, Entry * config_build_entry( Operation *op, SlapReply *rs, CfEntryInfo *parent,
ConfigArgs *c, struct berval *rdn, ConfigOCs *main, ConfigOCs *extra ); ConfigArgs *c, struct berval *rdn, ConfigOCs *main, ConfigOCs *extra );
int config_shadow( ConfigArgs *c, int flag );
#define config_slurp_shadow(c) config_shadow((c), SLAP_DBFLAG_SLURP_SHADOW)
#define config_sync_shadow(c) config_shadow((c), SLAP_DBFLAG_SYNC_SHADOW)
/* Make sure we don't exceed the bits reserved for userland */
#define config_check_userland(last) \
assert( ( ( (last) - 1 ) & ARGS_USERLAND ) == ( (last) - 1 ) );
#endif /* CONFIG_H */

@ -606,9 +606,7 @@ long connection_init(
c->c_send_search_entry = slap_send_search_entry; c->c_send_search_entry = slap_send_search_entry;
c->c_send_search_reference = slap_send_search_reference; c->c_send_search_reference = slap_send_search_reference;
c->c_send_ldap_extended = slap_send_ldap_extended; c->c_send_ldap_extended = slap_send_ldap_extended;
#ifdef LDAP_RES_INTERMEDIATE
c->c_send_ldap_intermediate = slap_send_ldap_intermediate; c->c_send_ldap_intermediate = slap_send_ldap_intermediate;
#endif
BER_BVZERO( &c->c_authmech ); BER_BVZERO( &c->c_authmech );
BER_BVZERO( &c->c_dn ); BER_BVZERO( &c->c_dn );

@ -29,6 +29,7 @@ static SLAP_CTRL_PARSE_FN parsePreRead;
static SLAP_CTRL_PARSE_FN parsePostRead; static SLAP_CTRL_PARSE_FN parsePostRead;
static SLAP_CTRL_PARSE_FN parseProxyAuthz; static SLAP_CTRL_PARSE_FN parseProxyAuthz;
#ifdef LDAP_DEVEL #ifdef LDAP_DEVEL
static SLAP_CTRL_PARSE_FN parseDontUseCopy;
static SLAP_CTRL_PARSE_FN parseManageDIT; static SLAP_CTRL_PARSE_FN parseManageDIT;
#endif #endif
static SLAP_CTRL_PARSE_FN parseManageDSAit; static SLAP_CTRL_PARSE_FN parseManageDSAit;
@ -125,41 +126,37 @@ static struct slap_control control_defs[] = {
SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE, NULL, SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE, NULL,
parseSortedResults, LDAP_SLIST_ENTRY_INITIALIZER(next) }, parseSortedResults, LDAP_SLIST_ENTRY_INITIALIZER(next) },
#endif #endif
#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
{ LDAP_CONTROL_X_DOMAIN_SCOPE, { LDAP_CONTROL_X_DOMAIN_SCOPE,
(int)offsetof(struct slap_control_ids, sc_domainScope), (int)offsetof(struct slap_control_ids, sc_domainScope),
SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH, NULL, SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE, NULL,
parseDomainScope, LDAP_SLIST_ENTRY_INITIALIZER(next) }, parseDomainScope, LDAP_SLIST_ENTRY_INITIALIZER(next) },
#endif
#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
{ LDAP_CONTROL_X_PERMISSIVE_MODIFY, { LDAP_CONTROL_X_PERMISSIVE_MODIFY,
(int)offsetof(struct slap_control_ids, sc_permissiveModify), (int)offsetof(struct slap_control_ids, sc_permissiveModify),
SLAP_CTRL_MODIFY, NULL, SLAP_CTRL_MODIFY|SLAP_CTRL_HIDE, NULL,
parsePermissiveModify, LDAP_SLIST_ENTRY_INITIALIZER(next) }, parsePermissiveModify, LDAP_SLIST_ENTRY_INITIALIZER(next) },
#endif
#ifdef SLAP_CONTROL_X_TREE_DELETE #ifdef SLAP_CONTROL_X_TREE_DELETE
{ LDAP_CONTROL_X_TREE_DELETE, { LDAP_CONTROL_X_TREE_DELETE,
(int)offsetof(struct slap_control_ids, sc_treeDelete), (int)offsetof(struct slap_control_ids, sc_treeDelete),
SLAP_CTRL_HIDE|SLAP_CTRL_DELETE, NULL, SLAP_CTRL_DELETE|SLAP_CTRL_HIDE, NULL,
parseTreeDelete, LDAP_SLIST_ENTRY_INITIALIZER(next) }, parseTreeDelete, LDAP_SLIST_ENTRY_INITIALIZER(next) },
#endif #endif
#ifdef LDAP_CONTROL_X_SEARCH_OPTIONS
{ LDAP_CONTROL_X_SEARCH_OPTIONS, { LDAP_CONTROL_X_SEARCH_OPTIONS,
(int)offsetof(struct slap_control_ids, sc_searchOptions), (int)offsetof(struct slap_control_ids, sc_searchOptions),
SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH, NULL, SLAP_CTRL_GLOBAL|SLAP_CTRL_SEARCH|SLAP_CTRL_HIDE, NULL,
parseSearchOptions, LDAP_SLIST_ENTRY_INITIALIZER(next) }, parseSearchOptions, LDAP_SLIST_ENTRY_INITIALIZER(next) },
#endif
#ifdef LDAP_CONTROL_SUBENTRIES
{ LDAP_CONTROL_SUBENTRIES, { LDAP_CONTROL_SUBENTRIES,
(int)offsetof(struct slap_control_ids, sc_subentries), (int)offsetof(struct slap_control_ids, sc_subentries),
SLAP_CTRL_SEARCH, NULL, SLAP_CTRL_SEARCH, NULL,
parseSubentries, LDAP_SLIST_ENTRY_INITIALIZER(next) }, parseSubentries, LDAP_SLIST_ENTRY_INITIALIZER(next) },
#endif
{ LDAP_CONTROL_NOOP, { LDAP_CONTROL_NOOP,
(int)offsetof(struct slap_control_ids, sc_noOp), (int)offsetof(struct slap_control_ids, sc_noOp),
SLAP_CTRL_HIDE|SLAP_CTRL_ACCESS, NULL, SLAP_CTRL_ACCESS|SLAP_CTRL_HIDE, NULL,
parseNoOp, LDAP_SLIST_ENTRY_INITIALIZER(next) }, parseNoOp, LDAP_SLIST_ENTRY_INITIALIZER(next) },
#ifdef LDAP_DEVEL #ifdef LDAP_DEVEL
{ LDAP_CONTROL_DONTUSECOPY,
(int)offsetof(struct slap_control_ids, sc_dontUseCopy),
SLAP_CTRL_INTROGATE|SLAP_CTRL_HIDE, NULL,
parseDontUseCopy, LDAP_SLIST_ENTRY_INITIALIZER(next) },
{ LDAP_CONTROL_MANAGEDIT, { LDAP_CONTROL_MANAGEDIT,
(int)offsetof(struct slap_control_ids, sc_manageDIT), (int)offsetof(struct slap_control_ids, sc_manageDIT),
SLAP_CTRL_GLOBAL|SLAP_CTRL_UPDATE|SLAP_CTRL_HIDE, NULL, SLAP_CTRL_GLOBAL|SLAP_CTRL_UPDATE|SLAP_CTRL_HIDE, NULL,
@ -706,7 +703,8 @@ slap_remove_control(
switch ( op->o_ctrlflag[ ctrl ] ) { switch ( op->o_ctrlflag[ ctrl ] ) {
case SLAP_CONTROL_NONCRITICAL: case SLAP_CONTROL_NONCRITICAL:
for ( i = 0, j = -1; op->o_ctrls[ i ] != NULL; i++ ) { for ( i = 0, j = -1; op->o_ctrls[ i ] != NULL; i++ ) {
if ( strcmp( op->o_ctrls[ i ]->ldctl_oid, slap_known_controls[ ctrl - 1 ] ) == 0 ) if ( strcmp( op->o_ctrls[ i ]->ldctl_oid,
slap_known_controls[ ctrl - 1 ] ) == 0 )
{ {
j = i; j = i;
} }
@ -763,6 +761,30 @@ slap_remove_control(
} }
#ifdef LDAP_DEVEL #ifdef LDAP_DEVEL
static int parseDontUseCopy (
Operation *op,
SlapReply *rs,
LDAPControl *ctrl )
{
if ( op->o_dontUseCopy != SLAP_CONTROL_NONE ) {
rs->sr_text = "dontUseCopy control specified multiple times";
return LDAP_PROTOCOL_ERROR;
}
if ( ctrl->ldctl_value.bv_len ) {
rs->sr_text = "dontUseCopy control value not empty";
return LDAP_PROTOCOL_ERROR;
}
if ( ctrl->ldctl_iscritical != SLAP_CONTROL_CRITICAL ) {
rs->sr_text = "dontUseCopy criticality of FALSE not allowed";
return LDAP_PROTOCOL_ERROR;
}
op->o_dontUseCopy = SLAP_CONTROL_CRITICAL;
return LDAP_SUCCESS;
}
static int parseManageDIT ( static int parseManageDIT (
Operation *op, Operation *op,
SlapReply *rs, SlapReply *rs,
@ -1042,8 +1064,8 @@ static int parseAssert (
return LDAP_OTHER; return LDAP_OTHER;
} }
rs->sr_err = get_filter( op, ber, (Filter **)&(op->o_assertion), &rs->sr_text); rs->sr_err = get_filter( op, ber, (Filter **)&(op->o_assertion),
&rs->sr_text);
if( rs->sr_err != LDAP_SUCCESS ) { if( rs->sr_err != LDAP_SUCCESS ) {
if( rs->sr_err == SLAPD_DISCONNECT ) { if( rs->sr_err == SLAPD_DISCONNECT ) {
rs->sr_err = LDAP_PROTOCOL_ERROR; rs->sr_err = LDAP_PROTOCOL_ERROR;
@ -1214,7 +1236,8 @@ static int parseValuesReturnFilter (
return LDAP_OTHER; return LDAP_OTHER;
} }
rs->sr_err = get_vrFilter( op, ber, (ValuesReturnFilter **)&(op->o_vrFilter), &rs->sr_text); rs->sr_err = get_vrFilter( op, ber,
(ValuesReturnFilter **)&(op->o_vrFilter), &rs->sr_text);
if( rs->sr_err != LDAP_SUCCESS ) { if( rs->sr_err != LDAP_SUCCESS ) {
if( rs->sr_err == SLAPD_DISCONNECT ) { if( rs->sr_err == SLAPD_DISCONNECT ) {
@ -1244,7 +1267,6 @@ static int parseValuesReturnFilter (
return LDAP_SUCCESS; return LDAP_SUCCESS;
} }
#ifdef LDAP_CONTROL_SUBENTRIES
static int parseSubentries ( static int parseSubentries (
Operation *op, Operation *op,
SlapReply *rs, SlapReply *rs,
@ -1274,9 +1296,7 @@ static int parseSubentries (
return LDAP_SUCCESS; return LDAP_SUCCESS;
} }
#endif
#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
static int parsePermissiveModify ( static int parsePermissiveModify (
Operation *op, Operation *op,
SlapReply *rs, SlapReply *rs,
@ -1298,9 +1318,7 @@ static int parsePermissiveModify (
return LDAP_SUCCESS; return LDAP_SUCCESS;
} }
#endif
#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
static int parseDomainScope ( static int parseDomainScope (
Operation *op, Operation *op,
SlapReply *rs, SlapReply *rs,
@ -1322,7 +1340,6 @@ static int parseDomainScope (
return LDAP_SUCCESS; return LDAP_SUCCESS;
} }
#endif
#ifdef SLAP_CONTROL_X_TREE_DELETE #ifdef SLAP_CONTROL_X_TREE_DELETE
static int parseTreeDelete ( static int parseTreeDelete (
@ -1348,7 +1365,6 @@ static int parseTreeDelete (
} }
#endif #endif
#ifdef LDAP_CONTROL_X_SEARCH_OPTIONS
static int parseSearchOptions ( static int parseSearchOptions (
Operation *op, Operation *op,
SlapReply *rs, SlapReply *rs,
@ -1399,5 +1415,4 @@ static int parseSearchOptions (
return LDAP_SUCCESS; return LDAP_SUCCESS;
} }
#endif

@ -1729,9 +1729,13 @@ slapd_daemon_task(
ber_socket_t active; ber_socket_t active;
if( slapd_gentle_shutdown == 1 ) { if( slapd_gentle_shutdown == 1 ) {
BackendDB *be;
Debug( LDAP_DEBUG_ANY, "slapd gentle shutdown\n", 0, 0, 0 ); Debug( LDAP_DEBUG_ANY, "slapd gentle shutdown\n", 0, 0, 0 );
close_listeners( 1 ); close_listeners( 1 );
frontendDB->be_restrictops |= SLAP_RESTRICT_OP_WRITES; frontendDB->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
LDAP_STAILQ_FOREACH(be, &backendDB, be_next) {
be->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
}
slapd_gentle_shutdown = 2; slapd_gentle_shutdown = 2;
} }
@ -1739,7 +1743,7 @@ slapd_daemon_task(
active = slap_daemon.sd_nactives; active = slap_daemon.sd_nactives;
ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex ); ldap_pvt_thread_mutex_unlock( &slap_daemon.sd_mutex );
if( active == 0 ) { if( active == 0 ) {
slapd_shutdown = 2; slapd_shutdown = 1;
break; break;
} }
} }

@ -45,11 +45,6 @@ static int get_ssa(
SubstringsAssertion **s, SubstringsAssertion **s,
const char **text ); const char **text );
static int filter_escape_value_x(
struct berval *in,
struct berval *out,
void *ctx );
static void simple_vrFilter2bv( static void simple_vrFilter2bv(
Operation *op, Operation *op,
ValuesReturnFilter *f, ValuesReturnFilter *f,
@ -782,42 +777,6 @@ filter2bv( Filter *f, struct berval *fstr )
filter2bv_x( &op, f, fstr ); filter2bv_x( &op, f, fstr );
} }
static int
filter_escape_value_x(
struct berval *in,
struct berval *out,
void *ctx )
{
ber_len_t i;
assert( in != NULL );
assert( out != NULL );
i = in->bv_len * 3 + 1;
out->bv_val = ctx ? slap_sl_malloc( i, ctx ) : ch_malloc( i );
out->bv_len = 0;
for( i=0; i < in->bv_len ; i++ ) {
if( FILTER_ESCAPE(in->bv_val[i]) ) {
out->bv_val[out->bv_len++] = SLAP_ESCAPE_CHAR;
out->bv_val[out->bv_len++] = SLAP_ESCAPE_HI( in->bv_val[i] );
out->bv_val[out->bv_len++] = SLAP_ESCAPE_LO( in->bv_val[i] );
} else {
out->bv_val[out->bv_len++] = in->bv_val[i];
}
}
out->bv_val[out->bv_len] = '\0';
return LDAP_SUCCESS;
}
int
filter_escape_value(
struct berval *in,
struct berval *out )
{
return filter_escape_value_x( in, out, NULL );
}
static int static int
get_simple_vrFilter( get_simple_vrFilter(
Operation *op, Operation *op,

@ -112,7 +112,6 @@ slap_parse_sync_cookie(
|| rid_ptr > &cookie->octet_str.bv_val[ cookie->octet_str.bv_len - STRLENOF( "rid=" ) ] ) || rid_ptr > &cookie->octet_str.bv_val[ cookie->octet_str.bv_len - STRLENOF( "rid=" ) ] )
{ {
return -1; return -1;
} }
cookie->rid = strtoul( &rid_ptr[ STRLENOF( "rid=" ) ], &next, 10 ); cookie->rid = strtoul( &rid_ptr[ STRLENOF( "rid=" ) ], &next, 10 );

@ -650,14 +650,9 @@ limits_parse_one(
limit->lms_t_soft = -1; limit->lms_t_soft = -1;
} else { } else {
char *next = NULL; int soft;
int soft = strtol( arg, &next, 10 );
if ( next == arg || next[ 0 ] != '\0' ) { if ( lutil_atoi( &soft, arg ) != 0 || soft < -1 ) {
return( 1 );
}
if ( soft < -1 ) {
return( 1 ); return( 1 );
} }
@ -677,14 +672,9 @@ limits_parse_one(
limit->lms_t_hard = -1; limit->lms_t_hard = -1;
} else { } else {
char *next = NULL; int hard;
int hard = strtol( arg, &next, 10 );
if ( next == arg || next[ 0 ] != '\0' ) { if ( lutil_atoi( &hard, arg ) != 0 || hard < -1 ) {
return( 1 );
}
if ( hard < -1 ) {
return( 1 ); return( 1 );
} }
@ -709,10 +699,9 @@ limits_parse_one(
limit->lms_t_soft = -1; limit->lms_t_soft = -1;
} else { } else {
char *next = NULL; if ( lutil_atoi( &limit->lms_t_soft, arg ) != 0
|| limit->lms_t_soft < -1 )
limit->lms_t_soft = strtol( arg, &next, 10 ); {
if ( next == arg || limit->lms_t_soft < -1 ) {
return( 1 ); return( 1 );
} }
} }
@ -733,14 +722,9 @@ limits_parse_one(
limit->lms_s_soft = -1; limit->lms_s_soft = -1;
} else { } else {
char *next = NULL; int soft;
int soft = strtol( arg, &next, 10 );
if ( next == arg || next[ 0 ] != '\0' ) { if ( lutil_atoi( &soft, arg ) != 0 || soft < -1 ) {
return( 1 );
}
if ( soft < -1 ) {
return( 1 ); return( 1 );
} }
@ -760,14 +744,9 @@ limits_parse_one(
limit->lms_s_hard = -1; limit->lms_s_hard = -1;
} else { } else {
char *next = NULL; int hard;
int hard = strtol( arg, &next, 10 );
if ( next == arg || next[ 0 ] != '\0' ) { if ( lutil_atoi( &hard, arg ) != 0 || hard < -1 ) {
return( 1 );
}
if ( hard < -1 ) {
return( 1 ); return( 1 );
} }
@ -791,14 +770,9 @@ limits_parse_one(
limit->lms_s_unchecked = 0; limit->lms_s_unchecked = 0;
} else { } else {
char *next = NULL; int unchecked;
int unchecked = strtol( arg, &next, 10 );
if ( next == arg || next[ 0 ] != '\0' ) { if ( lutil_atoi( &unchecked, arg ) != 0 || unchecked < -1 ) {
return( 1 );
}
if ( unchecked < -1 ) {
return( 1 ); return( 1 );
} }
@ -818,14 +792,9 @@ limits_parse_one(
limit->lms_s_pr = -1; limit->lms_s_pr = -1;
} else { } else {
char *next = NULL; int pr;
int pr = strtol( arg, &next, 10 );
if ( next == arg || next[ 0 ] != '\0' ) { if ( lutil_atoi( &pr, arg ) != 0 || pr < -1 ) {
return( 1 );
}
if ( pr < -1 ) {
return( 1 ); return( 1 );
} }
@ -849,15 +818,9 @@ limits_parse_one(
limit->lms_s_pr_total = 0; limit->lms_s_pr_total = 0;
} else { } else {
char *next = NULL;
int total; int total;
total = strtol( arg, &next, 10 ); if ( lutil_atoi( &total, arg ) != 0 || total < -1 ) {
if ( next == arg || next[ 0 ] != '\0' ) {
return( 1 );
}
if ( total < -1 ) {
return( 1 ); return( 1 );
} }
@ -882,10 +845,9 @@ limits_parse_one(
limit->lms_s_soft = -1; limit->lms_s_soft = -1;
} else { } else {
char *next = NULL; if ( lutil_atoi( &limit->lms_s_soft, arg ) != 0
|| limit->lms_s_soft < -1 )
limit->lms_s_soft = strtol( arg, &next, 10 ); {
if ( next == arg || limit->lms_s_soft < -1 ) {
return( 1 ); return( 1 );
} }
} }

@ -406,10 +406,8 @@ int main( int argc, char **argv )
slap_debug |= level; slap_debug |= level;
} else { } else {
int level; int level;
char *next = NULL;
level = strtol( optarg, &next, 0 ); if ( lutil_atoix( &level, optarg, 0 ) != 0 ) {
if ( next == NULL || next[ 0 ] != '\0' ) {
fprintf( stderr, fprintf( stderr,
"unrecognized log level " "unrecognized log level "
"\"%s\"\n", optarg ); "\"%s\"\n", optarg );
@ -418,7 +416,7 @@ int main( int argc, char **argv )
slap_debug |= level; slap_debug |= level;
} }
#else #else
if ( atoi( optarg ) != 0 ) if ( lutil_atoi( &level, optarg ) != 0 || level != 0 )
fputs( "must compile with LDAP_DEBUG for debugging\n", fputs( "must compile with LDAP_DEBUG for debugging\n",
stderr ); stderr );
#endif #endif
@ -467,7 +465,10 @@ int main( int argc, char **argv )
} }
case 's': /* set syslog level */ case 's': /* set syslog level */
ldap_syslog = atoi( optarg ); if ( lutil_atoi( &ldap_syslog, optarg ) != 0 ) {
fprintf( stderr, "unable to parse syslog level \"%s\"", optarg );
goto destroy;
}
break; break;
#ifdef LOG_LOCAL4 #ifdef LOG_LOCAL4

@ -28,6 +28,7 @@
#include <ac/string.h> #include <ac/string.h>
#include "slap.h" #include "slap.h"
#include "lutil.h"
int int
modify_add_values( modify_add_values(
@ -386,7 +387,12 @@ modify_increment_values(
if ( !strcmp( a->a_desc->ad_type->sat_syntax_oid, SLAPD_INTEGER_SYNTAX )) { if ( !strcmp( a->a_desc->ad_type->sat_syntax_oid, SLAPD_INTEGER_SYNTAX )) {
int i; int i;
char str[sizeof(long)*3 + 2]; /* overly long */ char str[sizeof(long)*3 + 2]; /* overly long */
long incr = atol( mod->sm_values[0].bv_val ); long incr;
if ( lutil_atol( &incr, mod->sm_values[0].bv_val ) != 0 ) {
*text = "modify/increment: invalid syntax of increment";
return LDAP_INVALID_SYNTAX;
}
/* treat zero and errors as a no-op */ /* treat zero and errors as a no-op */
if( incr == 0 ) { if( incr == 0 ) {
@ -395,13 +401,18 @@ modify_increment_values(
for( i = 0; !BER_BVISNULL( &a->a_nvals[i] ); i++ ) { for( i = 0; !BER_BVISNULL( &a->a_nvals[i] ); i++ ) {
char *tmp; char *tmp;
long value = atol( a->a_nvals[i].bv_val ); long value;
size_t strln = snprintf( str, sizeof(str), "%ld", value+incr ); size_t strln;
if ( lutil_atol( &value, a->a_nvals[i].bv_val ) != 0 ) {
*text = "modify/increment: invalid syntax of original value";
return LDAP_INVALID_SYNTAX;
}
strln = snprintf( str, sizeof(str), "%ld", value+incr );
tmp = SLAP_REALLOC( a->a_nvals[i].bv_val, strln+1 ); tmp = SLAP_REALLOC( a->a_nvals[i].bv_val, strln+1 );
if( tmp == NULL ) { if( tmp == NULL ) {
*text = "modify/increment: reallocation error"; *text = "modify/increment: reallocation error";
return LDAP_OTHER;; return LDAP_OTHER;
} }
a->a_nvals[i].bv_val = tmp; a->a_nvals[i].bv_val = tmp;
a->a_nvals[i].bv_len = strln; a->a_nvals[i].bv_len = strln;

@ -524,6 +524,30 @@ oc_insert(
rc = oc_check_dup( old_soc, soc ); rc = oc_check_dup( old_soc, soc );
ldap_memfree( oir ); ldap_memfree( oir );
while ( names > soc->soc_names ) {
struct oindexrec tmpoir;
names--;
ber_str2bv( *names, 0, 0, &tmpoir.oir_name );
tmpoir.oir_oc = soc;
oir = (struct oindexrec *)avl_delete( &oc_index,
(caddr_t)&tmpoir, oc_index_cmp );
assert( oir != NULL );
ldap_memfree( oir );
}
if ( soc->soc_oid ) {
struct oindexrec tmpoir;
ber_str2bv( soc->soc_oid, 0, 0, &tmpoir.oir_name );
tmpoir.oir_oc = soc;
oir = (struct oindexrec *)avl_delete( &oc_index,
(caddr_t)&tmpoir, oc_index_cmp );
assert( oir != NULL );
ldap_memfree( oir );
}
return rc; return rc;
} }

@ -29,6 +29,7 @@ SRCS = overlays.c \
unique.c \ unique.c \
valsort.c valsort.c
OBJS = overlays.o \ OBJS = overlays.o \
statover.o \
@SLAPD_STATIC_OVERLAYS@ @SLAPD_STATIC_OVERLAYS@
# Add here the objs that are needed by overlays, but do not make it # Add here the objs that are needed by overlays, but do not make it
@ -113,6 +114,8 @@ MKDEPFLAG = -l
.c.lo: .c.lo:
$(LTCOMPILE_MOD) $< $(LTCOMPILE_MOD) $<
statover.o: statover.c $(srcdir)/../slap.h
$(LIBRARY): $(OBJS) version.lo $(LIBRARY): $(OBJS) version.lo
$(AR) rs $@ $(OBJS) $(AR) rs $@ $(OBJS)
@ -124,3 +127,6 @@ depend-local:
mv Makefile Makefile.bak; $(SED) $$SCR Makefile.bak > Makefile && \ mv Makefile Makefile.bak; $(SED) $$SCR Makefile.bak > Makefile && \
$(RM) Makefile.bak; fi $(RM) Makefile.bak; fi
veryclean-local:
$(RM) statover.c

@ -990,7 +990,9 @@ static int accesslog_response(Operation *op, SlapReply *rs) {
bv.bv_len = sprintf( bv.bv_val, "%d", op->ors_tlimit ); bv.bv_len = sprintf( bv.bv_val, "%d", op->ors_tlimit );
attr_merge_one( e, ad_reqTimeLimit, &bv, NULL ); attr_merge_one( e, ad_reqTimeLimit, &bv, NULL );
/* FIXME: slimit was zeroed by the backends */
bv.bv_len = sprintf( bv.bv_val, "%d", op->ors_slimit );
attr_merge_one( e, ad_reqSizeLimit, &bv, NULL );
break; break;
case LOG_EN_BIND: case LOG_EN_BIND:
@ -1200,20 +1202,113 @@ accesslog_db_destroy(
{ {
slap_overinst *on = (slap_overinst *)be->bd_info; slap_overinst *on = (slap_overinst *)be->bd_info;
log_info *li = on->on_bi.bi_private; log_info *li = on->on_bi.bi_private;
ldap_pvt_thread_mutex_destroy( &li->li_log_mutex ); ldap_pvt_thread_mutex_destroy( &li->li_log_mutex );
ldap_pvt_thread_mutex_destroy( &li->li_op_mutex ); ldap_pvt_thread_mutex_destroy( &li->li_op_mutex );
free( li ); free( li );
return LDAP_SUCCESS; return LDAP_SUCCESS;
} }
int accesslog_init() static int
accesslog_db_open(
BackendDB *be
)
{
slap_overinst *on = (slap_overinst *)be->bd_info;
log_info *li = on->on_bi.bi_private;
Connection conn;
OperationBuffer opbuf;
Operation *op = (Operation *) &opbuf;
Entry *e;
int rc;
void *thrctx;
if ( slapMode & SLAP_TOOL_MODE )
return 0;
thrctx = ldap_pvt_thread_pool_context();
connection_fake_init( &conn, op, thrctx );
op->o_bd = li->li_db;
op->o_dn = li->li_db->be_rootdn;
op->o_ndn = li->li_db->be_rootndn;
rc = be_entry_get_rw( op, li->li_db->be_nsuffix, NULL, NULL, 0, &e );
if ( e ) {
be_entry_release_rw( op, e, 0 );
} else {
SlapReply rs = {REP_RESULT};
struct berval rdn, nrdn, attr;
char *ptr;
AttributeDescription *ad = NULL;
const char *text = NULL;
Entry *e_ctx;
e = ch_calloc( 1, sizeof( Entry ));
e->e_name = *li->li_db->be_suffix;
e->e_nname = *li->li_db->be_nsuffix;
attr_merge_one( e, slap_schema.si_ad_objectClass,
&log_container->soc_cname, NULL );
dnRdn( &e->e_name, &rdn );
dnRdn( &e->e_nname, &nrdn );
ptr = ber_bvchr( &rdn, '=' );
assert( ptr != NULL );
attr.bv_val = rdn.bv_val;
attr.bv_len = ptr - rdn.bv_val;
slap_bv2ad( &attr, &ad, &text );
rdn.bv_val = ptr+1;
rdn.bv_len -= attr.bv_len + 1;
ptr = ber_bvchr( &nrdn, '=' );
nrdn.bv_len -= ptr - nrdn.bv_val + 1;
nrdn.bv_val = ptr+1;
attr_merge_one( e, ad, &rdn, &nrdn );
/* Get contextCSN from main DB */
op->o_bd = be;
op->o_bd->bd_info = on->on_info->oi_orig;
rc = be_entry_get_rw( op, be->be_nsuffix, NULL,
slap_schema.si_ad_contextCSN, 0, &e_ctx );
if ( e_ctx ) {
Attribute *a;
a = attr_find( e_ctx->e_attrs, slap_schema.si_ad_contextCSN );
if ( a )
attr_merge( e, a->a_desc, a->a_vals, NULL );
be_entry_release_rw( op, e_ctx, 0 );
}
op->o_bd->bd_info = (BackendInfo *)on;
op->o_bd = li->li_db;
op->ora_e = e;
op->o_req_dn = e->e_name;
op->o_req_ndn = e->e_nname;
op->o_callback = &nullsc;
SLAP_DBFLAGS( op->o_bd ) |= SLAP_DBFLAG_NOLASTMOD;
rc = op->o_bd->be_add( op, &rs );
SLAP_DBFLAGS( op->o_bd ) ^= SLAP_DBFLAG_NOLASTMOD;
attrs_free( e->e_attrs );
ch_free( e );
}
ldap_pvt_thread_pool_context_reset( thrctx );
return rc;
}
int accesslog_initialize()
{ {
int i, rc; int i, rc;
accesslog.on_bi.bi_type = "accesslog"; accesslog.on_bi.bi_type = "accesslog";
accesslog.on_bi.bi_db_init = accesslog_db_init; accesslog.on_bi.bi_db_init = accesslog_db_init;
accesslog.on_bi.bi_db_destroy = accesslog_db_destroy; accesslog.on_bi.bi_db_destroy = accesslog_db_destroy;
accesslog.on_bi.bi_db_open = accesslog_db_open;
accesslog.on_bi.bi_op_add = accesslog_op_mod; accesslog.on_bi.bi_op_add = accesslog_op_mod;
accesslog.on_bi.bi_op_bind = accesslog_op_bind; accesslog.on_bi.bi_op_bind = accesslog_op_bind;
@ -1292,8 +1387,10 @@ int accesslog_init()
} }
#if SLAPD_OVER_ACCESSLOG == SLAPD_MOD_DYNAMIC #if SLAPD_OVER_ACCESSLOG == SLAPD_MOD_DYNAMIC
int init_module( int argc, char *argv[]) { int
return accesslog_init(); init_module( int argc, char *argv[] )
{
return accesslog_initialize();
} }
#endif #endif

@ -215,7 +215,7 @@ auditlog_config(
return SLAP_CONF_UNKNOWN; return SLAP_CONF_UNKNOWN;
} }
int auditlog_init() { int auditlog_initialize() {
auditlog.on_bi.bi_type = "auditlog"; auditlog.on_bi.bi_type = "auditlog";
auditlog.on_bi.bi_db_init = auditlog_db_init; auditlog.on_bi.bi_db_init = auditlog_db_init;
@ -228,8 +228,10 @@ int auditlog_init() {
} }
#if SLAPD_OVER_AUDITLOG == SLAPD_MOD_DYNAMIC && defined(PIC) #if SLAPD_OVER_AUDITLOG == SLAPD_MOD_DYNAMIC && defined(PIC)
int init_module( int argc, char *argv[]) { int
return auditlog_init(); init_module( int argc, char *argv[] )
{
return auditlog_initialize();
} }
#endif #endif

@ -153,7 +153,7 @@ static int collect_config(
static slap_overinst collect; static slap_overinst collect;
int collect_init() { int collect_initialize() {
collect.on_bi.bi_type = "collect"; collect.on_bi.bi_type = "collect";
collect.on_bi.bi_db_config = collect_config; collect.on_bi.bi_db_config = collect_config;
collect.on_response = collect_response; collect.on_response = collect_response;
@ -163,7 +163,7 @@ int collect_init() {
#if SLAPD_OVER_COLLECT == SLAPD_MOD_DYNAMIC #if SLAPD_OVER_COLLECT == SLAPD_MOD_DYNAMIC
int init_module(int argc, char *argv[]) { int init_module(int argc, char *argv[]) {
return collect_init(); return collect_initialize();
} }
#endif #endif

@ -224,7 +224,7 @@ denyop_destroy(
static slap_overinst denyop; static slap_overinst denyop;
int int
denyop_init( void ) denyop_initialize( void )
{ {
memset( &denyop, 0, sizeof( slap_overinst ) ); memset( &denyop, 0, sizeof( slap_overinst ) );
denyop.on_bi.bi_type = "denyop"; denyop.on_bi.bi_type = "denyop";
@ -251,7 +251,7 @@ denyop_init( void )
int int
init_module( int argc, char *argv[] ) init_module( int argc, char *argv[] )
{ {
return denyop_init(); return denyop_initialize();
} }
#endif /* SLAPD_OVER_DENYOP == SLAPD_MOD_DYNAMIC */ #endif /* SLAPD_OVER_DENYOP == SLAPD_MOD_DYNAMIC */

@ -146,7 +146,7 @@ static slap_overinst dyngroup;
* initialized and registered by some other function inside slapd. * initialized and registered by some other function inside slapd.
*/ */
int dyngroup_init() { int dyngroup_initialize() {
dyngroup.on_bi.bi_type = "dyngroup"; dyngroup.on_bi.bi_type = "dyngroup";
dyngroup.on_bi.bi_db_config = dyngroup_config; dyngroup.on_bi.bi_db_config = dyngroup_config;
dyngroup.on_bi.bi_db_close = dyngroup_close; dyngroup.on_bi.bi_db_close = dyngroup_close;
@ -156,8 +156,10 @@ int dyngroup_init() {
} }
#if SLAPD_OVER_DYNGROUP == SLAPD_MOD_DYNAMIC #if SLAPD_OVER_DYNGROUP == SLAPD_MOD_DYNAMIC
int init_module(int argc, char *argv[]) { int
return dyngroup_init(); init_module( int argc, char *argv[] )
{
return dyngroup_initialize();
} }
#endif #endif

@ -588,7 +588,17 @@ dynlist_response( Operation *op, SlapReply *rs )
break; break;
case LDAP_REQ_COMPARE: case LDAP_REQ_COMPARE:
if ( rs->sr_err == LDAP_NO_SUCH_ATTRIBUTE ) { switch ( rs->sr_err ) {
/* NOTE: we waste a few cycles running the dynamic list
* also when the result is FALSE, which occurs if the
* dynamic entry itself contains the AVA attribute */
/* FIXME: this approach is less than optimal; a dedicated
* compare op should be implemented, that fetches the
* entry, checks if it has the appropriate objectClass
* and, in case, runs a compare thru all the URIs,
* stopping at the first positive occurrence; see ITS#3756 */
case LDAP_COMPARE_FALSE:
case LDAP_NO_SUCH_ATTRIBUTE:
return dynlist_compare( op, rs ); return dynlist_compare( op, rs );
} }
break; break;
@ -602,12 +612,11 @@ dynlist_response( Operation *op, SlapReply *rs )
static int static int
dynlist_db_config( dynlist_db_config(
BackendDB *be, BackendDB *be,
const char *fname, const char *fname,
int lineno, int lineno,
int argc, int argc,
char **argv char **argv )
)
{ {
slap_overinst *on = (slap_overinst *)be->bd_info; slap_overinst *on = (slap_overinst *)be->bd_info;
dynlist_info *dli = (dynlist_info *)on->on_bi.bi_private; dynlist_info *dli = (dynlist_info *)on->on_bi.bi_private;
@ -668,8 +677,7 @@ dynlist_db_config(
static int static int
dynlist_db_init( dynlist_db_init(
BackendDB *be BackendDB *be )
)
{ {
slap_overinst *on = (slap_overinst *) be->bd_info; slap_overinst *on = (slap_overinst *) be->bd_info;
dynlist_info *dli; dynlist_info *dli;
@ -684,8 +692,7 @@ dynlist_db_init(
static int static int
dynlist_db_open( dynlist_db_open(
BackendDB *be BackendDB *be )
)
{ {
slap_overinst *on = (slap_overinst *) be->bd_info; slap_overinst *on = (slap_overinst *) be->bd_info;
dynlist_info *dli = (dynlist_info *)on->on_bi.bi_private; dynlist_info *dli = (dynlist_info *)on->on_bi.bi_private;
@ -719,8 +726,7 @@ dynlist_db_open(
static int static int
dynlist_db_destroy( dynlist_db_destroy(
BackendDB *be BackendDB *be )
)
{ {
slap_overinst *on = (slap_overinst *) be->bd_info; slap_overinst *on = (slap_overinst *) be->bd_info;
int rc = 0; int rc = 0;
@ -739,8 +745,11 @@ dynlist_db_destroy(
static slap_overinst dynlist = { { NULL } }; static slap_overinst dynlist = { { NULL } };
#if SLAPD_OVER_DYNLIST == SLAPD_MOD_DYNAMIC
static
#endif /* SLAPD_OVER_DYNLIST == SLAPD_MOD_DYNAMIC */
int int
dynlist_init(void) dynlist_initialize(void)
{ {
dynlist.on_bi.bi_type = "dynlist"; dynlist.on_bi.bi_type = "dynlist";
dynlist.on_bi.bi_db_init = dynlist_db_init; dynlist.on_bi.bi_db_init = dynlist_db_init;
@ -757,7 +766,7 @@ dynlist_init(void)
int int
init_module( int argc, char *argv[] ) init_module( int argc, char *argv[] )
{ {
return dynlist_init(); return dynlist_initialize();
} }
#endif #endif

@ -995,7 +995,7 @@ lastmod_db_destroy(
static slap_overinst lastmod; static slap_overinst lastmod;
int int
lastmod_init() lastmod_initialize()
{ {
lastmod.on_bi.bi_type = "lastmod"; lastmod.on_bi.bi_type = "lastmod";
lastmod.on_bi.bi_db_init = lastmod_db_init; lastmod.on_bi.bi_db_init = lastmod_db_init;
@ -1020,7 +1020,7 @@ lastmod_init()
int int
init_module( int argc, char *argv[] ) init_module( int argc, char *argv[] )
{ {
return lastmod_init(); return lastmod_initialize();
} }
#endif /* SLAPD_OVER_LASTMOD == SLAPD_MOD_DYNAMIC */ #endif /* SLAPD_OVER_LASTMOD == SLAPD_MOD_DYNAMIC */

@ -23,116 +23,22 @@
#include "slap.h" #include "slap.h"
#if SLAPD_OVER_ACCESSLOG == SLAPD_MOD_STATIC extern OverlayInit slap_oinfo[];
extern int accesslog_init();
#endif
#if SLAPD_OVER_DENYOP == SLAPD_MOD_STATIC
extern int denyop_init();
#endif
#if SLAPD_OVER_DYNGROUP == SLAPD_MOD_STATIC
extern int dyngroup_init();
#endif
#if SLAPD_OVER_DYNLIST == SLAPD_MOD_STATIC
extern int dynlist_init();
#endif
#if SLAPD_OVER_GLUE == SLAPD_MOD_STATIC
extern int glue_init();
#endif
#if SLAPD_OVER_LASTMOD == SLAPD_MOD_STATIC
extern int lastmod_init();
#endif
#if SLAPD_OVER_PPOLICY == SLAPD_MOD_STATIC
extern int ppolicy_init();
#endif
#if SLAPD_OVER_PROXYCACHE == SLAPD_MOD_STATIC
extern int pcache_init();
#endif
#if SLAPD_OVER_REFINT == SLAPD_MOD_STATIC
extern int refint_init();
#endif
#if SLAPD_OVER_RETCODE == SLAPD_MOD_STATIC
extern int retcode_init();
#endif
#if SLAPD_OVER_RWM == SLAPD_MOD_STATIC
extern int rwm_init();
#endif
#if SLAPD_OVER_SYNCPROV == SLAPD_MOD_STATIC
extern int syncprov_init();
#endif
#if SLAPD_OVER_TRANSLUCENT == SLAPD_MOD_STATIC
extern int translucent_init();
#endif
#if SLAPD_OVER_UNIQUE == SLAPD_MOD_STATIC
extern int unique_init();
#endif
#if SLAPD_OVER_VALSORT == SLAPD_MOD_STATIC
extern int valsort_init();
#endif
static struct {
char *name;
int (*func)();
} funcs[] = {
#if SLAPD_OVER_ACCESSLOG == SLAPD_MOD_STATIC
{ "Access Log", accesslog_init },
#endif
#if SLAPD_OVER_DENYOP == SLAPD_MOD_STATIC
{ "Deny Operation", denyop_init },
#endif
#if SLAPD_OVER_DYNGROUP == SLAPD_MOD_STATIC
{ "Dynamic Group", dyngroup_init },
#endif
#if SLAPD_OVER_DYNLIST == SLAPD_MOD_STATIC
{ "Dynamic List", dynlist_init },
#endif
#if SLAPD_OVER_GLUE == SLAPD_MOD_STATIC
{ "Backend Glue", glue_init },
#endif
#if SLAPD_OVER_LASTMOD == SLAPD_MOD_STATIC
{ "Last Modification", lastmod_init },
#endif
#if SLAPD_OVER_PPOLICY == SLAPD_MOD_STATIC
{ "Password Policy", ppolicy_init },
#endif
#if SLAPD_OVER_PROXYCACHE == SLAPD_MOD_STATIC
{ "Proxy Cache", pcache_init },
#endif
#if SLAPD_OVER_REFINT == SLAPD_MOD_STATIC
{ "Referential Integrity", refint_init },
#endif
#if SLAPD_OVER_RETCODE == SLAPD_MOD_STATIC
{ "Return Code", retcode_init },
#endif
#if SLAPD_OVER_RWM == SLAPD_MOD_STATIC
{ "Rewrite/Remap", rwm_init },
#endif
#if SLAPD_OVER_SYNCPROV == SLAPD_MOD_STATIC
{ "Syncrepl Provider", syncprov_init },
#endif
#if SLAPD_OVER_TRANSLUCENT == SLAPD_MOD_STATIC
{ "Translucent Proxy", translucent_init },
#endif
#if SLAPD_OVER_UNIQUE == SLAPD_MOD_STATIC
{ "Attribute Uniqueness", unique_init },
#endif
#if SLAPD_OVER_VALSORT == SLAPD_MOD_STATIC
{ "Value Sorting", valsort_init },
#endif
{ NULL, NULL }
};
int int
overlay_init(void) overlay_init(void)
{ {
int i, rc = 0; int i, rc = 0;
for ( i=0; funcs[i].name; i++ ) { for ( i= 0 ; slap_oinfo[i].ov_type; i++ ) {
rc = funcs[i].func(); rc = slap_oinfo[i].ov_init();
if ( rc ) { if ( rc ) {
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"%s overlay setup failed, err %d\n", funcs[i].name, rc, 0 ); "%s overlay setup failed, err %d\n",
slap_oinfo[i].ov_type, rc, 0 );
break; break;
} }
} }
return rc; return rc;
} }

@ -68,7 +68,7 @@ typedef struct query_template_s {
CachedQuery* query_last; /* oldest query cached for the template */ CachedQuery* query_last; /* oldest query cached for the template */
int no_of_queries; /* Total number of queries in the template */ int no_of_queries; /* Total number of queries in the template */
long ttl; /* TTL for the queries of this template */ time_t ttl; /* TTL for the queries of this template */
ldap_pvt_thread_rdwr_t t_rwlock; /* Rd/wr lock for accessing queries in the template */ ldap_pvt_thread_rdwr_t t_rwlock; /* Rd/wr lock for accessing queries in the template */
} QueryTemplate; } QueryTemplate;
@ -78,6 +78,9 @@ typedef struct query_template_s {
*/ */
struct attr_set { struct attr_set {
unsigned flags;
#define PC_CONFIGURED (0x1)
#define PC_REFERENCED (0x2)
AttributeName* attrs; /* specifies the set */ AttributeName* attrs; /* specifies the set */
int count; /* number of attributes */ int count; /* number of attributes */
int* ID_array; /* array of indices of supersets of 'attrs' */ int* ID_array; /* array of indices of supersets of 'attrs' */
@ -124,7 +127,7 @@ typedef struct cache_manager_s {
#define PCACHE_RESPONSE_CB_HEAD 0 #define PCACHE_RESPONSE_CB_HEAD 0
#define PCACHE_RESPONSE_CB_TAIL 1 #define PCACHE_RESPONSE_CB_TAIL 1
int cc_period; /* interval between successive consistency checks (sec) */ time_t cc_period; /* interval between successive consistency checks (sec) */
int cc_paused; int cc_paused;
void *cc_arg; void *cc_arg;
@ -730,6 +733,7 @@ static void cache_replacement(query_manager* qm, struct berval *result)
Debug ( LDAP_DEBUG_ANY, Debug ( LDAP_DEBUG_ANY,
"Cache replacement invoked without " "Cache replacement invoked without "
"any query in LRU list\n", 0, 0, 0 ); "any query in LRU list\n", 0, 0, 0 );
ldap_pvt_thread_mutex_unlock(&qm->lru_mutex);
return; return;
} }
@ -1082,7 +1086,7 @@ cache_entries(
} }
static int static int
proxy_cache_response( pcache_response(
Operation *op, Operation *op,
SlapReply *rs ) SlapReply *rs )
{ {
@ -1117,13 +1121,16 @@ proxy_cache_response(
} }
} }
if (rs->sr_attrs != op->ors_attrs ) { if ( rs->sr_attrs != op->ors_attrs ) {
op->o_tmpfree( rs->sr_attrs, op->o_tmpmemctx ); op->o_tmpfree( rs->sr_attrs, op->o_tmpmemctx );
} }
rs->sr_attrs = si->query.save_attrs;
op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx ); if ( si->query.save_attrs != NULL ) {
op->ors_attrs = si->query.save_attrs; rs->sr_attrs = si->query.save_attrs;
si->query.save_attrs = NULL; op->o_tmpfree( op->ors_attrs, op->o_tmpmemctx );
op->ors_attrs = si->query.save_attrs;
si->query.save_attrs = NULL;
}
} else if ( rs->sr_type == REP_RESULT ) { } else if ( rs->sr_type == REP_RESULT ) {
if ( si->count && cache_entries( op, rs, &uuid ) == 0 ) { if ( si->count && cache_entries( op, rs, &uuid ) == 0 ) {
@ -1211,7 +1218,7 @@ add_filter_attrs(
* performing the pagedResults search only within the client * performing the pagedResults search only within the client
* and the proxy. This requires pcache to understand pagedResults. */ * and the proxy. This requires pcache to understand pagedResults. */
static int static int
proxy_cache_chk_controls( pcache_chk_controls(
Operation *op, Operation *op,
SlapReply *rs ) SlapReply *rs )
{ {
@ -1242,7 +1249,7 @@ proxy_cache_chk_controls(
} }
static int static int
proxy_cache_search( pcache_op_search(
Operation *op, Operation *op,
SlapReply *rs ) SlapReply *rs )
{ {
@ -1370,7 +1377,7 @@ proxy_cache_search(
add_filter_attrs(op, &op->ors_attrs, query.attrs, filter_attrs); add_filter_attrs(op, &op->ors_attrs, query.attrs, filter_attrs);
cb = op->o_tmpalloc( sizeof(*cb) + sizeof(*si), op->o_tmpmemctx); cb = op->o_tmpalloc( sizeof(*cb) + sizeof(*si), op->o_tmpmemctx);
cb->sc_response = proxy_cache_response; cb->sc_response = pcache_response;
cb->sc_cleanup = NULL; cb->sc_cleanup = NULL;
cb->sc_private = (cb+1); cb->sc_private = (cb+1);
si = cb->sc_private; si = cb->sc_private;
@ -1710,21 +1717,22 @@ pc_cfadd( Operation *op, SlapReply *rs, Entry *p, ConfigArgs *ca )
static int static int
pc_cf_gen( ConfigArgs *c ) pc_cf_gen( ConfigArgs *c )
{ {
slap_overinst *on = (slap_overinst *)c->bi; slap_overinst *on = (slap_overinst *)c->bi;
cache_manager* cm = on->on_bi.bi_private; cache_manager* cm = on->on_bi.bi_private;
query_manager* qm = cm->qm; query_manager* qm = cm->qm;
QueryTemplate* temp; QueryTemplate* temp;
AttributeName* attr_name; AttributeName* attr_name;
AttributeName* attrarray; AttributeName* attrarray;
const char* text=NULL; const char* text=NULL;
int i, num, rc = 0; int i, num, rc = 0;
char *ptr; char *ptr;
unsigned long t;
if ( c->op == SLAP_CONFIG_EMIT ) { if ( c->op == SLAP_CONFIG_EMIT ) {
struct berval bv; struct berval bv;
switch( c->type ) { switch( c->type ) {
case PC_MAIN: case PC_MAIN:
bv.bv_len = sprintf( c->msg, "%s %d %d %d %d", bv.bv_len = snprintf( c->msg, sizeof( c->msg ), "%s %d %d %d %ld",
cm->db.bd_info->bi_type, cm->max_entries, cm->numattrsets, cm->db.bd_info->bi_type, cm->max_entries, cm->numattrsets,
cm->num_entries_limit, cm->cc_period ); cm->num_entries_limit, cm->cc_period );
bv.bv_val = c->msg; bv.bv_val = c->msg;
@ -1734,7 +1742,7 @@ pc_cf_gen( ConfigArgs *c )
for (i=0; i<cm->numattrsets; i++) { for (i=0; i<cm->numattrsets; i++) {
if ( !qm->attr_sets[i].count ) continue; if ( !qm->attr_sets[i].count ) continue;
bv.bv_len = sprintf( c->msg, "%d", i ); bv.bv_len = snprintf( c->msg, sizeof( c->msg ), "%d", i );
/* count the attr length */ /* count the attr length */
for ( attr_name = qm->attr_sets[i].attrs; for ( attr_name = qm->attr_sets[i].attrs;
@ -1755,7 +1763,7 @@ pc_cf_gen( ConfigArgs *c )
break; break;
case PC_TEMP: case PC_TEMP:
for (i=0; i<cm->numtemplates; i++) { for (i=0; i<cm->numtemplates; i++) {
bv.bv_len = sprintf( c->msg, " %d %ld", bv.bv_len = snprintf( c->msg, sizeof( c->msg ), " %d %ld",
qm->templates[i].attr_set_index, qm->templates[i].attr_set_index,
qm->templates[i].ttl ); qm->templates[i].ttl );
bv.bv_len += qm->templates[i].querystr.bv_len + 2; bv.bv_len += qm->templates[i].querystr.bv_len + 2;
@ -1793,38 +1801,98 @@ pc_cf_gen( ConfigArgs *c )
switch( c->type ) { switch( c->type ) {
case PC_MAIN: case PC_MAIN:
cm->numattrsets = atoi( c->argv[3] ); if ( cm->numattrsets > 0 ) {
if ( cm->numattrsets > MAX_ATTR_SETS ) { snprintf( c->msg, sizeof( c->msg ), "\"proxycache\" directive already provided" );
sprintf( c->msg, "numattrsets must be <= %d", MAX_ATTR_SETS ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
Debug( LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
return( 1 ); return( 1 );
} }
if ( !backend_db_init( c->argv[1], &cm->db )) {
sprintf( c->msg, "unknown backend type" );
Debug( LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
return( 1 );
}
cm->max_entries = atoi( c->argv[2] );
cm->num_entries_limit = atoi( c->argv[4] ); if ( lutil_atoi( &cm->numattrsets, c->argv[3] ) != 0 ) {
cm->cc_period = atoi( c->argv[5] ); snprintf( c->msg, sizeof( c->msg ), "unable to parse num attrsets=\"%s\" (arg #3)",
Debug( LDAP_DEBUG_TRACE, c->argv[3] );
"Total # of attribute sets to be cached = %d\n", Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
cm->numattrsets, 0, 0 ); return( 1 );
qm->attr_sets = ( struct attr_set * )ch_malloc( cm->numattrsets *
sizeof( struct attr_set ));
for ( i = 0; i < cm->numattrsets; i++ ) {
qm->attr_sets[i].attrs = NULL;
} }
if ( cm->numattrsets <= 0 ) {
snprintf( c->msg, sizeof( c->msg ), "numattrsets (arg #3) must be positive" );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return( 1 );
}
if ( cm->numattrsets > MAX_ATTR_SETS ) {
snprintf( c->msg, sizeof( c->msg ), "numattrsets (arg #3) must be <= %d", MAX_ATTR_SETS );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return( 1 );
}
if ( !backend_db_init( c->argv[1], &cm->db )) {
snprintf( c->msg, sizeof( c->msg ), "unknown backend type (arg #1)" );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return( 1 );
}
if ( lutil_atoi( &cm->max_entries, c->argv[2] ) != 0 ) {
snprintf( c->msg, sizeof( c->msg ), "unable to parse max entries=\"%s\" (arg #2)",
c->argv[2] );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return( 1 );
}
if ( cm->max_entries <= 0 ) {
snprintf( c->msg, sizeof( c->msg ), "max entries (arg #2) must be positive.\n" );
Debug( LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 );
return( 1 );
}
if ( lutil_atoi( &cm->num_entries_limit, c->argv[4] ) != 0 ) {
snprintf( c->msg, sizeof( c->msg ), "unable to parse entry limit=\"%s\" (arg #4)",
c->argv[4] );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return( 1 );
}
if ( cm->num_entries_limit <= 0 ) {
snprintf( c->msg, sizeof( c->msg ), "entry limit (arg #4) must be positive" );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return( 1 );
}
if ( cm->num_entries_limit > cm->max_entries ) {
snprintf( c->msg, sizeof( c->msg ), "entry limit (arg #4) must be less than max entries %d (arg #2)", cm->max_entries );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return( 1 );
}
if ( lutil_parse_time( c->argv[5], &t ) != 0 ) {
snprintf( c->msg, sizeof( c->msg ), "unable to parse period=\"%s\" (arg #5)",
c->argv[5] );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return( 1 );
}
cm->cc_period = (time_t)t;
Debug( LDAP_DEBUG_TRACE,
"Total # of attribute sets to be cached = %d.\n",
cm->numattrsets, 0, 0 );
qm->attr_sets = ( struct attr_set * )ch_calloc( cm->numattrsets,
sizeof( struct attr_set ) );
break; break;
case PC_ATTR: case PC_ATTR:
num = atoi( c->argv[1] ); if ( cm->numattrsets == 0 ) {
if (num >= cm->numattrsets) { snprintf( c->msg, sizeof( c->msg ), "\"proxycache\" directive not provided yet" );
sprintf( c->msg, "attrset index out of bounds" ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
Debug( LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 ); return( 1 );
}
if ( lutil_atoi( &num, c->argv[1] ) != 0 ) {
snprintf( c->msg, sizeof( c->msg ), "unable to parse attrset #=\"%s\"",
c->argv[1] );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return( 1 );
}
if ( num < 0 || num >= cm->numattrsets ) {
snprintf( c->msg, sizeof( c->msg ), "attrset index %d out of bounds (must be %s%d)",
num, cm->numattrsets > 1 ? "0->" : "", cm->numattrsets - 1 );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return 1; return 1;
} }
if ( c->argv[2] && strcmp( c->argv[2], "*" ) ) { qm->attr_sets[num].flags |= PC_CONFIGURED;
if ( c->argc > 2 && strcmp( c->argv[2], "*" ) ) {
qm->attr_sets[num].count = c->argc - 2; qm->attr_sets[num].count = c->argc - 2;
qm->attr_sets[num].attrs = (AttributeName*)ch_malloc( qm->attr_sets[num].attrs = (AttributeName*)ch_malloc(
(c->argc-1) * sizeof( AttributeName )); (c->argc-1) * sizeof( AttributeName ));
@ -1833,9 +1901,10 @@ pc_cf_gen( ConfigArgs *c )
ber_str2bv( c->argv[i], 0, 1, &attr_name->an_name); ber_str2bv( c->argv[i], 0, 1, &attr_name->an_name);
attr_name->an_desc = NULL; attr_name->an_desc = NULL;
if ( slap_bv2ad( &attr_name->an_name, if ( slap_bv2ad( &attr_name->an_name,
&attr_name->an_desc, &text )) { &attr_name->an_desc, &text ) )
{
strcpy( c->msg, text ); strcpy( c->msg, text );
Debug( LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
ch_free( qm->attr_sets[num].attrs ); ch_free( qm->attr_sets[num].attrs );
qm->attr_sets[num].attrs = NULL; qm->attr_sets[num].attrs = NULL;
qm->attr_sets[num].count = 0; qm->attr_sets[num].count = 0;
@ -1849,9 +1918,22 @@ pc_cf_gen( ConfigArgs *c )
} }
break; break;
case PC_TEMP: case PC_TEMP:
if (( i = atoi( c->argv[2] )) >= cm->numattrsets ) { if ( cm->numattrsets == 0 ) {
sprintf( c->msg, "template index invalid" ); snprintf( c->msg, sizeof( c->msg ), "\"proxycache\" directive not provided yet" );
Debug( LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return( 1 );
}
if ( lutil_atoi( &i, c->argv[2] ) != 0 ) {
snprintf( c->msg, sizeof( c->msg ), "unable to parse template #=\"%s\"",
c->argv[2] );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return( 1 );
}
if ( i < 0 || i >= cm->numattrsets ) {
snprintf( c->msg, sizeof( c->msg ), "template index %d invalid (%s%d)",
i, cm->numattrsets > 1 ? "0->" : "", cm->numattrsets - 1 );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return 1; return 1;
} }
num = cm->numtemplates; num = cm->numtemplates;
@ -1862,7 +1944,14 @@ pc_cf_gen( ConfigArgs *c )
temp = qm->templates + num; temp = qm->templates + num;
ldap_pvt_thread_rdwr_init( &temp->t_rwlock ); ldap_pvt_thread_rdwr_init( &temp->t_rwlock );
temp->query = temp->query_last = NULL; temp->query = temp->query_last = NULL;
temp->ttl = atoi( c->argv[3] ); if ( lutil_parse_time( c->argv[3], &t ) != 0 ) {
snprintf( c->msg, sizeof( c->msg ), "unable to parse template ttl=\"%s\"",
c->argv[3] );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return( 1 );
}
temp->ttl = (time_t)t;
temp->no_of_queries = 0; temp->no_of_queries = 0;
ber_str2bv( c->argv[1], 0, 1, &temp->querystr ); ber_str2bv( c->argv[1], 0, 1, &temp->querystr );
@ -1870,6 +1959,7 @@ pc_cf_gen( ConfigArgs *c )
Debug( LDAP_DEBUG_TRACE, " query template: %s\n", Debug( LDAP_DEBUG_TRACE, " query template: %s\n",
temp->querystr.bv_val, 0, 0 ); temp->querystr.bv_val, 0, 0 );
temp->attr_set_index = i; temp->attr_set_index = i;
qm->attr_sets[i].flags |= PC_REFERENCED;
Debug( LDAP_DEBUG_TRACE, " attributes: \n", 0, 0, 0 ); Debug( LDAP_DEBUG_TRACE, " attributes: \n", 0, 0, 0 );
if ( ( attrarray = qm->attr_sets[i].attrs ) != NULL ) { if ( ( attrarray = qm->attr_sets[i].attrs ) != NULL ) {
for ( i=0; attrarray[i].an_name.bv_val; i++ ) for ( i=0; attrarray[i].an_name.bv_val; i++ )
@ -1888,8 +1978,8 @@ pc_cf_gen( ConfigArgs *c )
cm->response_cb = PCACHE_RESPONSE_CB_TAIL; cm->response_cb = PCACHE_RESPONSE_CB_TAIL;
} else { } else {
sprintf( c->msg, "unknown specifier" ); snprintf( c->msg, sizeof( c->msg ), "unknown specifier" );
Debug( LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->msg, 0 ); Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return 1; return 1;
} }
break; break;
@ -1898,7 +1988,7 @@ pc_cf_gen( ConfigArgs *c )
} }
static int static int
proxy_cache_config( pcache_db_config(
BackendDB *be, BackendDB *be,
const char *fname, const char *fname,
int lineno, int lineno,
@ -1917,7 +2007,7 @@ proxy_cache_config(
} }
static int static int
proxy_cache_init( pcache_db_init(
BackendDB *be BackendDB *be
) )
{ {
@ -1962,13 +2052,42 @@ proxy_cache_init(
} }
static int static int
proxy_cache_open( pcache_db_open(
BackendDB *be BackendDB *be
) )
{ {
slap_overinst *on = (slap_overinst *)be->bd_info; slap_overinst *on = (slap_overinst *)be->bd_info;
cache_manager *cm = on->on_bi.bi_private; cache_manager *cm = on->on_bi.bi_private;
int rc = 0; query_manager* qm = cm->qm;
int i, ncf = 0, rf = 0, nrf = 0, rc = 0;
/* check attr sets */
for ( i = 0; i < cm->numattrsets; i++) {
if ( !( qm->attr_sets[i].flags & PC_CONFIGURED ) ) {
if ( qm->attr_sets[i].flags & PC_REFERENCED ) {
Debug( LDAP_DEBUG_ANY, "pcache: attr set #%d not configured but referenced.\n", i, 0, 0 );
rf++;
} else {
Debug( LDAP_DEBUG_ANY, "pcache: warning, attr set #%d not configured.\n", i, 0, 0 );
}
ncf++;
} else if ( !( qm->attr_sets[i].flags & PC_REFERENCED ) ) {
Debug( LDAP_DEBUG_ANY, "pcache: attr set #%d configured but not referenced.\n", i, 0, 0 );
nrf++;
}
}
if ( ncf || rf || nrf ) {
Debug( LDAP_DEBUG_ANY, "pcache: warning, %d attr sets configured but not referenced.\n", nrf, 0, 0 );
Debug( LDAP_DEBUG_ANY, "pcache: warning, %d attr sets not configured.\n", ncf, 0, 0 );
Debug( LDAP_DEBUG_ANY, "pcache: %d attr sets not configured but referenced.\n", rf, 0, 0 );
if ( rf > 0 ) {
return 1;
}
}
/* need to inherit something from the original database... */ /* need to inherit something from the original database... */
cm->db.be_def_limit = be->be_def_limit; cm->db.be_def_limit = be->be_def_limit;
@ -1990,7 +2109,7 @@ proxy_cache_open(
if ( BER_BVISNULL( &cm->db.be_rootndn ) if ( BER_BVISNULL( &cm->db.be_rootndn )
|| BER_BVISEMPTY( &cm->db.be_rootndn ) ) || BER_BVISEMPTY( &cm->db.be_rootndn ) )
{ {
Debug( LDAP_DEBUG_ANY, "proxy_cache_open(): " Debug( LDAP_DEBUG_ANY, "pcache_db_open(): "
"underlying database of type \"%s\"\n" "underlying database of type \"%s\"\n"
" serving naming context \"%s\"\n" " serving naming context \"%s\"\n"
" has no \"rootdn\", required by \"proxycache\".\n", " has no \"rootdn\", required by \"proxycache\".\n",
@ -2004,7 +2123,7 @@ proxy_cache_open(
} }
static int static int
proxy_cache_close( pcache_db_close(
BackendDB *be BackendDB *be
) )
{ {
@ -2046,7 +2165,7 @@ proxy_cache_close(
} }
static int static int
proxy_cache_destroy( pcache_db_destroy(
BackendDB *be BackendDB *be
) )
{ {
@ -2062,7 +2181,9 @@ proxy_cache_destroy(
BER_BVZERO( &cm->db.be_rootpw ); BER_BVZERO( &cm->db.be_rootpw );
/* FIXME: there might be more... */ /* FIXME: there might be more... */
backend_destroy_one( &cm->db, 0 ); if ( cm->db.be_private != NULL ) {
backend_destroy_one( &cm->db, 0 );
}
ldap_pvt_thread_mutex_destroy( &qm->lru_mutex ); ldap_pvt_thread_mutex_destroy( &qm->lru_mutex );
ldap_pvt_thread_mutex_destroy( &cm->cache_mutex ); ldap_pvt_thread_mutex_destroy( &cm->cache_mutex );
@ -2073,9 +2194,9 @@ proxy_cache_destroy(
return 0; return 0;
} }
static slap_overinst proxy_cache; static slap_overinst pcache;
int pcache_init() int pcache_initialize()
{ {
LDAPAttributeType *at; LDAPAttributeType *at;
int code; int code;
@ -2085,7 +2206,7 @@ int pcache_init()
LDAP_SCHEMA_ALLOW_ALL ); LDAP_SCHEMA_ALLOW_ALL );
if ( !at ) { if ( !at ) {
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"pcache_init: ldap_str2attributetype failed %s %s\n", "pcache_initialize: ldap_str2attributetype failed %s %s\n",
ldap_scherr2str(code), err, 0 ); ldap_scherr2str(code), err, 0 );
return code; return code;
} }
@ -2096,32 +2217,33 @@ int pcache_init()
ldap_memfree( at ); ldap_memfree( at );
if ( code ) { if ( code ) {
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"pcache_init: at_add failed %s %s\n", "pcache_initialize: at_add failed %s %s\n",
scherr2str(code), err, 0 ); scherr2str(code), err, 0 );
return code; return code;
} }
proxy_cache.on_bi.bi_type = "pcache"; pcache.on_bi.bi_type = "pcache";
proxy_cache.on_bi.bi_db_init = proxy_cache_init; pcache.on_bi.bi_db_init = pcache_db_init;
proxy_cache.on_bi.bi_db_config = proxy_cache_config; pcache.on_bi.bi_db_config = pcache_db_config;
proxy_cache.on_bi.bi_db_open = proxy_cache_open; pcache.on_bi.bi_db_open = pcache_db_open;
proxy_cache.on_bi.bi_db_close = proxy_cache_close; pcache.on_bi.bi_db_close = pcache_db_close;
proxy_cache.on_bi.bi_db_destroy = proxy_cache_destroy; pcache.on_bi.bi_db_destroy = pcache_db_destroy;
proxy_cache.on_bi.bi_op_search = proxy_cache_search;
proxy_cache.on_bi.bi_chk_controls = proxy_cache_chk_controls; pcache.on_bi.bi_op_search = pcache_op_search;
proxy_cache.on_bi.bi_cf_ocs = pcocs; pcache.on_bi.bi_chk_controls = pcache_chk_controls;
pcache.on_bi.bi_cf_ocs = pcocs;
code = config_register_schema( pccfg, pcocs ); code = config_register_schema( pccfg, pcocs );
if ( code ) return code; if ( code ) return code;
return overlay_register( &proxy_cache ); return overlay_register( &pcache );
} }
#if SLAPD_OVER_PROXYCACHE == SLAPD_MOD_DYNAMIC #if SLAPD_OVER_PROXYCACHE == SLAPD_MOD_DYNAMIC
int init_module(int argc, char *argv[]) { int init_module(int argc, char *argv[]) {
return pcache_init(); return pcache_initialize();
} }
#endif #endif

@ -357,30 +357,40 @@ ppolicy_get( Operation *op, Entry *e, PassPolicy *pp )
pp->ad = slap_schema.si_ad_userPassword; pp->ad = slap_schema.si_ad_userPassword;
#endif #endif
if ((a = attr_find( pe->e_attrs, ad_pwdMinAge ))) if ( ( a = attr_find( pe->e_attrs, ad_pwdMinAge ) )
pp->pwdMinAge = atoi(a->a_vals[0].bv_val ); && lutil_atoi( &pp->pwdMinAge, a->a_vals[0].bv_val ) != 0 )
if ((a = attr_find( pe->e_attrs, ad_pwdMaxAge ))) goto defaultpol;
pp->pwdMaxAge = atoi(a->a_vals[0].bv_val ); if ( ( a = attr_find( pe->e_attrs, ad_pwdMaxAge ) )
if ((a = attr_find( pe->e_attrs, ad_pwdInHistory ))) && lutil_atoi( &pp->pwdMaxAge, a->a_vals[0].bv_val ) != 0 )
pp->pwdInHistory = atoi(a->a_vals[0].bv_val ); goto defaultpol;
if ((a = attr_find( pe->e_attrs, ad_pwdCheckQuality ))) if ( ( a = attr_find( pe->e_attrs, ad_pwdInHistory ) )
pp->pwdCheckQuality = atoi(a->a_vals[0].bv_val ); && lutil_atoi( &pp->pwdInHistory, a->a_vals[0].bv_val ) != 0 )
if ((a = attr_find( pe->e_attrs, ad_pwdMinLength ))) goto defaultpol;
pp->pwdMinLength = atoi(a->a_vals[0].bv_val ); if ( ( a = attr_find( pe->e_attrs, ad_pwdCheckQuality ) )
if ((a = attr_find( pe->e_attrs, ad_pwdMaxFailure ))) && lutil_atoi( &pp->pwdCheckQuality, a->a_vals[0].bv_val ) != 0 )
pp->pwdMaxFailure = atoi(a->a_vals[0].bv_val ); goto defaultpol;
if ((a = attr_find( pe->e_attrs, ad_pwdGraceAuthNLimit ))) if ( ( a = attr_find( pe->e_attrs, ad_pwdMinLength ) )
pp->pwdGraceAuthNLimit = atoi(a->a_vals[0].bv_val ); && lutil_atoi( &pp->pwdMinLength, a->a_vals[0].bv_val ) != 0 )
if ((a = attr_find( pe->e_attrs, ad_pwdExpireWarning ))) goto defaultpol;
pp->pwdExpireWarning = atoi(a->a_vals[0].bv_val ); if ( ( a = attr_find( pe->e_attrs, ad_pwdMaxFailure ) )
if ((a = attr_find( pe->e_attrs, ad_pwdFailureCountInterval ))) && lutil_atoi( &pp->pwdMaxFailure, a->a_vals[0].bv_val ) != 0 )
pp->pwdFailureCountInterval = atoi(a->a_vals[0].bv_val ); goto defaultpol;
if ((a = attr_find( pe->e_attrs, ad_pwdLockoutDuration ))) if ( ( a = attr_find( pe->e_attrs, ad_pwdGraceAuthNLimit ) )
pp->pwdLockoutDuration = atoi(a->a_vals[0].bv_val ); && lutil_atoi( &pp->pwdGraceAuthNLimit, a->a_vals[0].bv_val ) != 0 )
goto defaultpol;
if ( ( a = attr_find( pe->e_attrs, ad_pwdExpireWarning ) )
&& lutil_atoi( &pp->pwdExpireWarning, a->a_vals[0].bv_val ) != 0 )
goto defaultpol;
if ( ( a = attr_find( pe->e_attrs, ad_pwdFailureCountInterval ) )
&& lutil_atoi( &pp->pwdFailureCountInterval, a->a_vals[0].bv_val ) != 0 )
goto defaultpol;
if ( ( a = attr_find( pe->e_attrs, ad_pwdLockoutDuration ) )
&& lutil_atoi( &pp->pwdLockoutDuration, a->a_vals[0].bv_val ) != 0 )
goto defaultpol;
if ((a = attr_find( pe->e_attrs, ad_pwdCheckModule ))) { if ( ( a = attr_find( pe->e_attrs, ad_pwdCheckModule ) ) ) {
strncpy(pp->pwdCheckModule, a->a_vals[0].bv_val, strncpy( pp->pwdCheckModule, a->a_vals[0].bv_val,
sizeof(pp->pwdCheckModule)); sizeof(pp->pwdCheckModule) );
pp->pwdCheckModule[sizeof(pp->pwdCheckModule)-1] = '\0'; pp->pwdCheckModule[sizeof(pp->pwdCheckModule)-1] = '\0';
} }
@ -1932,7 +1942,7 @@ static char *extops[] = {
static slap_overinst ppolicy; static slap_overinst ppolicy;
int ppolicy_init() int ppolicy_initialize()
{ {
LDAPAttributeType *at; LDAPAttributeType *at;
const char *err; const char *err;
@ -1992,7 +2002,7 @@ int ppolicy_init()
#if SLAPD_OVER_PPOLICY == SLAPD_MOD_DYNAMIC #if SLAPD_OVER_PPOLICY == SLAPD_MOD_DYNAMIC
int init_module(int argc, char *argv[]) { int init_module(int argc, char *argv[]) {
return ppolicy_init(); return ppolicy_initialize();
} }
#endif #endif

@ -659,7 +659,7 @@ done:
** it expects to be called automagically during dynamic module initialization ** it expects to be called automagically during dynamic module initialization
*/ */
int refint_init() { int refint_initialize() {
/* statically declared just after the #includes at top */ /* statically declared just after the #includes at top */
refint.on_bi.bi_type = "refint"; refint.on_bi.bi_type = "refint";
@ -674,7 +674,7 @@ int refint_init() {
#if SLAPD_OVER_REFINT == SLAPD_MOD_DYNAMIC && defined(PIC) #if SLAPD_OVER_REFINT == SLAPD_MOD_DYNAMIC && defined(PIC)
int init_module(int argc, char *argv[]) { int init_module(int argc, char *argv[]) {
return refint_init(); return refint_initialize();
} }
#endif #endif

@ -114,8 +114,6 @@ retcode_send_onelevel( Operation *op, SlapReply *rs )
retcode_item_t *rdi; retcode_item_t *rdi;
for ( rdi = rd->rd_item; rdi != NULL; rdi = rdi->rdi_next ) { for ( rdi = rd->rd_item; rdi != NULL; rdi = rdi->rdi_next ) {
int rc;
if ( op->o_abandon ) { if ( op->o_abandon ) {
return rs->sr_err = SLAPD_ABANDON; return rs->sr_err = SLAPD_ABANDON;
} }
@ -135,16 +133,14 @@ retcode_send_onelevel( Operation *op, SlapReply *rs )
rs->sr_err = LDAP_SUCCESS; rs->sr_err = LDAP_SUCCESS;
rs->sr_entry = &rdi->rdi_e; rs->sr_entry = &rdi->rdi_e;
rc = send_search_entry( op, rs ); rs->sr_err = send_search_entry( op, rs );
rs->sr_entry = NULL;
switch ( rc ) { switch ( rs->sr_err ) {
case 0: /* entry sent ok */ case LDAP_UNAVAILABLE: /* connection closed */
break;
case 1: /* entry not sent */
break;
case -1: /* connection closed */
rs->sr_entry = NULL;
rs->sr_err = LDAP_OTHER; rs->sr_err = LDAP_OTHER;
/* fallthru */
case LDAP_SIZELIMIT_EXCEEDED:
goto done; goto done;
} }
} }
@ -1062,7 +1058,7 @@ retcode_db_destroy( BackendDB *be )
static static
#endif /* SLAPD_OVER_RETCODE == SLAPD_MOD_DYNAMIC */ #endif /* SLAPD_OVER_RETCODE == SLAPD_MOD_DYNAMIC */
int int
retcode_init( void ) retcode_initialize( void )
{ {
int i, code; int i, code;
const char *err; const char *err;
@ -1239,7 +1235,7 @@ retcode_init( void )
int int
init_module( int argc, char *argv[] ) init_module( int argc, char *argv[] )
{ {
return retcode_init(); return retcode_initialize();
} }
#endif /* SLAPD_OVER_RETCODE == SLAPD_MOD_DYNAMIC */ #endif /* SLAPD_OVER_RETCODE == SLAPD_MOD_DYNAMIC */

@ -1504,7 +1504,7 @@ rwm_db_destroy(
static slap_overinst rwm = { { NULL } }; static slap_overinst rwm = { { NULL } };
int int
rwm_init(void) rwm_initialize(void)
{ {
memset( &rwm, 0, sizeof( slap_overinst ) ); memset( &rwm, 0, sizeof( slap_overinst ) );
@ -1541,7 +1541,7 @@ rwm_init(void)
int int
init_module( int argc, char *argv[] ) init_module( int argc, char *argv[] )
{ {
return rwm_init(); return rwm_initialize();
} }
#endif /* SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC */ #endif /* SLAPD_OVER_RWM == SLAPD_MOD_DYNAMIC */

@ -178,7 +178,7 @@ seqmod_db_close(
static slap_overinst seqmod; static slap_overinst seqmod;
int int
seqmod_init() seqmod_initialize()
{ {
seqmod.on_bi.bi_type = "seqmod"; seqmod.on_bi.bi_type = "seqmod";
seqmod.on_bi.bi_db_open = seqmod_db_open; seqmod.on_bi.bi_db_open = seqmod_db_open;
@ -195,7 +195,7 @@ seqmod_init()
int int
init_module( int argc, char *argv[] ) init_module( int argc, char *argv[] )
{ {
return seqmod_init(); return seqmod_initialize();
} }
#endif /* SLAPD_OVER_SEQMOD == SLAPD_MOD_DYNAMIC */ #endif /* SLAPD_OVER_SEQMOD == SLAPD_MOD_DYNAMIC */

@ -450,12 +450,10 @@ syncprov_findbase( Operation *op, fbase_cookie *fc )
case LDAP_SCOPE_SUBTREE: case LDAP_SCOPE_SUBTREE:
fc->fscope = dnIsSuffix( fc->fdn, &fc->fss->s_base ); fc->fscope = dnIsSuffix( fc->fdn, &fc->fss->s_base );
break; break;
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE: case LDAP_SCOPE_SUBORDINATE:
fc->fscope = dnIsSuffix( fc->fdn, &fc->fss->s_base ) && fc->fscope = dnIsSuffix( fc->fdn, &fc->fss->s_base ) &&
!dn_match( fc->fdn, &fc->fss->s_base ); !dn_match( fc->fdn, &fc->fss->s_base );
break; break;
#endif
} }
} }
@ -510,7 +508,11 @@ findcsn_cb( Operation *op, SlapReply *rs )
{ {
slap_callback *sc = op->o_callback; slap_callback *sc = op->o_callback;
if ( rs->sr_type == REP_SEARCH && rs->sr_err == LDAP_SUCCESS ) { /* We just want to know that at least one exists, so it's OK if
* we exceed the unchecked limit.
*/
if ( rs->sr_err == LDAP_ADMINLIMIT_EXCEEDED ||
(rs->sr_type == REP_SEARCH && rs->sr_err == LDAP_SUCCESS )) {
sc->sc_private = (void *)1; sc->sc_private = (void *)1;
} }
return LDAP_SUCCESS; return LDAP_SUCCESS;
@ -583,10 +585,10 @@ syncprov_findcsn( Operation *op, find_csn_t mode )
#else #else
AttributeAssertion eq = { NULL, BER_BVNULL }; AttributeAssertion eq = { NULL, BER_BVNULL };
#endif #endif
int i, rc = LDAP_SUCCESS;
fpres_cookie pcookie; fpres_cookie pcookie;
sync_control *srs = NULL; sync_control *srs = NULL;
int findcsn_retry = 1; struct slap_limits_set fc_limits;
int i, rc = LDAP_SUCCESS, findcsn_retry = 1;
if ( mode != FIND_MAXCSN ) { if ( mode != FIND_MAXCSN ) {
srs = op->o_controls[slap_cids.sc_LDAPsync]; srs = op->o_controls[slap_cids.sc_LDAPsync];
@ -637,6 +639,8 @@ again:
/* On retry, look for <= */ /* On retry, look for <= */
} else { } else {
cf.f_choice = LDAP_FILTER_LE; cf.f_choice = LDAP_FILTER_LE;
fop.ors_limit = &fc_limits;
fc_limits.lms_s_unchecked = 1;
fop.ors_filterstr.bv_len = sprintf( buf, "(entryCSN<=%s)", fop.ors_filterstr.bv_len = sprintf( buf, "(entryCSN<=%s)",
cf.f_av_value.bv_val ); cf.f_av_value.bv_val );
} }
@ -1244,7 +1248,9 @@ syncprov_checkpoint( Operation *op, SlapReply *rs, slap_overinst *on )
opm.o_req_ndn = op->o_bd->be_nsuffix[0]; opm.o_req_ndn = op->o_bd->be_nsuffix[0];
opm.o_bd->bd_info = on->on_info->oi_orig; opm.o_bd->bd_info = on->on_info->oi_orig;
opm.o_managedsait = SLAP_CONTROL_NONCRITICAL; opm.o_managedsait = SLAP_CONTROL_NONCRITICAL;
SLAP_DBFLAGS( opm.o_bd ) |= SLAP_DBFLAG_NOLASTMOD;
opm.o_bd->be_modify( &opm, &rsm ); opm.o_bd->be_modify( &opm, &rsm );
SLAP_DBFLAGS( opm.o_bd ) ^= SLAP_DBFLAG_NOLASTMOD;
if ( mod.sml_next != NULL ) { if ( mod.sml_next != NULL ) {
slap_mods_free( mod.sml_next, 1 ); slap_mods_free( mod.sml_next, 1 );
} }
@ -2187,8 +2193,31 @@ sp_cf_gen(ConfigArgs *c)
} }
switch ( c->type ) { switch ( c->type ) {
case SP_CHKPT: case SP_CHKPT:
si->si_chkops = atoi( c->argv[1] ); if ( lutil_atoi( &si->si_chkops, c->argv[1] ) != 0 ) {
si->si_chktime = atoi( c->argv[2] ) * 60; sprintf( c->msg, "%s unable to parse checkpoint ops # \"%s\"",
c->argv[0], c->argv[1] );
Debug( LDAP_DEBUG_CONFIG, "%s: %s\n", c->log, c->msg, 0 );
return ARG_BAD_CONF;
}
if ( si->si_chkops <= 0 ) {
sprintf( c->msg, "%s invalid checkpoint ops # \"%d\"",
c->argv[0], si->si_chkops );
Debug( LDAP_DEBUG_CONFIG, "%s: %s\n", c->log, c->msg, 0 );
return ARG_BAD_CONF;
}
if ( lutil_atoi( &si->si_chktime, c->argv[2] ) != 0 ) {
sprintf( c->msg, "%s unable to parse checkpoint time \"%s\"",
c->argv[0], c->argv[1] );
Debug( LDAP_DEBUG_CONFIG, "%s: %s\n", c->log, c->msg, 0 );
return ARG_BAD_CONF;
}
if ( si->si_chktime <= 0 ) {
sprintf( c->msg, "%s invalid checkpoint time \"%d\"",
c->argv[0], si->si_chkops );
Debug( LDAP_DEBUG_CONFIG, "%s: %s\n", c->log, c->msg, 0 );
return ARG_BAD_CONF;
}
si->si_chktime *= 60;
break; break;
case SP_SESSL: { case SP_SESSL: {
sessionlog *sl; sessionlog *sl;
@ -2508,7 +2537,7 @@ static int syncprov_parseCtrl (
static slap_overinst syncprov; static slap_overinst syncprov;
int int
syncprov_init() syncprov_initialize()
{ {
int rc; int rc;
@ -2553,7 +2582,7 @@ syncprov_init()
int int
init_module( int argc, char *argv[] ) init_module( int argc, char *argv[] )
{ {
return syncprov_init(); return syncprov_initialize();
} }
#endif /* SLAPD_OVER_SYNCPROV == SLAPD_MOD_DYNAMIC */ #endif /* SLAPD_OVER_SYNCPROV == SLAPD_MOD_DYNAMIC */

@ -29,6 +29,7 @@
#include <ac/socket.h> #include <ac/socket.h>
#include "slap.h" #include "slap.h"
#include "lutil.h"
/* config block */ /* config block */
@ -620,7 +621,11 @@ static int translucent_config(
ov->config->debug = 0xFFFF; ov->config->debug = 0xFFFF;
rc = 0; rc = 0;
} else if(argc == 2) { } else if(argc == 2) {
ov->config->debug = atoi(argv[1]); if ( lutil_atoi( &ov->config->debug, argv[1]) != 0 ) {
fprintf(stderr, "%s: line %d: unable to parse debug \"%s\"\n",
fname, lineno, argv[1]);
return 1;
}
rc = 0; rc = 0;
} else { } else {
fprintf(stderr, "%s: line %d: too many arguments (%d) to debug\n", fprintf(stderr, "%s: line %d: too many arguments (%d) to debug\n",
@ -730,7 +735,7 @@ static int translucent_close(BackendDB *be) {
** **
*/ */
int translucent_init() { int translucent_initialize() {
translucent.on_bi.bi_type = "translucent"; translucent.on_bi.bi_type = "translucent";
translucent.on_bi.bi_db_init = translucent_db_init; translucent.on_bi.bi_db_init = translucent_db_init;
@ -750,7 +755,7 @@ int translucent_init() {
#if SLAPD_OVER_TRANSLUCENT == SLAPD_MOD_DYNAMIC && defined(PIC) #if SLAPD_OVER_TRANSLUCENT == SLAPD_MOD_DYNAMIC && defined(PIC)
int init_module(int argc, char *argv[]) { int init_module(int argc, char *argv[]) {
return translucent_init(); return translucent_initialize();
} }
#endif #endif

@ -263,21 +263,35 @@ static int count_filter_len(
unique_attrs *up; unique_attrs *up;
int i; int i;
while(!is_at_operational(ad->ad_type)) { while ( !is_at_operational( ad->ad_type ) ) {
if(ud->ignore) { if ( ud->ignore ) {
for(up = ud->ignore; up; up = up->next) for ( up = ud->ignore; up; up = up->next ) {
if(ad == up->attr) break; if (ad == up->attr ) {
if(up) break; break;
}
}
if ( up ) {
break;
}
} }
if(ud->attrs) { if ( ud->attrs ) {
for(up = ud->attrs; up; up = up->next) for ( up = ud->attrs; up; up = up->next ) {
if(ad == up->attr) break; if ( ad == up->attr ) {
if(!up) break; break;
}
}
if ( !up ) {
break;
}
} }
if(b && b[0].bv_val) for(i = 0; b[i].bv_val; i++) if ( b && b[0].bv_val ) {
ks += b[i].bv_len + ad->ad_cname.bv_len + STRLENOF( "(=)" ); for (i = 0; b[i].bv_val; i++ ) {
else if(ud->strict) /* note: make room for filter escaping... */
ks += ( 3 * b[i].bv_len ) + ad->ad_cname.bv_len + STRLENOF( "(=)" );
}
} else if ( ud->strict ) {
ks += ad->ad_cname.bv_len + STRLENOF( "(=*)" ); /* (attr=*) */ ks += ad->ad_cname.bv_len + STRLENOF( "(=*)" ); /* (attr=*) */
}
break; break;
} }
return ks; return ks;
@ -287,27 +301,47 @@ static char *build_filter(
unique_data *ud, unique_data *ud,
AttributeDescription *ad, AttributeDescription *ad,
BerVarray b, BerVarray b,
char *kp char *kp,
void *ctx
) )
{ {
unique_attrs *up; unique_attrs *up;
int i; int i;
while(!is_at_operational(ad->ad_type)) { while ( !is_at_operational( ad->ad_type ) ) {
if(ud->ignore) { if ( ud->ignore ) {
for(up = ud->ignore; up; up = up->next) for ( up = ud->ignore; up; up = up->next ) {
if(ad == up->attr) break; if ( ad == up->attr ) {
if(up) break; break;
}
}
if ( up ) {
break;
}
} }
if(ud->attrs) { if ( ud->attrs ) {
for(up = ud->attrs; up; up = up->next) for ( up = ud->attrs; up; up = up->next ) {
if(ad == up->attr) break; if ( ad == up->attr ) {
if(!up) break; break;
}
}
if ( !up ) {
break;
}
}
if ( b && b[0].bv_val ) {
for ( i = 0; b[i].bv_val; i++ ) {
struct berval bv;
ldap_bv2escaped_filter_value_x( &b[i], &bv, 1, ctx );
kp += sprintf( kp, "(%s=%s)", ad->ad_cname.bv_val, bv.bv_val );
if ( bv.bv_val != b[i].bv_val ) {
ber_memfree_x( bv.bv_val, ctx );
}
}
} else if ( ud->strict ) {
kp += sprintf( kp, "(%s=*)", ad->ad_cname.bv_val );
} }
if(b && b[0].bv_val) for(i = 0; b[i].bv_val; i++)
kp += sprintf(kp, "(%s=%s)", ad->ad_cname.bv_val, b[i].bv_val);
else if(ud->strict)
kp += sprintf(kp, "(%s=*)", ad->ad_cname.bv_val);
break; break;
} }
return kp; return kp;
@ -409,7 +443,7 @@ static int unique_add(
kp = key + sprintf(key, "(|"); kp = key + sprintf(key, "(|");
for(a = op->ora_e->e_attrs; a; a = a->a_next) { for(a = op->ora_e->e_attrs; a; a = a->a_next) {
kp = build_filter(ud, a->a_desc, a->a_vals, kp); kp = build_filter(ud, a->a_desc, a->a_vals, kp, op->o_tmpmemctx);
} }
sprintf(kp, ")"); sprintf(kp, ")");
@ -461,7 +495,7 @@ static int unique_modify(
for(m = op->orm_modlist; m; m = m->sml_next) { for(m = op->orm_modlist; m; m = m->sml_next) {
if ((m->sml_op & LDAP_MOD_OP) == LDAP_MOD_DELETE) continue; if ((m->sml_op & LDAP_MOD_OP) == LDAP_MOD_DELETE) continue;
kp = build_filter(ud, m->sml_desc, m->sml_values, kp); kp = build_filter(ud, m->sml_desc, m->sml_values, kp, op->o_tmpmemctx);
} }
sprintf(kp, ")"); sprintf(kp, ")");
@ -524,7 +558,7 @@ static int unique_modrdn(
for(i = 0; newrdn[i]; i++) { for(i = 0; newrdn[i]; i++) {
bv[0] = newrdn[i]->la_value; bv[0] = newrdn[i]->la_value;
kp = build_filter(ud, newrdn[i]->la_private, bv, kp); kp = build_filter(ud, newrdn[i]->la_private, bv, kp, op->o_tmpmemctx);
} }
sprintf(kp, ")"); sprintf(kp, ")");
@ -539,7 +573,7 @@ static int unique_modrdn(
** it expects to be called automagically during dynamic module initialization ** it expects to be called automagically during dynamic module initialization
*/ */
int unique_init() { int unique_initialize() {
/* statically declared just after the #includes at top */ /* statically declared just after the #includes at top */
unique.on_bi.bi_type = "unique"; unique.on_bi.bi_type = "unique";
@ -557,7 +591,7 @@ int unique_init() {
#if SLAPD_OVER_UNIQUE == SLAPD_MOD_DYNAMIC && defined(PIC) #if SLAPD_OVER_UNIQUE == SLAPD_MOD_DYNAMIC && defined(PIC)
int init_module(int argc, char *argv[]) { int init_module(int argc, char *argv[]) {
return unique_init(); return unique_initialize();
} }
#endif #endif

@ -531,7 +531,7 @@ valsort_parseCtrl(
static slap_overinst valsort; static slap_overinst valsort;
int valsort_init() int valsort_initialize( void )
{ {
int rc; int rc;
@ -564,7 +564,7 @@ int valsort_init()
#if SLAPD_OVER_VALSORT == SLAPD_MOD_DYNAMIC #if SLAPD_OVER_VALSORT == SLAPD_MOD_DYNAMIC
int init_module( int argc, char *argv[]) { int init_module( int argc, char *argv[]) {
return valsort_init(); return valsort_initialize();
} }
#endif #endif

@ -913,8 +913,8 @@ LDAP_SLAPD_F (void) vrFilter_free LDAP_P(( Operation *op, ValuesReturnFilter *f
LDAP_SLAPD_F (void) vrFilter2bv LDAP_P(( Operation *op, ValuesReturnFilter *f, struct berval *fstr )); LDAP_SLAPD_F (void) vrFilter2bv LDAP_P(( Operation *op, ValuesReturnFilter *f, struct berval *fstr ));
LDAP_SLAPD_F (int) filter_has_subordinates LDAP_P(( Filter *filter )); LDAP_SLAPD_F (int) filter_has_subordinates LDAP_P(( Filter *filter ));
LDAP_SLAPD_F (int) filter_escape_value LDAP_P(( struct berval *in, #define filter_escape_value( in, out ) ldap_bv2escaped_filter_value_x( (in), (out), 0, NULL )
struct berval *out )); #define filter_escape_value_x( in, out, ctx ) ldap_bv2escaped_filter_value_x( (in), (out), 0, ctx )
/* /*
* filterentry.c * filterentry.c

@ -36,6 +36,7 @@
#include <ac/unistd.h> #include <ac/unistd.h>
#include "slap.h" #include "slap.h"
#include "lutil.h"
const struct berval slap_dummy_bv = BER_BVNULL; const struct berval slap_dummy_bv = BER_BVNULL;
@ -556,11 +557,8 @@ slap_send_ldap_result( Operation *op, SlapReply *rs )
assert( rs->sr_err != LDAP_PARTIAL_RESULTS ); assert( rs->sr_err != LDAP_PARTIAL_RESULTS );
if ( rs->sr_err == LDAP_REFERRAL ) { if ( rs->sr_err == LDAP_REFERRAL ) {
#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE if( op->o_domain_scope ) rs->sr_ref = NULL;
if( op->o_domain_scope ) {
rs->sr_ref = NULL;
}
#endif
if( rs->sr_ref == NULL ) { if( rs->sr_ref == NULL ) {
rs->sr_err = LDAP_NO_SUCH_OBJECT; rs->sr_err = LDAP_NO_SUCH_OBJECT;
} else if ( op->o_protocol < LDAP_VERSION3 ) { } else if ( op->o_protocol < LDAP_VERSION3 ) {
@ -661,13 +659,23 @@ slap_send_ldap_intermediate( Operation *op, SlapReply *rs )
} }
} }
/*
* returns:
*
* LDAP_SUCCESS entry sent
* LDAP_OTHER entry not sent (other)
* LDAP_INSUFFICIENT_ACCESS entry not sent (ACL)
* LDAP_UNAVAILABLE entry not sent (connection closed)
* LDAP_SIZELIMIT_EXCEEDED entry not sent (caller must send sizelimitExceeded)
*/
int int
slap_send_search_entry( Operation *op, SlapReply *rs ) slap_send_search_entry( Operation *op, SlapReply *rs )
{ {
BerElementBuffer berbuf; BerElementBuffer berbuf;
BerElement *ber = (BerElement *) &berbuf; BerElement *ber = (BerElement *) &berbuf;
Attribute *a; Attribute *a;
int i, j, rc=-1, bytes; int i, j, rc = LDAP_UNAVAILABLE, bytes;
char *edn; char *edn;
int userattrs; int userattrs;
AccessControlState acl_state = ACL_STATE_INIT; AccessControlState acl_state = ACL_STATE_INIT;
@ -679,7 +687,11 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
* e_flags: array of a_flags * e_flags: array of a_flags
*/ */
char **e_flags = NULL; char **e_flags = NULL;
if ( op->ors_slimit >= 0 && rs->sr_nentries >= op->ors_slimit ) {
return LDAP_SIZELIMIT_EXCEEDED;
}
rs->sr_type = REP_SEARCH; rs->sr_type = REP_SEARCH;
/* eventually will loop through generated operational attribute types /* eventually will loop through generated operational attribute types
@ -730,7 +742,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
"send_search_entry: conn %lu access to entry (%s) not allowed\n", "send_search_entry: conn %lu access to entry (%s) not allowed\n",
op->o_connid, rs->sr_entry->e_name.bv_val, 0 ); op->o_connid, rs->sr_entry->e_name.bv_val, 0 );
rc = 1; rc = LDAP_INSUFFICIENT_ACCESS;
goto error_return; goto error_return;
} }
@ -776,6 +788,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
if ( op->o_res_ber == NULL ) ber_free_buf( ber ); if ( op->o_res_ber == NULL ) ber_free_buf( ber );
send_ldap_error( op, rs, LDAP_OTHER, "encoding DN error" ); send_ldap_error( op, rs, LDAP_OTHER, "encoding DN error" );
rc = rs->sr_err;
goto error_return; goto error_return;
} }
@ -823,6 +836,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
if ( op->o_res_ber == NULL ) ber_free_buf( ber ); if ( op->o_res_ber == NULL ) ber_free_buf( ber );
send_ldap_error( op, rs, LDAP_OTHER, send_ldap_error( op, rs, LDAP_OTHER,
"matched values filtering error" ); "matched values filtering error" );
rc = rs->sr_err;
goto error_return; goto error_return;
} }
} }
@ -872,6 +886,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
if ( op->o_res_ber == NULL ) ber_free_buf( ber ); if ( op->o_res_ber == NULL ) ber_free_buf( ber );
send_ldap_error( op, rs, LDAP_OTHER, send_ldap_error( op, rs, LDAP_OTHER,
"encoding description error"); "encoding description error");
rc = rs->sr_err;
goto error_return; goto error_return;
} }
finish = 1; finish = 1;
@ -905,6 +920,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
if ( op->o_res_ber == NULL ) ber_free_buf( ber ); if ( op->o_res_ber == NULL ) ber_free_buf( ber );
send_ldap_error( op, rs, LDAP_OTHER, send_ldap_error( op, rs, LDAP_OTHER,
"encoding description error"); "encoding description error");
rc = rs->sr_err;
goto error_return; goto error_return;
} }
} }
@ -916,6 +932,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
if ( op->o_res_ber == NULL ) ber_free_buf( ber ); if ( op->o_res_ber == NULL ) ber_free_buf( ber );
send_ldap_error( op, rs, LDAP_OTHER, send_ldap_error( op, rs, LDAP_OTHER,
"encoding values error" ); "encoding values error" );
rc = rs->sr_err;
goto error_return; goto error_return;
} }
} }
@ -928,6 +945,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
if ( op->o_res_ber == NULL ) ber_free_buf( ber ); if ( op->o_res_ber == NULL ) ber_free_buf( ber );
send_ldap_error( op, rs, LDAP_OTHER, "encode end error" ); send_ldap_error( op, rs, LDAP_OTHER, "encode end error" );
rc = rs->sr_err;
goto error_return; goto error_return;
} }
} }
@ -981,6 +999,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
if ( op->o_res_ber == NULL ) ber_free_buf( ber ); if ( op->o_res_ber == NULL ) ber_free_buf( ber );
send_ldap_error( op, rs, LDAP_OTHER, send_ldap_error( op, rs, LDAP_OTHER,
"matched values filtering error" ); "matched values filtering error" );
rc = rs->sr_err;
goto error_return; goto error_return;
} }
} }
@ -1030,6 +1049,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
if ( op->o_res_ber == NULL ) ber_free_buf( ber ); if ( op->o_res_ber == NULL ) ber_free_buf( ber );
send_ldap_error( op, rs, LDAP_OTHER, send_ldap_error( op, rs, LDAP_OTHER,
"encoding description error" ); "encoding description error" );
rc = rs->sr_err;
goto error_return; goto error_return;
} }
@ -1058,6 +1078,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
if ( op->o_res_ber == NULL ) ber_free_buf( ber ); if ( op->o_res_ber == NULL ) ber_free_buf( ber );
send_ldap_error( op, rs, LDAP_OTHER, send_ldap_error( op, rs, LDAP_OTHER,
"encoding values error" ); "encoding values error" );
rc = rs->sr_err;
goto error_return; goto error_return;
} }
} }
@ -1070,6 +1091,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
if ( op->o_res_ber == NULL ) ber_free_buf( ber ); if ( op->o_res_ber == NULL ) ber_free_buf( ber );
send_ldap_error( op, rs, LDAP_OTHER, "encode end error" ); send_ldap_error( op, rs, LDAP_OTHER, "encode end error" );
rc = rs->sr_err;
goto error_return; goto error_return;
} }
} }
@ -1104,7 +1126,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
if ( op->o_res_ber == NULL ) ber_free_buf( ber ); if ( op->o_res_ber == NULL ) ber_free_buf( ber );
send_ldap_error( op, rs, LDAP_OTHER, "encode entry end error" ); send_ldap_error( op, rs, LDAP_OTHER, "encode entry end error" );
rc = 1; rc = rs->sr_err;
goto error_return; goto error_return;
} }
@ -1123,7 +1145,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
"send_search_entry: conn %lu ber write failed.\n", "send_search_entry: conn %lu ber write failed.\n",
op->o_connid, 0, 0 ); op->o_connid, 0, 0 );
rc = -1; rc = LDAP_UNAVAILABLE;
goto error_return; goto error_return;
} }
rs->sr_nentries++; rs->sr_nentries++;
@ -1141,7 +1163,7 @@ slap_send_search_entry( Operation *op, SlapReply *rs )
Debug( LDAP_DEBUG_TRACE, Debug( LDAP_DEBUG_TRACE,
"<= send_search_entry: conn %lu exit.\n", op->o_connid, 0, 0 ); "<= send_search_entry: conn %lu exit.\n", op->o_connid, 0, 0 );
rc = 0; rc = LDAP_SUCCESS;
error_return:; error_return:;
if ( op->o_callback ) { if ( op->o_callback ) {
@ -1246,7 +1268,6 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
goto rel; goto rel;
} }
#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
if( op->o_domain_scope ) { if( op->o_domain_scope ) {
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
"send_search_reference: domainScope control in (%s)\n", "send_search_reference: domainScope control in (%s)\n",
@ -1254,7 +1275,6 @@ slap_send_search_reference( Operation *op, SlapReply *rs )
rc = 0; rc = 0;
goto rel; goto rel;
} }
#endif
if( rs->sr_ref == NULL ) { if( rs->sr_ref == NULL ) {
Debug( LDAP_DEBUG_ANY, Debug( LDAP_DEBUG_ANY,
@ -1397,8 +1417,8 @@ str2result(
} }
if ( strncasecmp( s, "code", STRLENOF( "code" ) ) == 0 ) { if ( strncasecmp( s, "code", STRLENOF( "code" ) ) == 0 ) {
if ( c != NULL ) { if ( c != NULL && lutil_atoi( code, c ) != 0 ) {
*code = atoi( c ); goto bailout;
} }
} else if ( strncasecmp( s, "matched", STRLENOF( "matched" ) ) == 0 ) { } else if ( strncasecmp( s, "matched", STRLENOF( "matched" ) ) == 0 ) {
if ( c != NULL ) { if ( c != NULL ) {
@ -1409,6 +1429,7 @@ str2result(
*info = c; *info = c;
} }
} else { } else {
bailout:;
Debug( LDAP_DEBUG_ANY, "str2result (%s) unknown\n", Debug( LDAP_DEBUG_ANY, "str2result (%s) unknown\n",
s, 0, 0 ); s, 0, 0 );

@ -150,10 +150,10 @@ static const char *slap_propnames[] = {
static Filter generic_filter = { LDAP_FILTER_PRESENT, { 0 }, NULL }; static Filter generic_filter = { LDAP_FILTER_PRESENT, { 0 }, NULL };
static struct berval generic_filterstr = BER_BVC("(objectclass=*)"); static struct berval generic_filterstr = BER_BVC("(objectclass=*)");
#define PROP_CONN 0 #define SLAP_SASL_PROP_CONN 0
#define PROP_AUTHC 1 #define SLAP_SASL_PROP_AUTHC 1
#define PROP_AUTHZ 2 #define SLAP_SASL_PROP_AUTHZ 2
#define PROP_COUNT 3 /* Number of properties we used */ #define SLAP_SASL_PROP_COUNT 3 /* Number of properties we used */
typedef struct lookup_info { typedef struct lookup_info {
int flags; int flags;
@ -185,7 +185,7 @@ sasl_ap_lookup( Operation *op, SlapReply *rs )
if ( sl->flags & SASL_AUXPROP_AUTHZID ) continue; if ( sl->flags & SASL_AUXPROP_AUTHZID ) continue;
/* Skip our private properties */ /* Skip our private properties */
if ( !strcmp( name, slap_propnames[0] )) { if ( !strcmp( name, slap_propnames[0] )) {
i += PROP_COUNT-1; i += SLAP_SASL_PROP_COUNT - 1;
continue; continue;
} }
name++; name++;
@ -275,19 +275,19 @@ slap_auxprop_lookup(
/* Find our DN and conn first */ /* Find our DN and conn first */
for( i = 0; sl.list[i].name; i++ ) { for( i = 0; sl.list[i].name; i++ ) {
if ( sl.list[i].name[0] == '*' ) { if ( sl.list[i].name[0] == '*' ) {
if ( !strcmp( sl.list[i].name, slap_propnames[PROP_CONN] ) ) { if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_CONN] ) ) {
if ( sl.list[i].values && sl.list[i].values[0] ) if ( sl.list[i].values && sl.list[i].values[0] )
AC_MEMCPY( &conn, sl.list[i].values[0], sizeof( conn ) ); AC_MEMCPY( &conn, sl.list[i].values[0], sizeof( conn ) );
continue; continue;
} }
if ( (flags & SASL_AUXPROP_AUTHZID) && if ( (flags & SASL_AUXPROP_AUTHZID) &&
!strcmp( sl.list[i].name, slap_propnames[PROP_AUTHZ] ) ) { !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHZ] ) ) {
if ( sl.list[i].values && sl.list[i].values[0] ) if ( sl.list[i].values && sl.list[i].values[0] )
AC_MEMCPY( &op.o_req_ndn, sl.list[i].values[0], sizeof( struct berval ) ); AC_MEMCPY( &op.o_req_ndn, sl.list[i].values[0], sizeof( struct berval ) );
break; break;
} }
if ( !strcmp( sl.list[i].name, slap_propnames[PROP_AUTHC] ) ) { if ( !strcmp( sl.list[i].name, slap_propnames[SLAP_SASL_PROP_AUTHC] ) ) {
if ( sl.list[i].values && sl.list[i].values[0] ) { if ( sl.list[i].values && sl.list[i].values[0] ) {
AC_MEMCPY( &op.o_req_ndn, sl.list[i].values[0], sizeof( struct berval ) ); AC_MEMCPY( &op.o_req_ndn, sl.list[i].values[0], sizeof( struct berval ) );
if ( !(flags & SASL_AUXPROP_AUTHZID) ) if ( !(flags & SASL_AUXPROP_AUTHZID) )
@ -305,7 +305,7 @@ slap_auxprop_lookup(
if ( flags & SASL_AUXPROP_AUTHZID ) continue; if ( flags & SASL_AUXPROP_AUTHZID ) continue;
/* Skip our private properties */ /* Skip our private properties */
if ( !strcmp( name, slap_propnames[0] )) { if ( !strcmp( name, slap_propnames[0] )) {
i += PROP_COUNT-1; i += SLAP_SASL_PROP_COUNT - 1;
continue; continue;
} }
name++; name++;
@ -423,12 +423,12 @@ slap_auxprop_store(
/* Find our DN and conn first */ /* Find our DN and conn first */
for( i = 0; pr[i].name; i++ ) { for( i = 0; pr[i].name; i++ ) {
if ( pr[i].name[0] == '*' ) { if ( pr[i].name[0] == '*' ) {
if ( !strcmp( pr[i].name, slap_propnames[PROP_CONN] ) ) { if ( !strcmp( pr[i].name, slap_propnames[SLAP_SASL_PROP_CONN] ) ) {
if ( pr[i].values && pr[i].values[0] ) if ( pr[i].values && pr[i].values[0] )
AC_MEMCPY( &conn, pr[i].values[0], sizeof( conn ) ); AC_MEMCPY( &conn, pr[i].values[0], sizeof( conn ) );
continue; continue;
} }
if ( !strcmp( pr[i].name, slap_propnames[PROP_AUTHC] ) ) { if ( !strcmp( pr[i].name, slap_propnames[SLAP_SASL_PROP_AUTHC] ) ) {
if ( pr[i].values && pr[i].values[0] ) { if ( pr[i].values && pr[i].values[0] ) {
AC_MEMCPY( &op.o_req_ndn, pr[i].values[0], sizeof( struct berval ) ); AC_MEMCPY( &op.o_req_ndn, pr[i].values[0], sizeof( struct berval ) );
} }
@ -542,7 +542,7 @@ slap_sasl_canonicalize(
{ {
Connection *conn = (Connection *)context; Connection *conn = (Connection *)context;
struct propctx *props = sasl_auxprop_getctx( sconn ); struct propctx *props = sasl_auxprop_getctx( sconn );
struct propval auxvals[3]; struct propval auxvals[ SLAP_SASL_PROP_COUNT ] = { { 0 } };
struct berval dn; struct berval dn;
int rc, which; int rc, which;
const char *names[2]; const char *names[2];
@ -575,13 +575,13 @@ slap_sasl_canonicalize(
prop_request( props, slap_propnames ); prop_request( props, slap_propnames );
if ( flags & SASL_CU_AUTHID ) if ( flags & SASL_CU_AUTHID )
which = PROP_AUTHC; which = SLAP_SASL_PROP_AUTHC;
else else
which = PROP_AUTHZ; which = SLAP_SASL_PROP_AUTHZ;
/* Need to store the Connection for auxprop_lookup */ /* Need to store the Connection for auxprop_lookup */
if ( !auxvals[PROP_CONN].values ) { if ( !auxvals[SLAP_SASL_PROP_CONN].values ) {
names[0] = slap_propnames[PROP_CONN]; names[0] = slap_propnames[SLAP_SASL_PROP_CONN];
names[1] = NULL; names[1] = NULL;
prop_set( props, names[0], (char *)&conn, sizeof( conn ) ); prop_set( props, names[0], (char *)&conn, sizeof( conn ) );
} }
@ -605,7 +605,7 @@ slap_sasl_canonicalize(
* it does authzID before the authcID. If we see that authzID * it does authzID before the authcID. If we see that authzID
* has already been done, don't do anything special with authcID. * has already been done, don't do anything special with authcID.
*/ */
if ( flags == SASL_CU_AUTHID && !auxvals[PROP_AUTHZ].values ) { if ( flags == SASL_CU_AUTHID && !auxvals[SLAP_SASL_PROP_AUTHZ].values ) {
conn->c_sasl_dn.bv_val = (char *) in; conn->c_sasl_dn.bv_val = (char *) in;
} else if ( flags == SASL_CU_AUTHZID && conn->c_sasl_dn.bv_val ) { } else if ( flags == SASL_CU_AUTHZID && conn->c_sasl_dn.bv_val ) {
rc = strcmp( in, conn->c_sasl_dn.bv_val ); rc = strcmp( in, conn->c_sasl_dn.bv_val );
@ -654,7 +654,11 @@ slap_sasl_authorize(
struct propctx *props) struct propctx *props)
{ {
Connection *conn = (Connection *)context; Connection *conn = (Connection *)context;
struct propval auxvals[3]; /* actually:
* (SLAP_SASL_PROP_COUNT - 1) because we skip "conn",
* + 1 for NULL termination?
*/
struct propval auxvals[ SLAP_SASL_PROP_COUNT ] = { { 0 } };
struct berval authcDN, authzDN = BER_BVNULL; struct berval authcDN, authzDN = BER_BVNULL;
int rc; int rc;
@ -670,7 +674,7 @@ slap_sasl_authorize(
BER_BVZERO( &conn->c_sasl_dn ); BER_BVZERO( &conn->c_sasl_dn );
} }
/* Skip PROP_CONN */ /* Skip SLAP_SASL_PROP_CONN */
prop_getnames( props, slap_propnames+1, auxvals ); prop_getnames( props, slap_propnames+1, auxvals );
/* Should not happen */ /* Should not happen */

@ -1969,9 +1969,7 @@ slap_sasl2dn(
case LDAP_SCOPE_BASE: case LDAP_SCOPE_BASE:
case LDAP_SCOPE_ONELEVEL: case LDAP_SCOPE_ONELEVEL:
case LDAP_SCOPE_SUBTREE: case LDAP_SCOPE_SUBTREE:
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE: case LDAP_SCOPE_SUBORDINATE:
#endif
/* do a search */ /* do a search */
break; break;

@ -1207,6 +1207,7 @@ slap_schema_load( void )
code = at_add( at, 0, NULL, &err ); code = at_add( at, 0, NULL, &err );
if ( code ) { if ( code ) {
ldap_attributetype_free( at );
fprintf( stderr, "slap_schema_load: AttributeType " fprintf( stderr, "slap_schema_load: AttributeType "
"\"%s\": %s: \"%s\"\n", "\"%s\": %s: \"%s\"\n",
ad_map[i].ssam_name, scherr2str(code), err ); ad_map[i].ssam_name, scherr2str(code), err );

@ -280,6 +280,7 @@ parse_at(
code = at_add(at,1,sat,&err); code = at_add(at,1,sat,&err);
if ( code ) { if ( code ) {
ldap_attributetype_free( at );
fprintf( stderr, "%s: line %d: %s: \"%s\"\n", fprintf( stderr, "%s: line %d: %s: \"%s\"\n",
fname, lineno, scherr2str(code), err); fname, lineno, scherr2str(code), err);
return 1; return 1;

@ -92,9 +92,7 @@ do_search(
case LDAP_SCOPE_BASE: case LDAP_SCOPE_BASE:
case LDAP_SCOPE_ONELEVEL: case LDAP_SCOPE_ONELEVEL:
case LDAP_SCOPE_SUBTREE: case LDAP_SCOPE_SUBTREE:
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE: case LDAP_SCOPE_SUBORDINATE:
#endif
break; break;
default: default:
send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid scope" ); send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR, "invalid scope" );
@ -283,9 +281,17 @@ fe_op_search( Operation *op, SlapReply *rs )
rs->sr_err = test_filter( op, entry, op->ors_filter ); rs->sr_err = test_filter( op, entry, op->ors_filter );
if( rs->sr_err == LDAP_COMPARE_TRUE ) { if( rs->sr_err == LDAP_COMPARE_TRUE ) {
/* note: we set no limits because either
* no limit is specified, or at least 1
* is specified, and we're going to return
* at most one entry */
op->ors_slimit = SLAP_NO_LIMIT;
op->ors_tlimit = SLAP_NO_LIMIT;
rs->sr_entry = entry; rs->sr_entry = entry;
rs->sr_attrs = op->ors_attrs; rs->sr_attrs = op->ors_attrs;
rs->sr_operational_attrs = NULL; rs->sr_operational_attrs = NULL;
rs->sr_flags = 0;
send_search_entry( op, rs ); send_search_entry( op, rs );
rs->sr_entry = NULL; rs->sr_entry = NULL;
rs->sr_operational_attrs = NULL; rs->sr_operational_attrs = NULL;

@ -185,21 +185,32 @@ parse_input( FILE *ifp, FILE *ofp, struct ldop *op )
op->ldop_dn = estrdup( args ); op->ldop_dn = estrdup( args );
break; break;
case IP_TYPE_SCOPE: case IP_TYPE_SCOPE:
if (( op->ldop_srch.ldsp_scope = atoi( args )) != LDAP_SCOPE_BASE && if ( lutil_atoi( &op->ldop_srch.ldsp_scope, args ) != 0 ||
( op->ldop_srch.ldsp_scope != LDAP_SCOPE_BASE &&
op->ldop_srch.ldsp_scope != LDAP_SCOPE_ONELEVEL && op->ldop_srch.ldsp_scope != LDAP_SCOPE_ONELEVEL &&
op->ldop_srch.ldsp_scope != LDAP_SCOPE_SUBTREE ) { op->ldop_srch.ldsp_scope != LDAP_SCOPE_SUBTREE ) )
{
write_result( ofp, LDAP_OTHER, NULL, "Bad scope" ); write_result( ofp, LDAP_OTHER, NULL, "Bad scope" );
return( -1 ); return( -1 );
} }
break; break;
case IP_TYPE_ALIASDEREF: case IP_TYPE_ALIASDEREF:
op->ldop_srch.ldsp_aliasderef = atoi( args ); if ( lutil_atoi( &op->ldop_srch.ldsp_aliasderef, args ) != 0 ) {
write_result( ofp, LDAP_OTHER, NULL, "Bad alias deref" );
return( -1 );
}
break; break;
case IP_TYPE_SIZELIMIT: case IP_TYPE_SIZELIMIT:
op->ldop_srch.ldsp_sizelimit = atoi( args ); if ( lutil_atoi( &op->ldop_srch.ldsp_sizelimit, args ) != 0 ) {
write_result( ofp, LDAP_OTHER, NULL, "Bad size limit" );
return( -1 );
}
break; break;
case IP_TYPE_TIMELIMIT: case IP_TYPE_TIMELIMIT:
op->ldop_srch.ldsp_timelimit = atoi( args ); if ( lutil_atoi( &op->ldop_srch.ldsp_timelimit, args ) != 0 ) {
write_result( ofp, LDAP_OTHER, NULL, "Bad time limit" );
return( -1 );
}
break; break;
case IP_TYPE_FILTER: case IP_TYPE_FILTER:
op->ldop_srch.ldsp_filter = estrdup( args ); op->ldop_srch.ldsp_filter = estrdup( args );

@ -74,8 +74,8 @@ LDAP_BEGIN_DECL
#define LDAP_DYNAMIC_OBJECTS #define LDAP_DYNAMIC_OBJECTS
#define LDAP_SYNC_TIMESTAMP #define LDAP_SYNC_TIMESTAMP
#define LDAP_COLLECTIVE_ATTRIBUTES #define LDAP_COLLECTIVE_ATTRIBUTES
#define SLAP_CONTROL_X_TREE_DELETE LDAP_CONTROL_X_TREE_DELETE
#define SLAPD_CONF_UNKNOWN_BAILOUT #define SLAPD_CONF_UNKNOWN_BAILOUT
#define SLAP_CONTROL_X_TREE_DELETE LDAP_CONTROL_X_TREE_DELETE
#define SLAP_ORDERED_PRETTYNORM #define SLAP_ORDERED_PRETTYNORM
#define SLAP_AUTHZ_SYNTAX #define SLAP_AUTHZ_SYNTAX
@ -1005,9 +1005,7 @@ typedef struct slap_filter {
#define SLAPD_FILTER_COMPUTED ((ber_tag_t) -1) #define SLAPD_FILTER_COMPUTED ((ber_tag_t) -1)
#define SLAPD_FILTER_DN_ONE ((ber_tag_t) -2) #define SLAPD_FILTER_DN_ONE ((ber_tag_t) -2)
#define SLAPD_FILTER_DN_SUBTREE ((ber_tag_t) -3) #define SLAPD_FILTER_DN_SUBTREE ((ber_tag_t) -3)
#ifdef LDAP_SCOPE_SUBORDINATE
#define SLAPD_FILTER_DN_CHILDREN ((ber_tag_t) -4) #define SLAPD_FILTER_DN_CHILDREN ((ber_tag_t) -4)
#endif
union f_un_u { union f_un_u {
/* precomputed result */ /* precomputed result */
@ -1846,21 +1844,23 @@ struct slap_conn;
struct slap_op; struct slap_op;
/* Backend function typedefs */ /* Backend function typedefs */
typedef int (BI_init) LDAP_P((BackendInfo *bi)); typedef int (BI_bi_func) LDAP_P((BackendInfo *bi));
typedef BI_bi_func BI_init;
typedef BI_bi_func BI_open;
typedef BI_bi_func BI_close;
typedef BI_bi_func BI_destroy;
typedef int (BI_config) LDAP_P((BackendInfo *bi, typedef int (BI_config) LDAP_P((BackendInfo *bi,
const char *fname, int lineno, const char *fname, int lineno,
int argc, char **argv)); int argc, char **argv));
typedef int (BI_open) LDAP_P((BackendInfo *bi));
typedef int (BI_close) LDAP_P((BackendInfo *bi));
typedef int (BI_destroy) LDAP_P((BackendInfo *bi));
typedef int (BI_db_init) LDAP_P((Backend *bd)); typedef int (BI_db_func) LDAP_P((Backend *bd));
typedef BI_db_func BI_db_init;
typedef BI_db_func BI_db_open;
typedef BI_db_func BI_db_close;
typedef BI_db_func BI_db_destroy;
typedef int (BI_db_config) LDAP_P((Backend *bd, typedef int (BI_db_config) LDAP_P((Backend *bd,
const char *fname, int lineno, const char *fname, int lineno,
int argc, char **argv)); int argc, char **argv));
typedef int (BI_db_open) LDAP_P((Backend *bd));
typedef int (BI_db_close) LDAP_P((Backend *bd));
typedef int (BI_db_destroy) LDAP_P((Backend *bd));
typedef struct req_bind_s { typedef struct req_bind_s {
int rb_method; int rb_method;
@ -2001,22 +2001,20 @@ typedef struct slap_rep {
#define sr_rspdata sr_un.sru_extended.r_rspdata #define sr_rspdata sr_un.sru_extended.r_rspdata
#define sr_sasldata sr_un.sru_sasl.r_sasldata #define sr_sasldata sr_un.sru_sasl.r_sasldata
typedef int (BI_op_bind) LDAP_P(( struct slap_op *op, struct slap_rep *rs )); typedef int (BI_op_func) LDAP_P(( struct slap_op *op, struct slap_rep *rs ));
typedef int (BI_op_unbind) LDAP_P(( struct slap_op *op, struct slap_rep *rs )); typedef BI_op_func BI_op_bind;
typedef int (BI_op_search) LDAP_P(( struct slap_op *op, struct slap_rep *rs )); typedef BI_op_func BI_op_unbind;
typedef int (BI_op_compare) LDAP_P(( struct slap_op *op, struct slap_rep *rs )); typedef BI_op_func BI_op_search;
typedef int (BI_op_modify) LDAP_P(( struct slap_op *op, struct slap_rep *rs )); typedef BI_op_func BI_op_compare;
typedef int (BI_op_modrdn) LDAP_P(( struct slap_op *op, struct slap_rep *rs )); typedef BI_op_func BI_op_modify;
typedef int (BI_op_add) LDAP_P(( struct slap_op *op, struct slap_rep *rs )); typedef BI_op_func BI_op_modrdn;
typedef int (BI_op_delete) LDAP_P(( struct slap_op *op, struct slap_rep *rs )); typedef BI_op_func BI_op_add;
typedef int (BI_op_abandon) LDAP_P(( struct slap_op *op, struct slap_rep *rs )); typedef BI_op_func BI_op_delete;
typedef int (BI_op_cancel) LDAP_P(( struct slap_op *op, struct slap_rep *rs )); typedef BI_op_func BI_op_abandon;
typedef int (BI_op_extended) LDAP_P(( typedef BI_op_func BI_op_cancel;
struct slap_op *op, struct slap_rep *rs )); typedef BI_op_func BI_op_extended;
typedef int (BI_chk_referrals) LDAP_P(( typedef BI_op_func BI_chk_referrals;
struct slap_op *op, struct slap_rep *rs )); typedef BI_op_func BI_chk_controls;
typedef int (BI_chk_controls) LDAP_P((
struct slap_op *op, struct slap_rep *rs ));
typedef int (BI_entry_release_rw) typedef int (BI_entry_release_rw)
LDAP_P(( struct slap_op *op, Entry *e, int rw )); LDAP_P(( struct slap_op *op, Entry *e, int rw ));
typedef int (BI_entry_get_rw) LDAP_P(( struct slap_op *op, struct berval *ndn, typedef int (BI_entry_get_rw) LDAP_P(( struct slap_op *op, struct berval *ndn,
@ -2036,10 +2034,9 @@ typedef int (BI_acl_attribute) LDAP_P(( struct slap_op *op, Entry *target,
BerVarray *vals, slap_access_t access )); BerVarray *vals, slap_access_t access ));
#endif /* SLAP_OVERLAY_ACCESS */ #endif /* SLAP_OVERLAY_ACCESS */
typedef int (BI_connection_init) LDAP_P(( BackendDB *bd, typedef int (BI_conn_func) LDAP_P(( BackendDB *bd, struct slap_conn *c ));
struct slap_conn *c )); typedef BI_conn_func BI_connection_init;
typedef int (BI_connection_destroy) LDAP_P(( BackendDB *bd, typedef BI_conn_func BI_connection_destroy;
struct slap_conn *c ));
typedef int (BI_tool_entry_open) LDAP_P(( BackendDB *be, int mode )); typedef int (BI_tool_entry_open) LDAP_P(( BackendDB *be, int mode ));
typedef int (BI_tool_entry_close) LDAP_P(( BackendDB *be )); typedef int (BI_tool_entry_close) LDAP_P(( BackendDB *be ));
@ -2253,8 +2250,8 @@ typedef struct slap_overinfo {
} slap_overinfo; } slap_overinfo;
/* Should successive callbacks in a chain be processed? */ /* Should successive callbacks in a chain be processed? */
#define SLAP_CB_FREEME 0x4000 #define SLAP_CB_FREEME 0x04000
#define SLAP_CB_CONTINUE 0x8000 #define SLAP_CB_CONTINUE 0x08000
/* /*
* Paged Results state * Paged Results state
@ -2291,25 +2288,26 @@ typedef struct slap_gacl {
} GroupAssertion; } GroupAssertion;
struct slap_control_ids { struct slap_control_ids {
int sc_LDAPsync;
int sc_assert; int sc_assert;
int sc_preRead; int sc_domainScope;
int sc_postRead; int sc_dontUseCopy;
int sc_proxyAuthz;
int sc_manageDIT; int sc_manageDIT;
int sc_manageDSAit; int sc_manageDSAit;
int sc_modifyIncrement; int sc_modifyIncrement;
int sc_noOp; int sc_noOp;
int sc_pagedResults; int sc_pagedResults;
int sc_permissiveModify;
int sc_postRead;
int sc_preRead;
int sc_proxyAuthz;
int sc_searchOptions;
#ifdef LDAP_DEVEL #ifdef LDAP_DEVEL
int sc_sortedResults; int sc_sortedResults;
#endif #endif
int sc_valuesReturnFilter;
int sc_permissiveModify;
int sc_domainScope;
int sc_treeDelete;
int sc_searchOptions;
int sc_subentries; int sc_subentries;
int sc_LDAPsync; int sc_treeDelete;
int sc_valuesReturnFilter;
}; };
/* /*
@ -2457,6 +2455,9 @@ typedef struct slap_op {
char o_ctrlflag[SLAP_MAX_CIDS]; /* per-control flags */ char o_ctrlflag[SLAP_MAX_CIDS]; /* per-control flags */
void **o_controls; /* per-control state */ void **o_controls; /* per-control state */
#define o_dontUseCopy o_ctrlflag[slap_cids.sc_dontUseCopy]
#define get_dontUseCopy(op) _SCM((op)->o_dontUseCopy)
#define o_managedit o_ctrlflag[slap_cids.sc_manageDIT] #define o_managedit o_ctrlflag[slap_cids.sc_manageDIT]
#define get_manageDIT(op) _SCM((op)->o_managedit) #define get_manageDIT(op) _SCM((op)->o_managedit)
@ -2481,26 +2482,14 @@ typedef struct slap_op {
#define o_valuesreturnfilter o_ctrlflag[slap_cids.sc_valuesReturnFilter] #define o_valuesreturnfilter o_ctrlflag[slap_cids.sc_valuesReturnFilter]
#define o_vrFilter o_controls[slap_cids.sc_valuesReturnFilter] #define o_vrFilter o_controls[slap_cids.sc_valuesReturnFilter]
#ifdef LDAP_CONTROL_X_PERMISSIVE_MODIFY
#define o_permissive_modify o_ctrlflag[slap_cids.sc_permissiveModify] #define o_permissive_modify o_ctrlflag[slap_cids.sc_permissiveModify]
#define get_permissiveModify(op) ((int)(op)->o_permissive_modify) #define get_permissiveModify(op) ((int)(op)->o_permissive_modify)
#else
#define get_permissiveModify(op) (0)
#endif
#ifdef LDAP_CONTROL_X_DOMAIN_SCOPE
#define o_domain_scope o_ctrlflag[slap_cids.sc_domainScope] #define o_domain_scope o_ctrlflag[slap_cids.sc_domainScope]
#define get_domainScope(op) ((int)(op)->o_domain_scope) #define get_domainScope(op) ((int)(op)->o_domain_scope)
#else
#define get_domainScope(op) (0)
#endif
#ifdef SLAP_CONTROL_X_TREE_DELETE
#define o_tree_delete o_ctrlflag[slap_cids.sc_treeDelete] #define o_tree_delete o_ctrlflag[slap_cids.sc_treeDelete]
#define get_treeDelete(op) ((int)(op)->o_tree_delete) #define get_treeDelete(op) ((int)(op)->o_tree_delete)
#else
#define get_treeDelete(op) (0)
#endif
#define o_preread o_ctrlflag[slap_cids.sc_preRead] #define o_preread o_ctrlflag[slap_cids.sc_preRead]
#define o_postread o_ctrlflag[slap_cids.sc_postRead] #define o_postread o_ctrlflag[slap_cids.sc_postRead]
@ -2670,10 +2659,7 @@ typedef struct slap_conn {
SEND_SEARCH_ENTRY *c_send_search_entry; SEND_SEARCH_ENTRY *c_send_search_entry;
SEND_SEARCH_REFERENCE *c_send_search_reference; SEND_SEARCH_REFERENCE *c_send_search_reference;
SEND_LDAP_EXTENDED *c_send_ldap_extended; SEND_LDAP_EXTENDED *c_send_ldap_extended;
#ifdef LDAP_RES_INTERMEDIATE
SEND_LDAP_INTERMEDIATE *c_send_ldap_intermediate; SEND_LDAP_INTERMEDIATE *c_send_ldap_intermediate;
#endif
} Connection; } Connection;
#if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG) #if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG)
@ -3096,6 +3082,12 @@ struct zone_heap {
return 0; \ return 0; \
} }
typedef int (OV_init)(void);
typedef struct slap_oinit_t {
const char *ov_type;
OV_init *ov_init;
} OverlayInit;
LDAP_END_DECL LDAP_END_DECL
#include "proto-slap.h" #include "proto-slap.h"

@ -133,16 +133,28 @@ parse_slapacl( void )
ber_str2bv( p, 0, 1, &sock_name ); ber_str2bv( p, 0, 1, &sock_name );
} else if ( strncasecmp( optarg, "ssf", len ) == 0 ) { } else if ( strncasecmp( optarg, "ssf", len ) == 0 ) {
ssf = atoi( p ); if ( lutil_atou( &ssf, p ) ) {
Debug( LDAP_DEBUG_ANY, "unable to parse ssf=\"%s\".\n", p, 0, 0 );
return -1;
}
} else if ( strncasecmp( optarg, "transport_ssf", len ) == 0 ) { } else if ( strncasecmp( optarg, "transport_ssf", len ) == 0 ) {
transport_ssf = atoi( p ); if ( lutil_atou( &transport_ssf, p ) ) {
Debug( LDAP_DEBUG_ANY, "unable to parse transport_ssf=\"%s\".\n", p, 0, 0 );
return -1;
}
} else if ( strncasecmp( optarg, "tls_ssf", len ) == 0 ) { } else if ( strncasecmp( optarg, "tls_ssf", len ) == 0 ) {
tls_ssf = atoi( p ); if ( lutil_atou( &tls_ssf, p ) ) {
Debug( LDAP_DEBUG_ANY, "unable to parse tls_ssf=\"%s\".\n", p, 0, 0 );
return -1;
}
} else if ( strncasecmp( optarg, "sasl_ssf", len ) == 0 ) { } else if ( strncasecmp( optarg, "sasl_ssf", len ) == 0 ) {
sasl_ssf = atoi( p ); if ( lutil_atou( &sasl_ssf, p ) ) {
Debug( LDAP_DEBUG_ANY, "unable to parse sasl_ssf=\"%s\".\n", p, 0, 0 );
return -1;
}
} else if ( strncasecmp( optarg, "authzDN", len ) == 0 ) { } else if ( strncasecmp( optarg, "authzDN", len ) == 0 ) {
ber_str2bv( p, 0, 1, &authzDN ); ber_str2bv( p, 0, 1, &authzDN );
@ -264,16 +276,11 @@ slap_tool_init(
exit( EXIT_FAILURE ); exit( EXIT_FAILURE );
} }
} else { } else if ( lutil_atoix( &level, optarg, 0 ) != 0 ) {
char *next = NULL; fprintf( stderr,
"unrecognized log level "
level = strtol( optarg, &next, 0 ); "\"%s\"\n", optarg );
if ( next == NULL || next[ 0 ] != '\0' ) { exit( EXIT_FAILURE );
fprintf( stderr,
"unrecognized log level "
"\"%s\"\n", optarg );
exit( EXIT_FAILURE );
}
} }
if ( level ) { if ( level ) {
@ -283,7 +290,7 @@ slap_tool_init(
ldap_debug = 0; ldap_debug = 0;
} }
#else #else
if ( atoi( optarg ) != 0 ) if ( lutil_atoi( &level, optarg ) != 0 || level != 0 )
fputs( "must compile with LDAP_DEBUG for debugging\n", fputs( "must compile with LDAP_DEBUG for debugging\n",
stderr ); stderr );
#endif #endif
@ -321,7 +328,9 @@ slap_tool_init(
break; break;
case 'n': /* which config file db to index */ case 'n': /* which config file db to index */
dbnum = atoi( optarg ); if ( lutil_atoi( &dbnum, optarg ) ) {
usage( tool, progname );
}
break; break;
case 'o': case 'o':

@ -188,7 +188,7 @@ init_syncrepl(syncinfo_t *si)
} }
if ( attrs == NULL ) { if ( attrs == NULL ) {
Debug( LDAP_DEBUG_ANY, "out of memory\n", 0,0,0 ); Debug( LDAP_DEBUG_ANY, "out of memory\n", 0, 0, 0 );
} }
/* Add Attributes */ /* Add Attributes */
@ -500,7 +500,7 @@ do_syncrep1(
#else /* HAVE_CYRUS_SASL */ #else /* HAVE_CYRUS_SASL */
/* Should never get here, we trapped this at config time */ /* Should never get here, we trapped this at config time */
assert(0); assert(0);
fprintf( stderr, "not compiled with SASL support\n" ); Debug( LDAP_DEBUG_SYNC, "not compiled with SASL support\n", 0, 0, 0 );
rc = LDAP_OTHER; rc = LDAP_OTHER;
goto done; goto done;
#endif #endif
@ -756,7 +756,7 @@ do_syncrep2(
si->si_logstate = SYNCLOG_FALLBACK; si->si_logstate = SYNCLOG_FALLBACK;
} }
rc = err; rc = err;
break; goto done;
} }
if ( rctrls ) { if ( rctrls ) {
rctrlp = *rctrls; rctrlp = *rctrls;
@ -2683,10 +2683,8 @@ static struct {
{ BER_BVC("base"), LDAP_SCOPE_BASE }, { BER_BVC("base"), LDAP_SCOPE_BASE },
{ BER_BVC("one"), LDAP_SCOPE_ONELEVEL }, { BER_BVC("one"), LDAP_SCOPE_ONELEVEL },
{ BER_BVC("onelevel"), LDAP_SCOPE_ONELEVEL }, /* OpenLDAP extension */ { BER_BVC("onelevel"), LDAP_SCOPE_ONELEVEL }, /* OpenLDAP extension */
#ifdef LDAP_SCOPE_SUBORDINATE
{ BER_BVC("children"), LDAP_SCOPE_SUBORDINATE }, { BER_BVC("children"), LDAP_SCOPE_SUBORDINATE },
{ BER_BVC("subordinate"), LDAP_SCOPE_SUBORDINATE }, { BER_BVC("subordinate"), LDAP_SCOPE_SUBORDINATE },
#endif
{ BER_BVC("sub"), LDAP_SCOPE_SUBTREE }, { BER_BVC("sub"), LDAP_SCOPE_SUBTREE },
{ BER_BVC("subtree"), LDAP_SCOPE_SUBTREE }, /* OpenLDAP extension */ { BER_BVC("subtree"), LDAP_SCOPE_SUBTREE }, /* OpenLDAP extension */
{ BER_BVNULL, 0 } { BER_BVNULL, 0 }
@ -2701,40 +2699,46 @@ static slap_verbmasks datamodes[] = {
static int static int
parse_syncrepl_line( parse_syncrepl_line(
char **cargv, ConfigArgs *c,
int cargc, syncinfo_t *si )
syncinfo_t *si
)
{ {
int gots = 0; int gots = 0;
int i; int i;
char *val; char *val;
for ( i = 1; i < cargc; i++ ) { for ( i = 1; i < c->argc; i++ ) {
if ( !strncasecmp( cargv[ i ], IDSTR "=", if ( !strncasecmp( c->argv[ i ], IDSTR "=",
STRLENOF( IDSTR "=" ) ) ) STRLENOF( IDSTR "=" ) ) )
{ {
int tmp; int tmp;
/* '\0' string terminator accounts for '=' */ /* '\0' string terminator accounts for '=' */
val = cargv[ i ] + STRLENOF( IDSTR "=" ); val = c->argv[ i ] + STRLENOF( IDSTR "=" );
tmp= atoi( val ); if ( lutil_atoi( &tmp, val ) != 0 ) {
snprintf( c->msg, sizeof( c->msg ),
"Error: parse_syncrepl_line: "
"unable to parse syncrepl id \"%s\"", val );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return -1;
}
if ( tmp >= 1000 || tmp < 0 ) { if ( tmp >= 1000 || tmp < 0 ) {
fprintf( stderr, "Error: parse_syncrepl_line: " snprintf( c->msg, sizeof( c->msg ),
"syncrepl id %d is out of range [0..999]\n", tmp ); "Error: parse_syncrepl_line: "
"syncrepl id %d is out of range [0..999]", tmp );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return -1; return -1;
} }
si->si_rid = tmp; si->si_rid = tmp;
gots |= GOT_ID; gots |= GOT_ID;
} else if ( !strncasecmp( cargv[ i ], PROVIDERSTR "=", } else if ( !strncasecmp( c->argv[ i ], PROVIDERSTR "=",
STRLENOF( PROVIDERSTR "=" ) ) ) STRLENOF( PROVIDERSTR "=" ) ) )
{ {
val = cargv[ i ] + STRLENOF( PROVIDERSTR "=" ); val = c->argv[ i ] + STRLENOF( PROVIDERSTR "=" );
ber_str2bv( val, 0, 1, &si->si_bindconf.sb_uri ); ber_str2bv( val, 0, 1, &si->si_bindconf.sb_uri );
gots |= GOT_PROVIDER; gots |= GOT_PROVIDER;
} else if ( !strncasecmp( cargv[ i ], SCHEMASTR "=", } else if ( !strncasecmp( c->argv[ i ], SCHEMASTR "=",
STRLENOF( SCHEMASTR "=" ) ) ) STRLENOF( SCHEMASTR "=" ) ) )
{ {
val = cargv[ i ] + STRLENOF( SCHEMASTR "=" ); val = c->argv[ i ] + STRLENOF( SCHEMASTR "=" );
if ( !strncasecmp( val, "on", STRLENOF( "on" ) )) { if ( !strncasecmp( val, "on", STRLENOF( "on" ) )) {
si->si_schemachecking = 1; si->si_schemachecking = 1;
} else if ( !strncasecmp( val, "off", STRLENOF( "off" ) ) ) { } else if ( !strncasecmp( val, "off", STRLENOF( "off" ) ) ) {
@ -2742,59 +2746,63 @@ parse_syncrepl_line(
} else { } else {
si->si_schemachecking = 1; si->si_schemachecking = 1;
} }
} else if ( !strncasecmp( cargv[ i ], FILTERSTR "=", } else if ( !strncasecmp( c->argv[ i ], FILTERSTR "=",
STRLENOF( FILTERSTR "=" ) ) ) STRLENOF( FILTERSTR "=" ) ) )
{ {
val = cargv[ i ] + STRLENOF( FILTERSTR "=" ); val = c->argv[ i ] + STRLENOF( FILTERSTR "=" );
if ( si->si_filterstr.bv_val ) if ( si->si_filterstr.bv_val )
ch_free( si->si_filterstr.bv_val ); ch_free( si->si_filterstr.bv_val );
ber_str2bv( val, 0, 1, &si->si_filterstr ); ber_str2bv( val, 0, 1, &si->si_filterstr );
} else if ( !strncasecmp( cargv[ i ], LOGFILTERSTR "=", } else if ( !strncasecmp( c->argv[ i ], LOGFILTERSTR "=",
STRLENOF( LOGFILTERSTR "=" ) ) ) STRLENOF( LOGFILTERSTR "=" ) ) )
{ {
val = cargv[ i ] + STRLENOF( LOGFILTERSTR "=" ); val = c->argv[ i ] + STRLENOF( LOGFILTERSTR "=" );
if ( si->si_logfilterstr.bv_val ) if ( si->si_logfilterstr.bv_val )
ch_free( si->si_logfilterstr.bv_val ); ch_free( si->si_logfilterstr.bv_val );
ber_str2bv( val, 0, 1, &si->si_logfilterstr ); ber_str2bv( val, 0, 1, &si->si_logfilterstr );
} else if ( !strncasecmp( cargv[ i ], SEARCHBASESTR "=", } else if ( !strncasecmp( c->argv[ i ], SEARCHBASESTR "=",
STRLENOF( SEARCHBASESTR "=" ) ) ) STRLENOF( SEARCHBASESTR "=" ) ) )
{ {
struct berval bv; struct berval bv;
int rc; int rc;
val = cargv[ i ] + STRLENOF( SEARCHBASESTR "=" ); val = c->argv[ i ] + STRLENOF( SEARCHBASESTR "=" );
if ( si->si_base.bv_val ) { if ( si->si_base.bv_val ) {
ch_free( si->si_base.bv_val ); ch_free( si->si_base.bv_val );
} }
ber_str2bv( val, 0, 0, &bv ); ber_str2bv( val, 0, 0, &bv );
rc = dnNormalize( 0, NULL, NULL, &bv, &si->si_base, NULL ); rc = dnNormalize( 0, NULL, NULL, &bv, &si->si_base, NULL );
if ( rc != LDAP_SUCCESS ) { if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, "Invalid base DN \"%s\": %d (%s)\n", snprintf( c->msg, sizeof( c->msg ),
"Invalid base DN \"%s\": %d (%s)",
val, rc, ldap_err2string( rc ) ); val, rc, ldap_err2string( rc ) );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return -1; return -1;
} }
} else if ( !strncasecmp( cargv[ i ], LOGBASESTR "=", } else if ( !strncasecmp( c->argv[ i ], LOGBASESTR "=",
STRLENOF( LOGBASESTR "=" ) ) ) STRLENOF( LOGBASESTR "=" ) ) )
{ {
struct berval bv; struct berval bv;
int rc; int rc;
val = cargv[ i ] + STRLENOF( LOGBASESTR "=" ); val = c->argv[ i ] + STRLENOF( LOGBASESTR "=" );
if ( si->si_logbase.bv_val ) { if ( si->si_logbase.bv_val ) {
ch_free( si->si_logbase.bv_val ); ch_free( si->si_logbase.bv_val );
} }
ber_str2bv( val, 0, 0, &bv ); ber_str2bv( val, 0, 0, &bv );
rc = dnNormalize( 0, NULL, NULL, &bv, &si->si_logbase, NULL ); rc = dnNormalize( 0, NULL, NULL, &bv, &si->si_logbase, NULL );
if ( rc != LDAP_SUCCESS ) { if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, "Invalid logbase DN \"%s\": %d (%s)\n", snprintf( c->msg, sizeof( c->msg ),
"Invalid logbase DN \"%s\": %d (%s)",
val, rc, ldap_err2string( rc ) ); val, rc, ldap_err2string( rc ) );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return -1; return -1;
} }
} else if ( !strncasecmp( cargv[ i ], SCOPESTR "=", } else if ( !strncasecmp( c->argv[ i ], SCOPESTR "=",
STRLENOF( SCOPESTR "=" ) ) ) STRLENOF( SCOPESTR "=" ) ) )
{ {
int j; int j;
val = cargv[ i ] + STRLENOF( SCOPESTR "=" ); val = c->argv[ i ] + STRLENOF( SCOPESTR "=" );
for ( j=0; !BER_BVISNULL(&scopes[j].key); j++ ) { for ( j=0; !BER_BVISNULL(&scopes[j].key); j++ ) {
if (!strcasecmp( val, scopes[j].key.bv_val )) { if (!strcasecmp( val, scopes[j].key.bv_val )) {
si->si_scope = scopes[j].val; si->si_scope = scopes[j].val;
@ -2802,18 +2810,20 @@ parse_syncrepl_line(
} }
} }
if ( BER_BVISNULL(&scopes[j].key) ) { if ( BER_BVISNULL(&scopes[j].key) ) {
fprintf( stderr, "Error: parse_syncrepl_line: " snprintf( c->msg, sizeof( c->msg ),
"unknown scope \"%s\"\n", val); "Error: parse_syncrepl_line: "
"unknown scope \"%s\"", val);
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return -1; return -1;
} }
} else if ( !strncasecmp( cargv[ i ], ATTRSONLYSTR "=", } else if ( !strncasecmp( c->argv[ i ], ATTRSONLYSTR "=",
STRLENOF( ATTRSONLYSTR "=" ) ) ) STRLENOF( ATTRSONLYSTR "=" ) ) )
{ {
si->si_attrsonly = 1; si->si_attrsonly = 1;
} else if ( !strncasecmp( cargv[ i ], ATTRSSTR "=", } else if ( !strncasecmp( c->argv[ i ], ATTRSSTR "=",
STRLENOF( ATTRSSTR "=" ) ) ) STRLENOF( ATTRSSTR "=" ) ) )
{ {
val = cargv[ i ] + STRLENOF( ATTRSSTR "=" ); val = c->argv[ i ] + STRLENOF( ATTRSSTR "=" );
if ( !strncasecmp( val, ":include:", STRLENOF(":include:") ) ) { if ( !strncasecmp( val, ":include:", STRLENOF(":include:") ) ) {
char *attr_fname; char *attr_fname;
attr_fname = ch_strdup( val + STRLENOF(":include:") ); attr_fname = ch_strdup( val + STRLENOF(":include:") );
@ -2846,15 +2856,15 @@ parse_syncrepl_line(
return -1; return -1;
} }
} }
} else if ( !strncasecmp( cargv[ i ], EXATTRSSTR "=", } else if ( !strncasecmp( c->argv[ i ], EXATTRSSTR "=",
STRLENOF( EXATTRSSTR "=" ) ) ) STRLENOF( EXATTRSSTR "=" ) ) )
{ {
val = cargv[ i ] + STRLENOF( EXATTRSSTR "=" ); val = c->argv[ i ] + STRLENOF( EXATTRSSTR "=" );
if ( !strncasecmp( val, ":include:", STRLENOF(":include:") )) { if ( !strncasecmp( val, ":include:", STRLENOF(":include:") )) {
char *attr_fname; char *attr_fname;
attr_fname = ch_strdup( val + STRLENOF(":include:") ); attr_fname = ch_strdup( val + STRLENOF(":include:") );
si->si_exanlist = file2anlist( si->si_exanlist = file2anlist(
si->si_exanlist, attr_fname, " ,\t" ); si->si_exanlist, attr_fname, " ,\t" );
if ( si->si_exanlist == NULL ) { if ( si->si_exanlist == NULL ) {
ch_free( attr_fname ); ch_free( attr_fname );
return -1; return -1;
@ -2866,85 +2876,98 @@ parse_syncrepl_line(
return -1; return -1;
} }
} }
} else if ( !strncasecmp( cargv[ i ], TYPESTR "=", } else if ( !strncasecmp( c->argv[ i ], TYPESTR "=",
STRLENOF( TYPESTR "=" ) ) ) STRLENOF( TYPESTR "=" ) ) )
{ {
val = cargv[ i ] + STRLENOF( TYPESTR "=" ); val = c->argv[ i ] + STRLENOF( TYPESTR "=" );
if ( !strncasecmp( val, "refreshOnly", if ( !strncasecmp( val, "refreshOnly",
STRLENOF("refreshOnly") )) STRLENOF("refreshOnly") ) )
{ {
si->si_type = si->si_ctype = LDAP_SYNC_REFRESH_ONLY; si->si_type = si->si_ctype = LDAP_SYNC_REFRESH_ONLY;
} else if ( !strncasecmp( val, "refreshAndPersist", } else if ( !strncasecmp( val, "refreshAndPersist",
STRLENOF("refreshAndPersist") )) STRLENOF("refreshAndPersist") ) )
{ {
si->si_type = si->si_ctype = LDAP_SYNC_REFRESH_AND_PERSIST; si->si_type = si->si_ctype = LDAP_SYNC_REFRESH_AND_PERSIST;
si->si_interval = 60; si->si_interval = 60;
} else { } else {
fprintf( stderr, "Error: parse_syncrepl_line: " snprintf( c->msg, sizeof( c->msg ),
"unknown sync type \"%s\"\n", val); "Error: parse_syncrepl_line: "
"unknown sync type \"%s\"", val);
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return -1; return -1;
} }
} else if ( !strncasecmp( cargv[ i ], INTERVALSTR "=", } else if ( !strncasecmp( c->argv[ i ], INTERVALSTR "=",
STRLENOF( INTERVALSTR "=" ) ) ) STRLENOF( INTERVALSTR "=" ) ) )
{ {
val = cargv[ i ] + STRLENOF( INTERVALSTR "=" ); val = c->argv[ i ] + STRLENOF( INTERVALSTR "=" );
if ( si->si_type == LDAP_SYNC_REFRESH_AND_PERSIST ) { if ( si->si_type == LDAP_SYNC_REFRESH_AND_PERSIST ) {
si->si_interval = 0; si->si_interval = 0;
} else { } else if ( strchr( val, ':' ) != NULL ) {
char *hstr; char *next, *ptr = val;
char *mstr; unsigned dd, hh, mm, ss;
char *dstr; dd = strtoul( ptr, &next, 10 );
char *sstr; if ( next == ptr || next[0] != ':' ) {
int dd, hh, mm, ss; snprintf( c->msg, sizeof( c->msg ),
dstr = val; "Error: parse_syncrepl_line: "
hstr = strchr( dstr, ':' ); "invalid interval \"%s\", unable to parse days", val );
if ( hstr == NULL ) { Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
fprintf( stderr, "Error: parse_syncrepl_line: "
"invalid interval \"%s\"\n", val );
return -1; return -1;
} }
*hstr++ = '\0'; ptr = next + 1;
mstr = strchr( hstr, ':' ); hh = strtoul( ptr, &next, 10 );
if ( mstr == NULL ) { if ( next == ptr || next[0] != ':' || hh > 24 ) {
fprintf( stderr, "Error: parse_syncrepl_line: " snprintf( c->msg, sizeof( c->msg ),
"invalid interval \"%s\"\n", val ); "Error: parse_syncrepl_line: "
"invalid interval \"%s\", unable to parse hours", val );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return -1; return -1;
} }
*mstr++ = '\0'; ptr = next + 1;
sstr = strchr( mstr, ':' ); mm = strtoul( ptr, &next, 10 );
if ( sstr == NULL ) { if ( next == ptr || next[0] != ':' || mm > 60 ) {
fprintf( stderr, "Error: parse_syncrepl_line: " snprintf( c->msg, sizeof( c->msg ),
"invalid interval \"%s\"\n", val ); "Error: parse_syncrepl_line: "
"invalid interval \"%s\", unable to parse minutes", val );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return -1; return -1;
} }
*sstr++ = '\0'; ptr = next + 1;
ss = strtoul( ptr, &next, 10 );
dd = atoi( dstr ); if ( next == ptr || next[0] != '\0' || ss > 60 ) {
hh = atoi( hstr ); snprintf( c->msg, sizeof( c->msg ),
mm = atoi( mstr ); "Error: parse_syncrepl_line: "
ss = atoi( sstr ); "invalid interval \"%s\", unable to parse seconds", val );
if (( hh > 24 ) || ( hh < 0 ) || Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
( mm > 60 ) || ( mm < 0 ) ||
( ss > 60 ) || ( ss < 0 ) || ( dd < 0 )) {
fprintf( stderr, "Error: parse_syncrepl_line: "
"invalid interval \"%s\"\n", val );
return -1; return -1;
} }
si->si_interval = (( dd * 24 + hh ) * 60 + mm ) * 60 + ss; si->si_interval = (( dd * 24 + hh ) * 60 + mm ) * 60 + ss;
} else {
unsigned long t;
if ( lutil_parse_time( val, &t ) != 0 ) {
snprintf( c->msg, sizeof( c->msg ),
"Error: parse_syncrepl_line: "
"invalid interval \"%s\"", val );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return -1;
}
si->si_interval = (time_t)t;
} }
if ( si->si_interval < 0 ) { if ( si->si_interval < 0 ) {
fprintf( stderr, "Error: parse_syncrepl_line: " snprintf( c->msg, sizeof( c->msg ),
"invalid interval \"%ld\"\n", "Error: parse_syncrepl_line: "
"invalid interval \"%ld\"",
(long) si->si_interval); (long) si->si_interval);
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return -1; return -1;
} }
} else if ( !strncasecmp( cargv[ i ], RETRYSTR "=", } else if ( !strncasecmp( c->argv[ i ], RETRYSTR "=",
STRLENOF( RETRYSTR "=" ) ) ) STRLENOF( RETRYSTR "=" ) ) )
{ {
char **retry_list; char **retry_list;
int j, k, n; int j, k, n;
val = cargv[ i ] + STRLENOF( RETRYSTR "=" ); val = c->argv[ i ] + STRLENOF( RETRYSTR "=" );
retry_list = (char **) ch_calloc( 1, sizeof( char * )); retry_list = (char **) ch_calloc( 1, sizeof( char * ));
retry_list[0] = NULL; retry_list[0] = NULL;
@ -2953,27 +2976,51 @@ parse_syncrepl_line(
for ( k = 0; retry_list && retry_list[k]; k++ ) ; for ( k = 0; retry_list && retry_list[k]; k++ ) ;
n = k / 2; n = k / 2;
if ( k % 2 ) { if ( k % 2 ) {
fprintf( stderr, snprintf( c->msg, sizeof( c->msg ),
"Error: incomplete syncrepl retry list\n" ); "Error: incomplete syncrepl retry list" );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
for ( k = 0; retry_list && retry_list[k]; k++ ) { for ( k = 0; retry_list && retry_list[k]; k++ ) {
ch_free( retry_list[k] ); ch_free( retry_list[k] );
} }
ch_free( retry_list ); ch_free( retry_list );
exit( EXIT_FAILURE ); return 1;
} }
si->si_retryinterval = (time_t *) ch_calloc( n + 1, sizeof( time_t )); si->si_retryinterval = (time_t *) ch_calloc( n + 1, sizeof( time_t ));
si->si_retrynum = (int *) ch_calloc( n + 1, sizeof( int )); si->si_retrynum = (int *) ch_calloc( n + 1, sizeof( int ));
si->si_retrynum_init = (int *) ch_calloc( n + 1, sizeof( int )); si->si_retrynum_init = (int *) ch_calloc( n + 1, sizeof( int ));
for ( j = 0; j < n; j++ ) { for ( j = 0; j < n; j++ ) {
si->si_retryinterval[j] = atoi( retry_list[j*2] ); unsigned long t;
if ( lutil_atoul( &t, retry_list[j*2] ) != 0 ) {
snprintf( c->msg, sizeof( c->msg ),
"Error: invalid retry interval \"%s\" (#%d)",
retry_list[j*2], j );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
/* do some cleanup */
return 1;
}
si->si_retryinterval[j] = (time_t)t;
if ( *retry_list[j*2+1] == '+' ) { if ( *retry_list[j*2+1] == '+' ) {
si->si_retrynum_init[j] = -1; si->si_retrynum_init[j] = -1;
si->si_retrynum[j] = -1; si->si_retrynum[j] = -1;
j++; j++;
break; break;
} else { } else {
si->si_retrynum_init[j] = atoi( retry_list[j*2+1] ); if ( lutil_atoi( &si->si_retrynum_init[j], retry_list[j*2+1] ) != 0 ) {
si->si_retrynum[j] = atoi( retry_list[j*2+1] ); snprintf( c->msg, sizeof( c->msg ),
"Error: invalid initial retry number \"%s\" (#%d)",
retry_list[j*2+1], j );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
/* do some cleanup */
return 1;
}
if ( lutil_atoi( &si->si_retrynum[j], retry_list[j*2+1] ) != 0 ) {
snprintf( c->msg, sizeof( c->msg ),
"Error: invalid retry number \"%s\" (#%d)",
retry_list[j*2+1], j );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
/* do some cleanup */
return 1;
}
} }
} }
si->si_retrynum_init[j] = -2; si->si_retrynum_init[j] = -2;
@ -2984,36 +3031,59 @@ parse_syncrepl_line(
ch_free( retry_list[k] ); ch_free( retry_list[k] );
} }
ch_free( retry_list ); ch_free( retry_list );
} else if ( !strncasecmp( cargv[ i ], MANAGEDSAITSTR "=", } else if ( !strncasecmp( c->argv[ i ], MANAGEDSAITSTR "=",
STRLENOF( MANAGEDSAITSTR "=" ) ) ) STRLENOF( MANAGEDSAITSTR "=" ) ) )
{ {
val = cargv[ i ] + STRLENOF( MANAGEDSAITSTR "=" ); val = c->argv[ i ] + STRLENOF( MANAGEDSAITSTR "=" );
si->si_manageDSAit = atoi( val ); if ( lutil_atoi( &si->si_manageDSAit, val ) != 0
} else if ( !strncasecmp( cargv[ i ], SLIMITSTR "=", || si->si_manageDSAit < 0 || si->si_manageDSAit > 1 )
{
snprintf( c->msg, sizeof( c->msg ),
"invalid manageDSAit value \"%s\".\n",
val );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return 1;
}
} else if ( !strncasecmp( c->argv[ i ], SLIMITSTR "=",
STRLENOF( SLIMITSTR "=") ) ) STRLENOF( SLIMITSTR "=") ) )
{ {
val = cargv[ i ] + STRLENOF( SLIMITSTR "=" ); val = c->argv[ i ] + STRLENOF( SLIMITSTR "=" );
si->si_slimit = atoi( val ); if ( lutil_atoi( &si->si_slimit, val ) != 0 ) {
} else if ( !strncasecmp( cargv[ i ], TLIMITSTR "=", snprintf( c->msg, sizeof( c->msg ),
"invalid size limit value \"%s\".\n",
val );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return 1;
}
} else if ( !strncasecmp( c->argv[ i ], TLIMITSTR "=",
STRLENOF( TLIMITSTR "=" ) ) ) STRLENOF( TLIMITSTR "=" ) ) )
{ {
val = cargv[ i ] + STRLENOF( TLIMITSTR "=" ); val = c->argv[ i ] + STRLENOF( TLIMITSTR "=" );
si->si_tlimit = atoi( val ); if ( lutil_atoi( &si->si_tlimit, val ) != 0 ) {
} else if ( !strncasecmp( cargv[ i ], SYNCDATASTR "=", snprintf( c->msg, sizeof( c->msg ),
"invalid time limit value \"%s\".\n",
val );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return 1;
}
} else if ( !strncasecmp( c->argv[ i ], SYNCDATASTR "=",
STRLENOF( SYNCDATASTR "=" ) ) ) STRLENOF( SYNCDATASTR "=" ) ) )
{ {
val = cargv[ i ] + STRLENOF( SYNCDATASTR "=" ); val = c->argv[ i ] + STRLENOF( SYNCDATASTR "=" );
si->si_syncdata = verb_to_mask( val, datamodes ); si->si_syncdata = verb_to_mask( val, datamodes );
} else if ( bindconf_parse( cargv[i], &si->si_bindconf )) { } else if ( bindconf_parse( c->argv[i], &si->si_bindconf ) ) {
fprintf( stderr, "Error: parse_syncrepl_line: " snprintf( c->msg, sizeof( c->msg ),
"unknown keyword \"%s\"\n", cargv[ i ] ); "Error: parse_syncrepl_line: "
"unknown keyword \"%s\"\n", c->argv[ i ] );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return -1; return -1;
} }
} }
if ( gots != GOT_ALL ) { if ( gots != GOT_ALL ) {
fprintf( stderr, snprintf( c->msg, sizeof( c->msg ),
"Error: Malformed \"syncrepl\" line in slapd config file" ); "Error: Malformed \"syncrepl\" line in slapd config file" );
Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->msg, 0 );
return -1; return -1;
} }
@ -3022,17 +3092,14 @@ parse_syncrepl_line(
static int static int
add_syncrepl( add_syncrepl(
Backend *be, ConfigArgs *c )
char **cargv,
int cargc
)
{ {
syncinfo_t *si; syncinfo_t *si;
int rc = 0; int rc = 0;
if ( !( be->be_search && be->be_add && be->be_modify && be->be_delete )) { if ( !( c->be->be_search && c->be->be_add && c->be->be_modify && c->be->be_delete ) ) {
Debug( LDAP_DEBUG_ANY, "database %s does not support operations " Debug( LDAP_DEBUG_ANY, "%s: database %s does not support operations "
"required for syncrepl\n", be->be_type, 0, 0 ); "required for syncrepl\n", c->log, c->be->be_type, 0 );
return 1; return 1;
} }
si = (syncinfo_t *) ch_calloc( 1, sizeof( syncinfo_t ) ); si = (syncinfo_t *) ch_calloc( 1, sizeof( syncinfo_t ) );
@ -3070,13 +3137,13 @@ add_syncrepl(
LDAP_LIST_INIT( &si->si_nonpresentlist ); LDAP_LIST_INIT( &si->si_nonpresentlist );
ldap_pvt_thread_mutex_init( &si->si_mutex ); ldap_pvt_thread_mutex_init( &si->si_mutex );
rc = parse_syncrepl_line( cargv, cargc, si ); rc = parse_syncrepl_line( c, si );
if ( rc == 0 ) { if ( rc == 0 ) {
si->si_be = be; si->si_be = c->be;
init_syncrepl( si ); init_syncrepl( si );
si->si_re = ldap_pvt_runqueue_insert( &slapd_rq, si->si_interval, si->si_re = ldap_pvt_runqueue_insert( &slapd_rq, si->si_interval,
do_syncrepl, si, "do_syncrepl", be->be_suffix[0].bv_val ); do_syncrepl, si, "do_syncrepl", c->be->be_suffix[0].bv_val );
if ( !si->si_re ) if ( !si->si_re )
rc = -1; rc = -1;
} }
@ -3090,9 +3157,9 @@ add_syncrepl(
BER_BVISNULL( &si->si_bindconf.sb_uri ) ? BER_BVISNULL( &si->si_bindconf.sb_uri ) ?
"(null)" : si->si_bindconf.sb_uri.bv_val, 0, 0 ); "(null)" : si->si_bindconf.sb_uri.bv_val, 0, 0 );
if ( !si->si_schemachecking ) { if ( !si->si_schemachecking ) {
SLAP_DBFLAGS(be) |= SLAP_DBFLAG_NO_SCHEMA_CHECK; SLAP_DBFLAGS(c->be) |= SLAP_DBFLAG_NO_SCHEMA_CHECK;
} }
be->be_syncinfo = si; c->be->be_syncinfo = si;
return 0; return 0;
} }
} }
@ -3226,7 +3293,8 @@ syncrepl_unparse( syncinfo_t *si, struct berval *bv )
} }
int int
syncrepl_config(ConfigArgs *c) { syncrepl_config( ConfigArgs *c )
{
if (c->op == SLAP_CONFIG_EMIT) { if (c->op == SLAP_CONFIG_EMIT) {
if ( c->be->be_syncinfo ) { if ( c->be->be_syncinfo ) {
struct berval bv; struct berval bv;
@ -3241,24 +3309,23 @@ syncrepl_config(ConfigArgs *c) {
if ( c->be->be_syncinfo ) { if ( c->be->be_syncinfo ) {
re = c->be->be_syncinfo->si_re; re = c->be->be_syncinfo->si_re;
if ( re ) { if ( re ) {
if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re )) if ( ldap_pvt_runqueue_isrunning( &slapd_rq, re ) )
ldap_pvt_runqueue_stoptask( &slapd_rq, re ); ldap_pvt_runqueue_stoptask( &slapd_rq, re );
ldap_pvt_runqueue_remove( &slapd_rq, re ); ldap_pvt_runqueue_remove( &slapd_rq, re );
} }
syncinfo_free( c->be->be_syncinfo ); syncinfo_free( c->be->be_syncinfo );
c->be->be_syncinfo = NULL; c->be->be_syncinfo = NULL;
} }
SLAP_DBFLAGS(c->be) &= ~(SLAP_DBFLAG_SHADOW|SLAP_DBFLAG_SYNC_SHADOW); SLAP_DBFLAGS( c->be ) &= ~(SLAP_DBFLAG_SHADOW|SLAP_DBFLAG_SYNC_SHADOW);
return 0; return 0;
} }
if(SLAP_SHADOW(c->be)) { if ( SLAP_SHADOW( c->be ) ) {
Debug(LDAP_DEBUG_ANY, "%s: " Debug(LDAP_DEBUG_ANY, "%s: "
"syncrepl: database already shadowed.\n", "syncrepl: database already shadowed.\n",
c->log, 0, 0); c->log, 0, 0);
return(1); return(1);
} else if(add_syncrepl(c->be, c->argv, c->argc)) { } else if ( add_syncrepl( c ) ) {
return(1); return(1);
} }
SLAP_DBFLAGS(c->be) |= (SLAP_DBFLAG_SHADOW | SLAP_DBFLAG_SYNC_SHADOW); return config_sync_shadow( c );
return(0);
} }

@ -34,6 +34,7 @@
#include <ac/unistd.h> #include <ac/unistd.h>
#include "slap.h" #include "slap.h"
#include "lutil.h"
/* /*
* Set real and effective user id and group id, and group access list * Set real and effective user id and group id, and group access list
@ -49,9 +50,17 @@ slap_init_user( char *user, char *group )
if ( user ) { if ( user ) {
struct passwd *pwd; struct passwd *pwd;
if ( isdigit( (unsigned char) *user )) { if ( isdigit( (unsigned char) *user ) ) {
unsigned u;
got_uid = 1; got_uid = 1;
uid = atoi( user ); if ( lutil_atou( &u, user ) != 0 ) {
Debug( LDAP_DEBUG_ANY, "Unble to parse user %s\n",
user, 0, 0 );
exit( EXIT_FAILURE );
}
uid = (uid_t)u;
#ifdef HAVE_GETPWUID #ifdef HAVE_GETPWUID
pwd = getpwuid( uid ); pwd = getpwuid( uid );
goto did_getpw; goto did_getpw;
@ -86,7 +95,15 @@ slap_init_user( char *user, char *group )
if ( group ) { if ( group ) {
struct group *grp; struct group *grp;
if ( isdigit( (unsigned char) *group )) { if ( isdigit( (unsigned char) *group )) {
gid = atoi( group ); unsigned g;
if ( lutil_atou( &g, group ) != 0 ) {
Debug( LDAP_DEBUG_ANY, "Unble to parse group %s\n",
group, 0, 0 );
exit( EXIT_FAILURE );
}
gid = (uid_t)g;
#ifdef HAVE_GETGRGID #ifdef HAVE_GETGRGID
grp = getgrgid( gid ); grp = getgrgid( gid );
goto did_group; goto did_group;

@ -700,7 +700,7 @@ ordered_value_add(
k = -1; k = -1;
if ( vals[i].bv_val[0] == '{' ) { if ( vals[i].bv_val[0] == '{' ) {
k = strtol( vals[i].bv_val+1, &next, 0 ); k = strtol( vals[i].bv_val + 1, &next, 0 );
if ( next == vals[i].bv_val + 1 || if ( next == vals[i].bv_val + 1 ||
next[ 0 ] != '}' || next[ 0 ] != '}' ||
next - vals[i].bv_val > vals[i].bv_len ) next - vals[i].bv_val > vals[i].bv_len )

@ -429,6 +429,27 @@ telephoneNumber: +1 313 555 5331
# refldap://localhost:9016/cn=Somewhere,ou=Meta,dc=example,dc=com??sub # refldap://localhost:9016/cn=Somewhere,ou=Meta,dc=example,dc=com??sub
# searching base="ou=Meta,o=Example,c=US"...
dn: cn=Dan Aykroyd,ou=Meta,o=Example,c=US
objectClass: inetOrgPerson
cn: Dan Aykroyd
sn: Aykroyd
userPassword:: ZWx3b29k
description: Elwood Blues
dn: cn=John Belushi,ou=Meta,o=Example,c=US
objectClass: inetOrgPerson
cn: John Belushi
sn: Belushi
userPassword:: amFjaw==
description: Joliet Jack Blues
dn: ou=Meta,o=Example,c=US
objectClass: organizationalUnit
ou: Meta
# refldap://localhost:9016/cn=Somewhere,ou=Meta,dc=example,dc=com??sub
# searching base="o=Example,c=US"... # searching base="o=Example,c=US"...
dn: cn=Added Group,ou=Groups,o=Example,c=US dn: cn=Added Group,ou=Groups,o=Example,c=US
objectClass: groupOfNames objectClass: groupOfNames

Some files were not shown because too many files have changed in this diff Show More