Commit 20c5ec95 authored by Kurt Zeilenga's avatar Kurt Zeilenga
Browse files

Sync with HEAD

parent 2c7553a3
This diff is collapsed.
......@@ -43,7 +43,7 @@ ldapsearch \- LDAP search tool
[\c
.BI \-b \ searchbase\fR]
[\c
.BI \-s \ base\fR\||\|\fIone\fR\||\|\fIsub\fR]
.BI \-s \ base\fR\||\|\fIone\fR\||\|\fIsub\fR\||\|\fIchildren\fR]
[\c
.BI \-a \ never\fR\||\|\fIalways\fR\||\|\fIsearch\fR\||\|\fIfind\fR]
[\c
......@@ -183,15 +183,19 @@ Deprecated in favor of -H.
Use \fIsearchbase\fP as the starting point for the search instead of
the default.
.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
.IR base ,
.IR one ,
.IR sub ,
or
.I sub
to specify a base object, one-level, or subtree search. The default
is
.I children
to specify a base object, one-level, subtree, or children search.
The default is
.IR sub .
Note:
.I children
scope requires LDAPv3 subordinate feature extension.
.TP
.BI \-a \ never\fR\||\|\fIalways\fR\||\|\fIsearch\fR\||\|\fIfind
Specify how aliases dereferencing is done. Should be one of
......
......@@ -1758,7 +1758,8 @@ By default it is not built.
.B chain
Chaining.
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
.B denyop
Deny Operation.
......
......@@ -28,9 +28,9 @@ directive.
.B logdb <suffix>
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
of the config file. The suffix entry of the database must also already
exist. The log entries will be generated as the immediate children of the
suffix entry.
of the config file. The suffix entry of the log database will be created
automatically by this overlay. The log entries will be generated as the
immediate children of the suffix entry.
.TP
.B logops <operations>
Specify which types of operations to log. The valid operation types are
......
......@@ -13,7 +13,7 @@ overlay to
.BR slapd (8)
allows automatic referral chasing.
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),
that identity can be asserted while chasing the referrals
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)
for details), which is essentially based on the
.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
The config directives that are specific to the
.B chain
overlay can be prefixed by
overlay are prefixed by
.BR chain\- ,
to avoid potential conflicts with directives specific to the underlying
database or to other stacked overlays.
.LP
There are no chain overlay specific directives; however, directives
related to the \fIldap\fP database that is implicitly instantiated
by the overlay may assume a special meaning when used in conjunction
with this overlay. They are described in
.BR slapd-ldap (5).
There are very few chain overlay specific directives; however, directives
related to the instances of the \fIldap\fP backend that may be implicitly
instantiated by the overlay may assume a special meaning when used
in conjunction with this overlay. They are described in
.BR slapd-ldap (5),
and they also need be prefixed by
.BR chain\- .
.TP
.B overlay chain
This directive adds the chain overlay to the current backend.
The chain overlay may be used with any backend, but it is mainly
intended for use with local storage backends that may return referrals.
It is useless in conjunction with the \fIldap\fP and \fImeta\fP backends
because they already exploit the libldap specific referral chase feature.
It is useless in conjunction with the \fIslapd-ldap\fP and \fIslapd-meta\fP
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
.B chain-uri <ldapuri>
This directive instructs the underlying ldap database about which
URI to contact to chase referrals.
If not present, the referral itself is parsed, and the protocol/host/port
portions are used to establish a connection.
This directive instantiates a new underlying \fIldap\fP database
and instructs it about which URI to contact to chase referrals.
As opposed to what stated in \fBslapd-ldap\fP(5), only one URI
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
Directives for configuring the underlying ldap database may also
be required, as shown here:
be required, as shown in this example:
.LP
.RS
.nf
chain-idassert-method "simple"
chain-idassert-authcDN "cn=Auth,dc=example,dc=com"
chain-idassert-passwd "secret"
chain-idassert-mode "self"
overlay chain
chain-rebind-as-user FALSE
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
.RE
.LP
Any valid directives for the ldap database may be used; see
.BR slapd-ldap (5)
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
.TP
ETCDIR/slapd.conf
......@@ -76,4 +128,4 @@ default slapd configuration file
.BR slapd\-ldap (5),
.BR slapd (8).
.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
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
The following adds a template with filter string \fB((&sn=)(givenName=))\fP
and attributes mail, postaladdress, telephonenumber and a TTL of 1 hour.
......@@ -116,7 +133,52 @@ cachesize 100
.RE
.LP
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
.TP
ETCDIR/slapd.conf
default slapd configuration file
......
......@@ -104,19 +104,33 @@ rewrite_parse(
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 ) {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] negative or null rewriteMaxPasses'\n",
"[%s:%d] negative or null rewriteMaxPasses\n",
fname, lineno, 0 );
return -1;
}
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 ) {
Debug( LDAP_DEBUG_ANY,
"[%s:%d] negative or null rewriteMaxPassesPerRule'\n",
"[%s:%d] negative or null rewriteMaxPassesPerRule\n",
fname, lineno, 0 );
return -1;
}
} else {
......
......@@ -696,7 +696,7 @@ aci_init( void )
&rc, &text, LDAP_SCHEMA_ALLOW_ALL );
if ( !at ) {
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 );
return rc;
}
......@@ -704,9 +704,9 @@ aci_init( void )
rc = at_add( at, 0, &sat, &text );
if ( rc != LDAP_SUCCESS ) {
ldap_attributetype_free( at );
fprintf( stderr, "iMUX_monitor_schema_init: "
"AttributeType load failed: %s %s\n",
scherr2str( rc ), text );
Debug( LDAP_DEBUG_ANY,
"aci_init: AttributeType \"%s\" load failed: %s %s\n",
aci_at.name, scherr2str( rc ), text );
return rc;
}
ldap_memfree( at );
......@@ -715,7 +715,7 @@ aci_init( void )
aci_at.ad, &text );
if ( rc != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY,
"unable to find AttributeDescription "
"aci_init: unable to find AttributeDescription "
"\"%s\": %d (%s)\n",
aci_at.name, rc, text );
return 1;
......
......@@ -310,9 +310,10 @@ fe_access_allowed(
*/
be_orig = op->o_bd;
op->o_bd = select_backend( &op->o_req_ndn, 0, 0 );
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 );
op->o_bd = be_orig;
......@@ -423,14 +424,10 @@ access_allowed_mask(
desc, val, access, state, &mask );
} else {
BackendDB *be_orig = op->o_bd;
/* use default (but pass through frontend
* for global ACL overlays) */
op->o_bd = frontendDB;
ret = frontendDB->bd_info->bi_access_allowed( op, e,
desc, val, access, state, &mask );
op->o_bd = be_orig;
}
if ( !ret ) {
......@@ -1603,12 +1600,9 @@ slap_acl_mask(
port = strrchr( ip.bv_val, ':' );
if ( port ) {
char *next;
ip.bv_len = port - ip.bv_val;
++port;
port_number = strtol( port, &next, 10 );
if ( next[0] != '\0' )
if ( lutil_atoi( &port_number, port ) != 0 )
continue;
}
......
......@@ -325,7 +325,7 @@ parse_acl(
int pos )
{
int i;
char *left, *right, *style, *next;
char *left, *right, *style;
struct berval bv;
AccessControl *a;
Access *b;
......@@ -776,10 +776,7 @@ parse_acl(
} else if ( strcasecmp( style, "level" ) == 0 )
{
char *next;
level = strtol( style_level, &next, 10 );
if ( next[0] != '\0' ) {
if ( lutil_atoi( &level, style_level ) != 0 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: unable to parse level "
"in \"level{n}\"\n",
......@@ -1385,7 +1382,7 @@ parse_acl(
char *end = NULL;
b->a_peername_port = strtol( port, &end, 10 );
if ( end[0] != '}' ) {
if ( end == port || end[0] != '}' ) {
/* illegal port */
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"illegal peername port specification "
......@@ -1700,8 +1697,7 @@ parse_acl(
return acl_usage();
}
b->a_authz.sai_ssf = strtol( right, &next, 10 );
if ( next == NULL || next[0] != '\0' ) {
if ( lutil_atou( &b->a_authz.sai_ssf, right ) != 0 ) {
Debug( LDAP_DEBUG_ANY,
"%s: line %d: unable to parse ssf value (%s).\n",
fname, lineno, right );
......@@ -1739,8 +1735,7 @@ parse_acl(
return acl_usage();
}
b->a_authz.sai_transport_ssf = strtol( right, &next, 10 );
if ( next == NULL || next[0] != '\0' ) {
if ( lutil_atou( &b->a_authz.sai_transport_ssf, right ) != 0 ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"unable to parse transport_ssf value (%s).\n",
fname, lineno, right );
......@@ -1778,8 +1773,7 @@ parse_acl(
return acl_usage();
}
b->a_authz.sai_tls_ssf = strtol( right, &next, 10 );
if ( next == NULL || next[0] != '\0' ) {
if ( lutil_atou( &b->a_authz.sai_tls_ssf, right ) != 0 ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"unable to parse tls_ssf value (%s).\n",
fname, lineno, right );
......@@ -1817,8 +1811,7 @@ parse_acl(
return acl_usage();
}
b->a_authz.sai_sasl_ssf = strtol( right, &next, 10 );
if ( next == NULL || next[0] != '\0' ) {
if ( lutil_atou( &b->a_authz.sai_sasl_ssf, right ) != 0 ) {
Debug( LDAP_DEBUG_ANY, "%s: line %d: "
"unable to parse sasl_ssf value (%s).\n",
fname, lineno, right );
......
......@@ -345,14 +345,13 @@ at_insert(
const char **err )
{
struct aindexrec *air;
char **names;
char **names = NULL;
if ( sat->sat_oid ) {
air = (struct aindexrec *)
ch_calloc( 1, sizeof(struct aindexrec) );
air->air_name.bv_val = sat->sat_oid;
air->air_name.bv_len = strlen(sat->sat_oid);
ber_str2bv( sat->sat_oid, 0, 0, &air->air_name );
air->air_at = sat;
if ( avl_insert( &attr_index, (caddr_t) air,
attr_index_cmp, avl_dup_error ) )
......@@ -379,8 +378,7 @@ at_insert(
while ( *names ) {
air = (struct aindexrec *)
ch_calloc( 1, sizeof(struct aindexrec) );
air->air_name.bv_val = *names;
air->air_name.bv_len = strlen(*names);
ber_str2bv( *names, 0, 0, &air->air_name );
air->air_at = sat;
if ( avl_insert( &attr_index, (caddr_t) air,
attr_index_cmp, avl_dup_error ) )
......@@ -396,6 +394,29 @@ at_insert(
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;
}
/* FIX: temporal consistency check */
......@@ -428,16 +449,17 @@ at_add(
AttributeType **rsat,
const char **err )
{
AttributeType *sat;
MatchingRule *mr;
Syntax *syn;
AttributeType *sat = NULL;
MatchingRule *mr = NULL;
Syntax *syn = NULL;
int i;
int code;
char *cname;
char *oid;
char *oidm = NULL;
int code = LDAP_SUCCESS;
char *cname = NULL;
char *oidm = NULL;
if ( !OID_LEADCHAR( at->at_oid[0] )) {
char *oid;
/* Expand OID macros */
oid = oidm_find( at->at_oid );
if ( !oid ) {
......@@ -451,11 +473,14 @@ at_add(
}
if ( at->at_syntax_oid && !OID_LEADCHAR( at->at_syntax_oid[0] )) {
char *oid;
/* Expand OID macros */
oid = oidm_find( at->at_syntax_oid );
if ( !oid ) {
*err = at->at_syntax_oid;
return SLAP_SCHERR_OIDM;
code = SLAP_SCHERR_OIDM;
goto error_return;
}
if ( oid != at->at_syntax_oid ) {
ldap_memfree( at->at_syntax_oid );
......@@ -469,7 +494,8 @@ at_add(
for( i=0; at->at_names[i]; i++ ) {
if( !slap_valid_descr( 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 {
*err = "";
return SLAP_SCHERR_ATTR_INCOMPLETE;
code = SLAP_SCHERR_ATTR_INCOMPLETE;
goto error_return;
}
*err = cname;
if ( !at->at_usage && at->at_no_user_mod ) {
/* 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_usage ) {
/* 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 ) {
/* 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 ) {
case BDB_CHKPT:
case BDB_CHKPT: {
long l;
bdb->bi_txn_cp = 1;
bdb->bi_txn_cp_kbyte = strtol( c->argv[1], NULL, 0 );
bdb->bi_txn_cp_min = strtol( c->argv[2], NULL, 0 );
if ( lutil_atolx( &l, c->argv[1], 0 ) != 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,
* 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 );
}
}
break;