Sync with HEAD

This commit is contained in:
Kurt Zeilenga 2005-08-17 18:15:34 +00:00
parent b2da42b873
commit 01fbca5974
46 changed files with 2817 additions and 1096 deletions

View File

@ -0,0 +1,36 @@
Copyright 2005 The OpenLDAP Foundation. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted only as authorized by the OpenLDAP
Public License.
This directory contains native slapd plugins that implement access rules.
posixgroup.c contains a simple example that implements access control
based on posixGroup membership, loosely inspired by ITS#3849. It should
be made clear that this access control policy does not reflect any
standard track model of handling access control, and should be
essentially viewed as an illustration of the use of the dynamic
extension of access control within slapd.
To use the acl-posixgroup plugin, add:
moduleload acl-posixgroup.so
to your slapd configuration file; it requires "nis.schema" to be loaded.
It is configured using
access to <what>
by dynacl/posixGroup[.{exact,expand}]=<dnpat> {<level>|<priv(s)}
The default is "exact"; in case of "expand", "<dnpat>" results from
the expansion of submatches in the "<what>" portion. "<level>|<priv(s)>"
describe the level of privilege this rule can assume.
No Makefile is provided. Use a command line similar to:
gcc -shared -I../../../include -I../../../servers/slapd -Wall -g \
-o acl-posixgroup.so posixgroup.c
to compile the posixGroup ACL plugin.

View File

@ -0,0 +1,320 @@
/* $OpenLDAP$ */
/*
* Copyright 1998-2005 The OpenLDAP Foundation.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted only as authorized by the OpenLDAP
* Public License.
*
* A copy of this license is available in the file LICENSE in the
* top-level directory of the distribution or, alternatively, at
* <http://www.OpenLDAP.org/license.html>.
*/
#include <portable.h>
#include <ac/string.h>
#include <slap.h>
#include <lutil.h>
/* Need dynacl... */
#ifdef SLAP_DYNACL
typedef struct pg_t {
slap_style_t pg_style;
struct berval pg_pat;
} pg_t;
static ObjectClass *pg_posixGroup;
static AttributeDescription *pg_memberUid;
static ObjectClass *pg_posixAccount;
static AttributeDescription *pg_uidNumber;
static int pg_dynacl_destroy( void *priv );
static int
pg_dynacl_parse(
const char *fname,
int lineno,
slap_style_t style,
const char *pattern,
void **privp )
{
pg_t *pg;
int rc;
const char *text = NULL;
struct berval pat;
ber_str2bv( pattern, 0, 0, &pat );
pg = ch_calloc( 1, sizeof( pg_t ) );
pg->pg_style = style;
switch ( pg->pg_style ) {
case ACL_STYLE_BASE:
rc = dnNormalize( 0, NULL, NULL, &pat, &pg->pg_pat, NULL );
if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, "%s line %d: posixGroup ACL: "
"unable to normalize DN \"%s\".\n",
fname, lineno, pattern );
goto cleanup;
}
break;
case ACL_STYLE_EXPAND:
ber_dupbv( &pg->pg_pat, &pat );
break;
default:
fprintf( stderr, "%s line %d: posixGroup ACL: "
"unsupported style \"%s\".\n",
fname, lineno, style_strings[ pg->pg_style ] );
goto cleanup;
}
if ( pg_posixGroup == NULL ) {
pg_posixGroup = oc_find( "posixGroup" );
if ( pg_posixGroup == NULL ) {
fprintf( stderr, "%s line %d: posixGroup ACL: "
"unable to lookup \"posixGroup\" "
"objectClass.\n",
fname, lineno );
goto cleanup;
}
pg_posixAccount = oc_find( "posixAccount" );
if ( pg_posixGroup == NULL ) {
fprintf( stderr, "%s line %d: posixGroup ACL: "
"unable to lookup \"posixAccount\" "
"objectClass.\n",
fname, lineno );
goto cleanup;
}
rc = slap_str2ad( "memberUid", &pg_memberUid, &text );
if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, "%s line %d: posixGroup ACL: "
"unable to lookup \"memberUid\" "
"attributeDescription (%d: %s).\n",
fname, lineno, rc, text );
goto cleanup;
}
rc = slap_str2ad( "uidNumber", &pg_uidNumber, &text );
if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, "%s line %d: posixGroup ACL: "
"unable to lookup \"uidNumber\" "
"attributeDescription (%d: %s).\n",
fname, lineno, rc, text );
goto cleanup;
}
}
*privp = (void *)pg;
return 0;
cleanup:
(void)pg_dynacl_destroy( (void *)pg );
return 1;
}
static int
pg_dynacl_unparse(
void *priv,
struct berval *bv )
{
pg_t *pg = (pg_t *)priv;
char *ptr;
bv->bv_len = STRLENOF( " dynacl/posixGroup.expand=" ) + pg->pg_pat.bv_len;
bv->bv_val = ch_malloc( bv->bv_len + 1 );
ptr = lutil_strcopy( bv->bv_val, " dynacl/posixGroup" );
switch ( pg->pg_style ) {
case ACL_STYLE_BASE:
ptr = lutil_strcopy( ptr, ".exact=" );
break;
case ACL_STYLE_EXPAND:
ptr = lutil_strcopy( ptr, ".expand=" );
break;
default:
assert( 0 );
}
ptr = lutil_strncopy( ptr, pg->pg_pat.bv_val, pg->pg_pat.bv_len );
ptr[ 0 ] = '\0';
bv->bv_len = ptr - bv->bv_val;
return 0;
}
static int
pg_dynacl_mask(
void *priv,
struct slap_op *op,
Entry *target,
AttributeDescription *desc,
struct berval *val,
int nmatch,
regmatch_t *matches,
slap_access_t *grant,
slap_access_t *deny )
{
pg_t *pg = (pg_t *)priv;
Entry *group = NULL,
*user = NULL;
int rc;
Backend *be = op->o_bd,
*group_be = NULL,
*user_be = NULL;
struct berval group_ndn;
ACL_INVALIDATE( *deny );
/* get user */
if ( target && dn_match( &target->e_nname, &op->o_ndn ) ) {
user = target;
rc = LDAP_SUCCESS;
} else {
user_be = op->o_bd = select_backend( &op->o_ndn, 0, 0 );
if ( op->o_bd == NULL ) {
op->o_bd = be;
return 0;
}
rc = be_entry_get_rw( op, &op->o_ndn, pg_posixAccount, pg_uidNumber, 0, &user );
}
if ( rc != LDAP_SUCCESS || user == NULL ) {
op->o_bd = be;
return 0;
}
/* get target */
if ( pg->pg_style == ACL_STYLE_EXPAND ) {
char buf[ 1024 ];
struct berval bv;
bv.bv_len = sizeof( buf ) - 1;
bv.bv_val = buf;
if ( acl_string_expand( &bv, &pg->pg_pat,
target->e_nname.bv_val,
nmatch, matches ) )
{
goto cleanup;
}
if ( dnNormalize( 0, NULL, NULL, &bv, &group_ndn,
op->o_tmpmemctx ) != LDAP_SUCCESS )
{
/* did not expand to a valid dn */
goto cleanup;
}
} else {
group_ndn = pg->pg_pat;
}
if ( target && dn_match( &target->e_nname, &group_ndn ) ) {
group = target;
rc = LDAP_SUCCESS;
} else {
group_be = op->o_bd = select_backend( &group_ndn, 0, 0 );
if ( op->o_bd == NULL ) {
goto cleanup;
}
rc = be_entry_get_rw( op, &group_ndn, pg_posixGroup, pg_memberUid, 0, &group );
}
if ( group_ndn.bv_val != pg->pg_pat.bv_val ) {
op->o_tmpfree( group_ndn.bv_val, op->o_tmpmemctx );
}
if ( rc == LDAP_SUCCESS && group != NULL ) {
Attribute *a_uid,
*a_member;
a_uid = attr_find( user->e_attrs, pg_uidNumber);
if ( !a_uid || !BER_BVISNULL( &a_uid->a_nvals[ 1 ] ) ) {
rc = LDAP_NO_SUCH_ATTRIBUTE;
} else {
a_member = attr_find( group->e_attrs, pg_memberUid );
if ( !a_member ) {
rc = LDAP_NO_SUCH_ATTRIBUTE;
} else {
rc = value_find_ex( pg_memberUid,
SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH |
SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
a_member->a_nvals, &a_uid->a_nvals[ 0 ],
op->o_tmpmemctx );
}
}
} else {
rc = LDAP_NO_SUCH_OBJECT;
}
if ( rc == LDAP_SUCCESS ) {
ACL_LVL_ASSIGN_WRITE( *grant );
}
cleanup:;
if ( group != NULL && group != target ) {
op->o_bd = group_be;
be_entry_release_r( op, group );
op->o_bd = be;
}
if ( user != NULL && user != target ) {
op->o_bd = user_be;
be_entry_release_r( op, group );
op->o_bd = be;
}
return 0;
}
static int
pg_dynacl_destroy(
void *priv )
{
pg_t *pg = (pg_t *)priv;
if ( pg != NULL ) {
if ( !BER_BVISNULL( &pg->pg_pat ) ) {
ber_memfree( pg->pg_pat.bv_val );
}
ch_free( pg );
}
return 0;
}
static struct slap_dynacl_t pg_dynacl = {
"posixGroup",
pg_dynacl_parse,
pg_dynacl_unparse,
pg_dynacl_mask,
pg_dynacl_destroy
};
int
init_module( int argc, char *argv[] )
{
return slap_dynacl_register( &pg_dynacl );
}
#endif /* SLAP_DYNACL */

View File

@ -37,22 +37,19 @@ directive.
.TP
.B syncprov-checkpoint <ops> <minutes>
After a write operation has succeeded, write the contextCSN to the underlying
database if <ops> write operations or more than <minutes> time have passed
database if
.B <ops>
write operations or more than
.B <minutes>
time have passed
since the last checkpoint. Checkpointing is disabled by default.
.TP
.B syncprov-sessionlog <sid> <size>
Specify a session log for recording information about entries that have been
scoped out of the content identified by
.BR <sid> .
The number of entries in the log is limited by
.BR <size> .
Both
.B <sid>
and
.B <size>
must be non-negative integers, and
.B <sid>
can have no more than three decimal digits.
.B syncprov-sessionlog <ops>
Specify a session log for recording information about write operations made
on the database. The
.B <ops>
specifies the number of operations that are recorded in the log. All write
operations (except Adds) are recorded in the log.
When using the session log, it is helpful to set an eq index on the
entryUUID attribute in the underlying database.
.SH FILES

View File

@ -58,7 +58,7 @@ attributes, as these will generally not be unique, nor are they operational
attributes.
.TP
.B unique_attributes <attribute...>
Specify one or more attributes which for which uniqueness will be enforced.
Specify one or more attributes for which uniqueness will be enforced.
If not specified, all attributes which are not operational (eg, system
attributes such as
.B entryUUID )
@ -79,7 +79,15 @@ on the
list, and included in the
.B unique_attributes
list, in that order. This makes it possible to create interesting and
unusable configurations.
unusable configurations. Usually only one of
.B unique_ignore
or
.B unique_attributes
should be configured; use
.B unique_ignore
if the majority of attributes should be unique, and use
.B unique_attributes
if only a small set of attributes should be unique.
.LP
Typical attributes for the
.B unique_ignore

View File

@ -62,7 +62,14 @@ cannot be used in conjunction with the
option.
.TP
.BI \-a " filter"
Only dump entries matching the asserted filter.
Only dump entries matching the asserted filter.
For example
slapcat -a \\
"(!(entryDN:dnSubtreeMatch:=ou=People,dc=example,dc=com))"
will dump all but the "ou=People,dc=example,dc=com" subtree
of the "dc=example,dc=com" database.
.TP
.BI \-s " subtree-dn"
Only dump entries in the subtree specified by this DN.

View File

@ -530,6 +530,7 @@ int slapi_x_backend_get_flags( const Slapi_Backend *be, unsigned long *flags );
#define SLAPI_X_OPERATION_DELETE_GLUE_PARENT 1305
#define SLAPI_X_MANAGEDIT 1306
#define SLAPI_X_OPERATION_NO_SCHEMA_CHECK 1307
#define SLAPI_X_ADD_STRUCTURAL_CLASS 1308
/* Authentication types */
#define SLAPD_AUTH_NONE "none"

View File

@ -1228,14 +1228,9 @@ ldap_url_duplist (LDAPURLDesc *ludlist)
return dest;
}
int
ldap_url_parselist (LDAPURLDesc **ludlist, const char *url )
{
return ldap_url_parselist_ext( ludlist, url, ", " );
}
int
ldap_url_parselist_ext (LDAPURLDesc **ludlist, const char *url, const char *sep )
static int
ldap_url_parselist_int (LDAPURLDesc **ludlist, const char *url, const char *sep,
int (*url_parse)( const char *, LDAPURLDesc ** ) )
{
int i, rc;
LDAPURLDesc *ludp;
@ -1254,7 +1249,7 @@ ldap_url_parselist_ext (LDAPURLDesc **ludlist, const char *url, const char *sep
for (i = 0; urls[i] != NULL; i++) ;
/* ...and put them in the "stack" backward */
while (--i >= 0) {
rc = ldap_url_parse( urls[i], &ludp );
rc = url_parse( urls[i], &ludp );
if ( rc != 0 ) {
ldap_charray_free(urls);
ldap_free_urllist(*ludlist);
@ -1268,6 +1263,18 @@ ldap_url_parselist_ext (LDAPURLDesc **ludlist, const char *url, const char *sep
return LDAP_URL_SUCCESS;
}
int
ldap_url_parselist (LDAPURLDesc **ludlist, const char *url )
{
return ldap_url_parselist_int( ludlist, url, ", ", ldap_url_parse );
}
int
ldap_url_parselist_ext (LDAPURLDesc **ludlist, const char *url, const char *sep )
{
return ldap_url_parselist_int( ludlist, url, sep, ldap_url_parse_ext );
}
int
ldap_url_parsehosts(
LDAPURLDesc **ludlist,

View File

@ -206,10 +206,7 @@ struct rewrite_rule {
char *lr_pattern;
char *lr_subststring;
char *lr_flagstring;
#ifdef USE_REWRITE_LDAP_PVT_THREADS
ldap_pvt_thread_mutex_t lr_mutex;
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
regex_t lr_regex;
regex_t lr_regex;
/*
* I was thinking about some kind of per-rule mutex, but there's

View File

@ -346,14 +346,6 @@ rewrite_rule_compile(
return REWRITE_ERR;
}
#ifdef USE_REWRITE_LDAP_PVT_THREADS
if ( ldap_pvt_thread_mutex_init( &rule->lr_mutex ) ) {
regfree( &rule->lr_regex );
free( rule );
return REWRITE_ERR;
}
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
/*
* Just to remember them ...
*/
@ -427,13 +419,7 @@ recurse:;
op->lo_num_passes++;
#ifdef USE_REWRITE_LDAP_PVT_THREADS
ldap_pvt_thread_mutex_lock( &rule->lr_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
rc = regexec( &rule->lr_regex, string, nmatch, match, 0 );
#ifdef USE_REWRITE_LDAP_PVT_THREADS
ldap_pvt_thread_mutex_unlock( &rule->lr_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
if ( rc != 0 ) {
if ( *result == NULL && string != arg ) {
free( string );
@ -503,9 +489,6 @@ rewrite_rule_destroy(
}
regfree( &rule->lr_regex );
#ifdef USE_REWRITE_LDAP_PVT_THREADS
ldap_pvt_thread_mutex_destroy( &rule->lr_mutex );
#endif /* USE_REWRITE_LDAP_PVT_THREADS */
for ( action = rule->lr_action; action; ) {
struct rewrite_action *curraction = action;

View File

@ -38,6 +38,7 @@ SRCS = main.c globals.c bconfig.c config.c daemon.c \
backover.c ctxcsn.c ldapsync.c frontend.c \
slapadd.c slapcat.c slapcommon.c slapdn.c slapindex.c \
slappasswd.c slaptest.c slapauth.c slapacl.c component.c \
aci.c \
$(@PLAT@_SRCS)
OBJS = main.o globals.o bconfig.o config.o daemon.o \
@ -55,6 +56,7 @@ OBJS = main.o globals.o bconfig.o config.o daemon.o \
backover.o ctxcsn.o ldapsync.o frontend.o \
slapadd.o slapcat.o slapcommon.o slapdn.o slapindex.o \
slappasswd.o slaptest.o slapauth.o slapacl.o component.o \
aci.o \
$(@PLAT@_OBJS)
LDAP_INCDIR= ../../include -I$(srcdir) -I$(srcdir)/slapi -I.

View File

@ -51,6 +51,9 @@ do_abandon( Operation *op, SlapReply *rs )
return SLAPD_DISCONNECT;
}
Statslog( LDAP_DEBUG_STATS, "%s ABANDON msg=%ld\n",
op->o_log_prefix, (long) id, 0, 0, 0 );
if( get_ctrls( op, rs, 0 ) != LDAP_SUCCESS ) {
Debug( LDAP_DEBUG_ANY, "do_abandon: get_ctrls failed\n", 0, 0 ,0 );
return rs->sr_err;

1502
servers/slapd/aci.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1109,7 +1109,7 @@ parse_acl(
}
} else {
b->a_group_oc = oc_find(SLAPD_GROUP_CLASS);
b->a_group_oc = oc_find( SLAPD_GROUP_CLASS );
if( b->a_group_oc == NULL ) {
fprintf( stderr,
@ -2250,6 +2250,20 @@ access_free( Access *a )
if ( !BER_BVISNULL( &a->a_group_pat ) ) {
free( a->a_group_pat.bv_val );
}
if ( a->a_dynacl != NULL ) {
slap_dynacl_t *da;
for ( da = a->a_dynacl; da; ) {
slap_dynacl_t *tmp = da;
da = da->da_next;
if ( tmp->da_destroy ) {
tmp->da_destroy( tmp->da_private );
}
ch_free( tmp );
}
}
free( a );
}
@ -2263,6 +2277,9 @@ acl_free( AccessControl *a )
filter_free( a->acl_filter );
}
if ( !BER_BVISNULL( &a->acl_dn_pat ) ) {
if ( a->acl_dn_style == ACL_STYLE_REGEX ) {
regfree( &a->acl_dn_re );
}
free ( a->acl_dn_pat.bv_val );
}
if ( a->acl_attrs ) {
@ -2523,8 +2540,9 @@ access2text( Access *b, char *ptr )
for ( da = b->a_dynacl; da; da = da->da_next ) {
if ( da->da_unparse ) {
struct berval bv;
struct berval bv = BER_BVNULL;
(void)( *da->da_unparse )( da->da_private, &bv );
assert( !BER_BVISNULL( &bv ) );
ptr = lutil_strcopy( ptr, bv.bv_val );
ch_free( bv.bv_val );
}

View File

@ -850,6 +850,12 @@ fetch_entry_retry:
if ( get_pagedresults(op) > SLAP_CONTROL_IGNORED ) {
if ( rs->sr_nentries >= ((PagedResultsState *)op->o_pagedresults_state)->ps_size ) {
#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;
send_paged_response( op, rs, &lastid, tentries );
goto done;
}

View File

@ -251,12 +251,150 @@ ldap_back_freeconn( Operation *op, struct ldapconn *lc )
return 0;
}
#ifdef HAVE_TLS
static int
ldap_back_start_tls(
LDAP *ld,
int protocol,
int *is_tls,
const char *url,
unsigned flags,
const char **text )
{
int rc = LDAP_SUCCESS;
struct ldapinfo li;
/* this is ridicolous... */
li.flags = flags;
/* start TLS ("tls-[try-]{start,propagate}" statements) */
if ( ( LDAP_BACK_USE_TLS( &li ) || ( *is_tls && LDAP_BACK_PROPAGATE_TLS( &li ) ) )
&& !ldap_is_ldaps_url( url ) )
{
#ifdef SLAP_STARTTLS_ASYNCHRONOUS
/*
* use asynchronous StartTLS
* in case, chase referral (not implemented yet)
*/
int msgid;
if ( protocol == 0 ) {
ldap_get_option( ld, LDAP_OPT_PROTOCOL_VERSION,
(void *)&protocol );
}
if ( protocol < LDAP_VERSION3 ) {
protocol = LDAP_VERSION3;
/* Set LDAP version */
ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION,
(const void *)&protocol );
}
rc = ldap_start_tls( ld, NULL, NULL, &msgid );
if ( rc == LDAP_SUCCESS ) {
LDAPMessage *res = NULL;
int retries = 1;
struct timeval tv = { 0, 0 };
retry:;
rc = ldap_result( ld, msgid, LDAP_MSG_ALL, &tv, &res );
if ( rc < 0 ) {
rc = LDAP_OTHER;
} else if ( rc == 0 ) {
if ( retries ) {
retries--;
tv.tv_sec = 0;
tv.tv_usec = 100000;
goto retry;
}
rc = LDAP_OTHER;
} else if ( rc == LDAP_RES_EXTENDED ) {
struct berval *data = NULL;
rc = ldap_parse_extended_result( ld, res,
NULL, &data, 0 );
if ( rc == LDAP_SUCCESS ) {
rc = ldap_result2error( ld, res, 1 );
res = NULL;
/* FIXME: in case a referral
* is returned, should we try
* using it instead of the
* configured URI? */
if ( rc == LDAP_SUCCESS ) {
rc = ldap_install_tls( ld );
} else if ( rc == LDAP_REFERRAL ) {
rc = LDAP_OTHER;
*text = "unwilling to chase referral returned by Start TLS exop";
}
if ( data ) {
if ( data->bv_val ) {
ber_memfree( data->bv_val );
}
ber_memfree( data );
}
}
} else {
rc = LDAP_OTHER;
}
if ( res != NULL ) {
ldap_msgfree( res );
}
}
#else /* ! SLAP_STARTTLS_ASYNCHRONOUS */
/*
* use synchronous StartTLS
*/
rc = ldap_start_tls_s( ld, NULL, NULL );
#endif /* ! SLAP_STARTTLS_ASYNCHRONOUS */
/* if StartTLS is requested, only attempt it if the URL
* is not "ldaps://"; this may occur not only in case
* of misconfiguration, but also when used in the chain
* overlay, where the "uri" can be parsed out of a referral */
switch ( rc ) {
case LDAP_SUCCESS:
*is_tls = 1;
break;
case LDAP_SERVER_DOWN:
break;
default:
if ( LDAP_BACK_TLS_CRITICAL( &li ) ) {
*text = "could not start TLS";
break;
}
/* in case Start TLS is not critical */
*is_tls = 0;
rc = LDAP_SUCCESS;
break;
}
} else {
*is_tls = 0;
}
return rc;
}
#endif /* HAVE_TLS */
static int
ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, ldap_back_send_t sendok )
{
struct ldapinfo *li = (struct ldapinfo *)op->o_bd->be_private;
int vers = op->o_protocol;
LDAP *ld = NULL;
#ifdef HAVE_TLS
int is_tls = op->o_conn->c_is_tls;
#endif /* HAVE_TLS */
assert( lcp != NULL );
@ -276,102 +414,24 @@ ldap_back_prepare_conn( struct ldapconn **lcp, Operation *op, SlapReply *rs, lda
}
#ifdef HAVE_TLS
/* start TLS ("tls-[try-]{start,propagate}" statements) */
if ( ( LDAP_BACK_USE_TLS( li ) || ( op->o_conn->c_is_tls && LDAP_BACK_PROPAGATE_TLS( li ) ) )
&& !ldap_is_ldaps_url( li->url ) )
{
#ifdef SLAP_STARTTLS_ASYNCHRONOUS
/*
* use asynchronous StartTLS
* in case, chase referral (not implemented yet)
*/
int msgid;
rs->sr_err = ldap_start_tls( ld, NULL, NULL, &msgid );
if ( rs->sr_err == LDAP_SUCCESS ) {
LDAPMessage *res = NULL;
int rc, retries = 1;
struct timeval tv = { 0, 0 };
retry:;
rc = ldap_result( ld, msgid, LDAP_MSG_ALL, &tv, &res );
if ( rc < 0 ) {
rs->sr_err = LDAP_OTHER;
} else if ( rc == 0 ) {
if ( retries ) {
retries--;
tv.tv_sec = 0;
tv.tv_usec = 100000;
goto retry;
}
rs->sr_err = LDAP_OTHER;
} else if ( rc == LDAP_RES_EXTENDED ) {
struct berval *data = NULL;
rs->sr_err = ldap_parse_extended_result( ld, res,
NULL, &data, 0 );
if ( rs->sr_err == LDAP_SUCCESS ) {
rs->sr_err = ldap_result2error( ld, res, 1 );
res = NULL;
/* FIXME: in case a referral
* is returned, should we try
* using it instead of the
* configured URI? */
if ( rs->sr_err == LDAP_SUCCESS ) {
ldap_install_tls( ld );
} else if ( rs->sr_err == LDAP_REFERRAL ) {
rs->sr_err = LDAP_OTHER;
rs->sr_text = "unwilling to chase referral returned by Start TLS exop";
}
if ( data ) {
if ( data->bv_val ) {
ber_memfree( data->bv_val );
}
ber_memfree( data );
}
}
} else {
rs->sr_err = LDAP_OTHER;
}
if ( res != NULL ) {
ldap_msgfree( res );
}
}
#else /* ! SLAP_STARTTLS_ASYNCHRONOUS */
/*
* use synchronous StartTLS
*/
rs->sr_err = ldap_start_tls_s( ld, NULL, NULL );
#endif /* ! SLAP_STARTTLS_ASYNCHRONOUS */
/* if StartTLS is requested, only attempt it if the URL
* is not "ldaps://"; this may occur not only in case
* of misconfiguration, but also when used in the chain
* overlay, where the "uri" can be parsed out of a referral */
if ( rs->sr_err == LDAP_SERVER_DOWN
|| ( rs->sr_err != LDAP_SUCCESS && LDAP_BACK_TLS_CRITICAL( li ) ) )
{
ldap_unbind_ext( ld, NULL, NULL );
goto error_return;
}
/* in case Start TLS is not critical */
rs->sr_err = LDAP_SUCCESS;
rs->sr_err = ldap_back_start_tls( ld,
op->o_protocol, &is_tls,
li->url, li->flags, &rs->sr_text );
if ( rs->sr_err != LDAP_SUCCESS ) {
ldap_unbind_ext( ld, NULL, NULL );
goto error_return;
}
#endif /* HAVE_TLS */
if ( *lcp == NULL ) {
*lcp = (struct ldapconn *)ch_calloc( 1, sizeof( struct ldapconn ) );
(*lcp)->lc_flags= li->flags;
}
(*lcp)->lc_ld = ld;
(*lcp)->lc_refcnt = 1;
#ifdef HAVE_TLS
(*lcp)->lc_is_tls = is_tls;
#endif /* HAVE_TLS */
error_return:;
if ( rs->sr_err != LDAP_SUCCESS ) {
@ -407,14 +467,28 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
lc_curr.lc_conn = op->o_conn;
} else {
lc_curr.lc_conn = NULL;
#ifdef HAVE_TLS
if ( op->o_conn->c_is_tls ) {
lc_curr.lc_conn = LDAP_BACK_PRIV_CONN_TLS;
} else
#endif /* HAVE_TLS */
{
lc_curr.lc_conn = LDAP_BACK_PRIV_CONN;
}
}
/* Internal searches are privileged and shared. So is root. */
/* FIXME: there seem to be concurrency issues */
if ( op->o_do_not_cache || be_isroot( op ) ) {
lc_curr.lc_local_ndn = op->o_bd->be_rootndn;
lc_curr.lc_conn = NULL;
#ifdef HAVE_TLS
if ( op->o_conn->c_is_tls ) {
lc_curr.lc_conn = LDAP_BACK_PRIV_CONN_TLS;
} else
#endif /* HAVE_TLS */
{
lc_curr.lc_conn = LDAP_BACK_PRIV_CONN;
}
lc_curr.lc_ispriv = 1;
} else {
@ -454,6 +528,33 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
}
}
#ifdef HAVE_TLS
/* if start TLS failed but it was not mandatory,
* check if the non-TLS connection was already
* in cache; in case, destroy the newly created
* connection and use the existing one */
if ( lc->lc_conn == LDAP_BACK_PRIV_CONN_TLS
&& !ldap_tls_inplace( lc->lc_ld ) )
{
struct ldapconn *tmplc;
lc_curr.lc_conn = LDAP_BACK_PRIV_CONN;
ldap_pvt_thread_mutex_lock( &li->conn_mutex );
tmplc = (struct ldapconn *)avl_find( li->conntree,
(caddr_t)&lc_curr, ldap_back_conn_cmp );
if ( tmplc != NULL ) {
refcnt = ++tmplc->lc_refcnt;
ldap_back_conn_free( lc );
lc = tmplc;
}
ldap_pvt_thread_mutex_unlock( &li->conn_mutex );
if ( tmplc != NULL ) {
goto done;
}
}
#endif /* HAVE_TLS */
lc->lc_bound = 0;
/* Inserts the newly created ldapconn in the avl tree */
@ -489,7 +590,8 @@ ldap_back_getconn( Operation *op, SlapReply *rs, ldap_back_send_t sendok )
"=>ldap_back_getconn: conn %p fetched (refcnt=%u)\n",
(void *)lc, refcnt, 0 );
}
done:;
return lc;
}
@ -673,6 +775,22 @@ ldap_back_rebind( LDAP *ld, LDAP_CONST char *url, ber_tag_t request,
{
struct ldapconn *lc = (struct ldapconn *)params;
#ifdef HAVE_TLS
/* ... otherwise we couldn't get here */
assert( lc != NULL );
if ( !ldap_tls_inplace( ld ) ) {
int is_tls = lc->lc_is_tls,
rc;
const char *text = NULL;
rc = ldap_back_start_tls( ld, 0, &is_tls, url, lc->lc_flags, &text );
if ( rc != LDAP_SUCCESS ) {
return rc;
}
}
#endif /* HAVE_TLS */
/* FIXME: add checks on the URL/identity? */
return ldap_sasl_bind_s( ld, lc->lc_bound_ndn.bv_val,

View File

@ -908,8 +908,22 @@ ldap_back_cf_gen( ConfigArgs *c )
case LDAP_BACK_CFG_IDASSERT_AUTHZFROM: {
struct berval bv;
#ifdef SLAP_AUTHZ_SYNTAX
struct berval in;
int rc;
ber_str2bv( c->argv[ 1 ], 0, 0, &in );
rc = authzNormalize( 0, NULL, NULL, &in, &bv, NULL );
if ( rc != LDAP_SUCCESS ) {
fprintf( stderr, "%s: %d: "
"\"idassert-authzFrom <authz>\": "
"invalid syntax.\n",
c->fname, c->lineno );
return 1;
}
#else /* !SLAP_AUTHZ_SYNTAX */
ber_str2bv( c->argv[ 1 ], 0, 1, &bv );
#endif /* !SLAP_AUTHZ_SYNTAX */
ber_bvarray_add( &li->idassert_authz, &bv );
} break;
@ -1562,6 +1576,9 @@ ldap_back_exop_whoami(
return rs->sr_err = LDAP_PROTOCOL_ERROR;
}
Statslog( LDAP_DEBUG_STATS, "%s WHOAMI\n",
op->o_log_prefix, 0, 0, 0, 0 );
rs->sr_err = backend_check_restrictions( op, rs,
(struct berval *)&slap_EXOP_WHOAMI );
if( rs->sr_err != LDAP_SUCCESS ) return rs->sr_err;

View File

@ -394,6 +394,15 @@ fail:;
BER_BVZERO( &rs->sr_ref[ cnt ] );
}
if ( match.bv_val != NULL ) {
if ( match.bv_val[ 0 ] == '\0' ) {
LDAP_FREE( match.bv_val );
BER_BVZERO( &match );
} else {
match.bv_len = strlen( match.bv_val );
}
}
/* cleanup */
if ( references ) {
ldap_value_free( references );

View File

@ -203,6 +203,7 @@ enum {
typedef struct metatarget_t {
char *mt_uri;
int mt_scope;
struct berval mt_psuffix; /* pretty suffix */
struct berval mt_nsuffix; /* normalized suffix */
@ -351,6 +352,7 @@ meta_back_conn_dup(
extern int
meta_back_is_candidate(
struct berval *nsuffix,
int suffixscope,
struct berval *ndn,
int scope );

View File

@ -502,15 +502,22 @@ meta_back_dobind(
{
metainfo_t *mi = ( metainfo_t * )op->o_bd->be_private;
int bound = 0, i;
int bound = 0,
i,
isroot = 0;
SlapReply *candidates = meta_back_candidates_get( op );
ldap_pvt_thread_mutex_lock( &mc->mc_mutex );
if ( be_isroot( op ) ) {
isroot = 1;
}
Debug( LDAP_DEBUG_TRACE,
"%s meta_back_dobind: conn=%ld\n",
op->o_log_prefix, mc->mc_conn->c_connid, 0 );
"%s meta_back_dobind: conn=%ld%s\n",
op->o_log_prefix, mc->mc_conn->c_connid,
isroot ? " (isroot)" : "" );
ldap_pvt_thread_mutex_lock( &mc->mc_mutex );
/*
* all the targets are bound as pseudoroot
@ -546,8 +553,23 @@ meta_back_dobind(
continue;
}
rc = meta_back_single_dobind( op, rs, mc, i,
if ( isroot && !BER_BVISNULL( &mi->mi_targets[ i ].mt_pseudorootdn ) )
{
Operation op2 = *op;
op2.o_tag = LDAP_REQ_BIND;
op2.o_req_dn = mi->mi_targets[ i ].mt_pseudorootdn;
op2.o_req_ndn = mi->mi_targets[ i ].mt_pseudorootdn;
op2.orb_cred = mi->mi_targets[ i ].mt_pseudorootpw;
op2.orb_method = LDAP_AUTH_SIMPLE;
rc = meta_back_single_bind( &op2, rs, mc, i );
} else {
rc = meta_back_single_dobind( op, rs, mc, i,
LDAP_BACK_DONTSEND, mt->mt_nretries, 1 );
}
if ( rc != LDAP_SUCCESS ) {
rs->sr_err = slap_map_api2result( rs );

View File

@ -23,6 +23,7 @@
#include "portable.h"
#include <stdio.h>
#include "ac/string.h"
#include "slap.h"
#include "../back-ldap/back-ldap.h"
@ -59,11 +60,46 @@
int
meta_back_is_candidate(
struct berval *nsuffix,
int suffixscope,
struct berval *ndn,
int scope )
{
if ( dnIsSuffix( ndn, nsuffix ) ) {
return META_CANDIDATE;
switch ( suffixscope ) {
case LDAP_SCOPE_SUBTREE:
default:
return META_CANDIDATE;
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE:
if ( ndn->bv_len > nsuffix->bv_len ) {
return META_CANDIDATE;
}
break;
#endif /* LDAP_SCOPE_SUBORDINATE */
/* nearly useless; not allowed by config */
case LDAP_SCOPE_ONELEVEL:
if ( ndn->bv_len > nsuffix->bv_len ) {
struct berval rdn = *ndn;
rdn.bv_len -= nsuffix->bv_len
+ STRLENOF( "," );
if ( dnIsOneLevelRDN( &rdn ) ) {
return META_CANDIDATE;
}
}
break;
/* nearly useless; not allowed by config */
case LDAP_SCOPE_BASE:
if ( ndn->bv_len == nsuffix->bv_len ) {
return META_CANDIDATE;
}
break;
}
return META_NOT_CANDIDATE;
}
if ( scope == LDAP_SCOPE_SUBTREE && dnIsSuffix( nsuffix, ndn ) ) {
@ -76,28 +112,6 @@ meta_back_is_candidate(
return META_NOT_CANDIDATE;
}
#if 0
/*
* meta_back_is_candidate_unique
*
* checks whether a candidate is unique
* Note: dn MUST be normalized
*/
static int
meta_back_is_candidate_unique(
metainfo_t *mi,
struct berval *ndn )
{
switch ( meta_back_select_unique_candidate( mi, ndn ) ) {
case META_TARGET_MULTIPLE:
case META_TARGET_NONE:
return 0;
}
return 1;
}
#endif /* 0 */
/*
* meta_back_select_unique_candidate
*
@ -114,7 +128,9 @@ meta_back_select_unique_candidate(
int i, candidate = META_TARGET_NONE;
for ( i = 0; i < mi->mi_ntargets; ++i ) {
if ( meta_back_is_candidate( &mi->mi_targets[ i ].mt_nsuffix, ndn, LDAP_SCOPE_BASE ) )
if ( meta_back_is_candidate( &mi->mi_targets[ i ].mt_nsuffix,
mi->mi_targets[ i ].mt_scope,
ndn, LDAP_SCOPE_BASE ) )
{
if ( candidate == META_TARGET_NONE ) {
candidate = i;

View File

@ -159,9 +159,7 @@ meta_back_db_config(
/*
* copies and stores uri and suffix
*/
dn.bv_val = ludp->lud_dn;
dn.bv_len = strlen( ludp->lud_dn );
ber_str2bv( ludp->lud_dn, 0, 0, &dn );
rc = dnPrettyNormal( NULL, &dn, &mi->mi_targets[ i ].mt_psuffix,
&mi->mi_targets[ i ].mt_nsuffix, NULL );
if( rc != LDAP_SUCCESS ) {
@ -173,6 +171,25 @@ meta_back_db_config(
ludp->lud_dn[ 0 ] = '\0';
switch ( ludp->lud_scope ) {
case LDAP_SCOPE_DEFAULT:
mi->mi_targets[ i ].mt_scope = LDAP_SCOPE_SUBTREE;
break;
case LDAP_SCOPE_SUBTREE:
#ifdef LDAP_SCOPE_SUBORDINATE
case LDAP_SCOPE_SUBORDINATE:
#endif /* LDAP_SCOPE_SUBORDINATE */
mi->mi_targets[ i ].mt_scope = ludp->lud_scope;
break;
default:
fprintf( stderr, "%s: line %d: "
"invalid scope for target '%s'\n",
fname, lineno, argv[ 1 ] );
return( 1 );
}
/* check all, to apply the scope check on the first one */
for ( tmpludp = ludp; tmpludp; tmpludp = tmpludp->lud_next ) {
if ( tmpludp->lud_dn != NULL && tmpludp->lud_dn[ 0 ] != '\0' ) {
@ -183,10 +200,6 @@ meta_back_db_config(
return( 1 );
}
if ( tmpludp->lud_scope == LDAP_SCOPE_BASE ) {
tmpludp->lud_scope = LDAP_SCOPE_DEFAULT;
}
}
mi->mi_targets[ i ].mt_uri = ldap_url_list2urls( ludp );

View File

@ -526,6 +526,7 @@ meta_back_get_candidate(
* a candidate, try using it (FIXME: YMMV) */
if ( mi->mi_defaulttarget != META_DEFAULT_TARGET_NONE
&& meta_back_is_candidate( &mi->mi_targets[ mi->mi_defaulttarget ].mt_nsuffix,
mi->mi_targets[ mi->mi_defaulttarget ].mt_scope,
ndn, op->o_tag == LDAP_REQ_SEARCH ? op->ors_scope : LDAP_SCOPE_BASE ) )
{
candidate = mi->mi_defaulttarget;
@ -538,6 +539,9 @@ meta_back_get_candidate(
}
break;
}
} else {
rs->sr_err = LDAP_SUCCESS;
}
return candidate;
@ -795,6 +799,13 @@ meta_back_getconn(
}
if ( rs->sr_err != LDAP_SUCCESS ) {
if ( new_conn ) {
meta_back_freeconn( op, mc );
} else {
meta_back_release_conn( op, mc );
}
if ( sendok & LDAP_BACK_SENDERR ) {
if ( rs->sr_err == LDAP_NO_SUCH_OBJECT ) {
rs->sr_matched = op->o_bd->be_suffix[ 0 ].bv_val;
@ -803,18 +814,27 @@ meta_back_getconn(
rs->sr_text = NULL;
rs->sr_matched = NULL;
}
return NULL;
}
}
if ( newparent && meta_back_get_candidate( op, rs, op->orr_nnewSup ) != i )
{
if ( new_conn ) {
meta_back_freeconn( op, mc );
} else {
meta_back_release_conn( op, mc );
}
rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
rs->sr_text = "cross-target rename not supported";
if ( sendok & LDAP_BACK_SENDERR ) {
send_ldap_result( op, rs );
rs->sr_text = NULL;
}
return NULL;
}
@ -894,6 +914,7 @@ meta_back_getconn(
for ( i = 0; i < mi->mi_ntargets; i++ ) {
if ( i == cached
|| meta_back_is_candidate( &mi->mi_targets[ i ].mt_nsuffix,
mi->mi_targets[ i ].mt_scope,
&op->o_req_ndn, LDAP_SCOPE_SUBTREE ) )
{

View File

@ -97,6 +97,11 @@ meta_back_search_start(
&op->o_req_ndn ) )
{
realbase = mi->mi_targets[ candidate ].mt_nsuffix;
#ifdef LDAP_SCOPE_SUBORDINATE
if ( mi->mi_targets[ candidate ].mt_scope == LDAP_SCOPE_SUBORDINATE ) {
realscope = LDAP_SCOPE_SUBORDINATE;
}
#endif /* LDAP_SCOPE_SUBORDINATE */
} else {
/*
@ -124,7 +129,11 @@ meta_back_search_start(
realbase = mi->mi_targets[ candidate ].mt_nsuffix;
#ifdef LDAP_SCOPE_SUBORDINATE
if ( op->ors_scope == LDAP_SCOPE_SUBORDINATE ) {
realscope = LDAP_SCOPE_SUBTREE;
if ( mi->mi_targets[ candidate ].mt_scope == LDAP_SCOPE_SUBORDINATE ) {
realscope = LDAP_SCOPE_SUBORDINATE;
} else {
realscope = LDAP_SCOPE_SUBTREE;
}
} else
#endif /* LDAP_SCOPE_SUBORDINATE */
{
@ -693,17 +702,52 @@ really_bad:;
*
* FIXME: only the last one gets caught!
*/
if ( candidate_match > 0 && rs->sr_nentries > 0 ) {
savepriv = op->o_private;
op->o_private = (void *)mi->mi_ntargets;
if ( candidate_match > 0 ) {
struct berval pmatched = BER_BVNULL;
/* we use the first one */
for ( i = 0; i < mi->mi_ntargets; i++ ) {
if ( candidates[ i ].sr_tag == META_CANDIDATE
&& candidates[ i ].sr_matched )
{
matched = (char *)candidates[ i ].sr_matched;
candidates[ i ].sr_matched = NULL;
break;
struct berval bv, pbv;
int rc;
ber_str2bv( candidates[ i ].sr_matched, 0, 0, &bv );
rc = dnPretty( NULL, &bv, &pbv, op->o_tmpmemctx );
if ( rc == LDAP_SUCCESS ) {
/* NOTE: if they all are superiors
* of the baseDN, the shorter is also
* superior of the longer... */
if ( pbv.bv_len > pmatched.bv_len ) {
if ( !BER_BVISNULL( &pmatched ) ) {
op->o_tmpfree( pmatched.bv_val, op->o_tmpmemctx );
}
pmatched = pbv;
op->o_private = (void *)i;
} else {
op->o_tmpfree( pbv.bv_val, op->o_tmpmemctx );
}
}
if ( candidates[ i ].sr_matched != NULL ) {
free( (char *)candidates[ i ].sr_matched );
candidates[ i ].sr_matched = NULL;
}
}
}
if ( !BER_BVISNULL( &pmatched ) ) {
matched = pmatched.bv_val;
}
} else if ( sres == LDAP_NO_SUCH_OBJECT ) {
matched = ch_strdup( op->o_bd->be_suffix[ 0 ].bv_val );
}
#if 0
@ -742,8 +786,6 @@ really_bad:;
rs->sr_err = sres;
rs->sr_matched = matched;
rs->sr_ref = ( sres == LDAP_REFERRAL ? rs->sr_v2ref : NULL );
savepriv = op->o_private;
op->o_private = (void *)mi->mi_ntargets;
send_ldap_result( op, rs );
op->o_private = savepriv;
rs->sr_matched = NULL;
@ -751,7 +793,7 @@ really_bad:;
finish:;
if ( matched ) {
free( matched );
op->o_tmpfree( matched, op->o_tmpmemctx );
}
if ( rs->sr_v2ref ) {
@ -786,7 +828,7 @@ finish:;
meta_back_release_conn( op, mc );
return rc;
return rs->sr_err;
}
static int

View File

@ -60,6 +60,9 @@ int cancel_extop( Operation *op, SlapReply *rs )
return LDAP_PROTOCOL_ERROR;
}
Statslog( LDAP_DEBUG_STATS, "%s CANCEL msg=%d\n",
op->o_log_prefix, opid, 0, 0, 0 );
ldap_pvt_thread_mutex_lock( &op->o_conn->c_mutex );
LDAP_STAILQ_FOREACH( o, &op->o_conn->c_pending_ops, o_next ) {
if ( o->o_msgid == opid ) {

View File

@ -50,6 +50,8 @@ static Connection *connections = NULL;
static ldap_pvt_thread_mutex_t conn_nextid_mutex;
static unsigned long conn_nextid = 0;
static const char conn_lost_str[] = "connection lost";
/* structure state (protected by connections_mutex) */
#define SLAP_C_UNINITIALIZED 0x00 /* MUST BE ZERO (0) */
#define SLAP_C_UNUSED 0x01
@ -191,7 +193,7 @@ int connections_shutdown(void)
ldap_pvt_thread_mutex_lock( &connections[i].c_mutex );
/* connections_mutex and c_mutex are locked */
connection_closing( &connections[i] );
connection_closing( &connections[i], "slapd shutdown" );
connection_close( &connections[i] );
ldap_pvt_thread_mutex_unlock( &connections[i].c_mutex );
@ -222,7 +224,7 @@ int connections_timeout_idle(time_t now)
if( difftime( c->c_activitytime+global_idletimeout, now) < 0 ) {
/* close it */
connection_closing( c );
connection_closing( c, "idletimeout" );
connection_close( c );
i++;
}
@ -492,6 +494,7 @@ long connection_init(
if ( flags == CONN_IS_CLIENT ) {
c->c_conn_state = SLAP_C_CLIENT;
c->c_struct_state = SLAP_C_USED;
c->c_close_reason = "?"; /* should never be needed */
ber_sockbuf_ctrl( c->c_sb, LBER_SB_OPT_SET_FD, &s );
ldap_pvt_thread_mutex_unlock( &c->c_mutex );
ldap_pvt_thread_mutex_unlock( &connections_mutex );
@ -563,6 +566,7 @@ long connection_init(
c->c_conn_state = SLAP_C_INACTIVE;
c->c_struct_state = SLAP_C_USED;
c->c_close_reason = "?"; /* should never be needed */
c->c_ssf = c->c_transport_ssf = ssf;
c->c_tls_ssf = 0;
@ -625,6 +629,7 @@ connection_destroy( Connection *c )
/* note: connections_mutex should be locked by caller */
ber_socket_t sd;
unsigned long connid;
const char *close_reason;
assert( connections != NULL );
assert( c != NULL );
@ -635,6 +640,7 @@ connection_destroy( Connection *c )
/* only for stats (print -1 as "%lu" may give unexpected results ;) */
connid = c->c_connid;
close_reason = c->c_close_reason;
backend_connection_destroy(c);
@ -672,9 +678,10 @@ connection_destroy( Connection *c )
if ( sd != AC_SOCKET_INVALID ) {
slapd_remove( sd, 1, 0 );
Statslog( LDAP_DEBUG_STATS,
"conn=%lu fd=%ld closed\n",
connid, (long) sd, 0, 0, 0 );
Statslog( LDAP_DEBUG_STATS, (close_reason
? "conn=%lu fd=%ld closed (%s)\n"
: "conn=%lu fd=%ld closed\n"),
connid, (long) sd, close_reason, 0, 0 );
}
ber_sockbuf_free( c->c_sb );
@ -688,6 +695,7 @@ connection_destroy( Connection *c )
c->c_conn_state = SLAP_C_INVALID;
c->c_struct_state = SLAP_C_UNUSED;
c->c_close_reason = "?"; /* should never be needed */
#ifdef LDAP_SLAPI
/* call destructors, then constructors; avoids unnecessary allocation */
@ -740,7 +748,7 @@ static void connection_abandon( Connection *c )
}
}
void connection_closing( Connection *c )
void connection_closing( Connection *c, const char *why )
{
assert( connections != NULL );
assert( c != NULL );
@ -758,6 +766,7 @@ void connection_closing( Connection *c )
c->c_connid, sd, 0 );
/* update state to closing */
c->c_conn_state = SLAP_C_CLOSING;
c->c_close_reason = why;
/* don't listen on this port anymore */
slapd_clr_read( sd, 1 );
@ -773,6 +782,9 @@ void connection_closing( Connection *c )
ldap_pvt_thread_yield();
ldap_pvt_thread_mutex_lock( &c->c_mutex );
}
} else if( why == NULL && c->c_close_reason == conn_lost_str ) {
/* Client closed connection after doing Unbind. */
c->c_close_reason = NULL;
}
}
@ -1085,7 +1097,8 @@ operations_error:
case LBER_ERROR:
case LDAP_REQ_UNBIND:
/* c_mutex is locked */
connection_closing( conn );
connection_closing(
conn, tag == LDAP_REQ_UNBIND ? NULL : "operations error" );
break;
case LDAP_REQ_BIND:
@ -1144,6 +1157,7 @@ void connection_client_stop(
c->c_listener = NULL;
c->c_conn_state = SLAP_C_INVALID;
c->c_struct_state = SLAP_C_UNUSED;
c->c_close_reason = "?"; /* should never be needed */
connection_return( c );
slapd_remove( s, 0, 1 );
}
@ -1209,7 +1223,7 @@ int connection_read(ber_socket_t s)
s, rc, c->c_connid );
c->c_needs_tls_accept = 0;
/* connections_mutex and c_mutex are locked */
connection_closing( c );
connection_closing( c, "TLS negotiation failure" );
#if 0
/* Drain input before close, to allow SSL error codes
@ -1247,6 +1261,9 @@ int connection_read(ber_socket_t s)
"unable to get TLS client DN, error=%d id=%lu\n",
s, rc, c->c_connid );
}
Statslog( LDAP_DEBUG_STATS,
"conn=%lu TLS established tls_ssf=%u ssf=%u\n",
c->c_connid, c->c_tls_ssf, c->c_ssf, 0, 0 );
slap_sasl_external( c, c->c_tls_ssf, &authid );
if ( authid.bv_val ) free( authid.bv_val );
}
@ -1281,7 +1298,7 @@ int connection_read(ber_socket_t s)
"error=%d id=%lu, closing\n",
s, rc, c->c_connid );
/* connections_mutex and c_mutex are locked */
connection_closing( c );
connection_closing( c, "SASL layer install failure" );
connection_close( c );
connection_return( c );
ldap_pvt_thread_mutex_unlock( &connections_mutex );
@ -1310,7 +1327,7 @@ int connection_read(ber_socket_t s)
"connection_read(%d): input error=%d id=%lu, closing.\n",
s, rc, c->c_connid );
/* connections_mutex and c_mutex are locked */
connection_closing( c );
connection_closing( c, conn_lost_str );
connection_close( c );
connection_return( c );
ldap_pvt_thread_mutex_unlock( &connections_mutex );

View File

@ -996,7 +996,7 @@ dnRelativeMatch(
asserted->bv_val,
asserted->bv_len );
} else {
return 1;
match = 1;
}
}
@ -1022,7 +1022,7 @@ dnRelativeMatch(
asserted->bv_val,
asserted->bv_len );
} else {
return 1;
match = 1;
}
}
@ -1049,7 +1049,7 @@ dnRelativeMatch(
match = dnIsOneLevelRDN( &rdn ) ? 0 : 1;
}
} else {
return 1;
match = 1;
}
}

View File

@ -166,6 +166,8 @@ do_extended(
/* check for controls inappropriate for all extended operations */
if( get_manageDSAit( op ) == SLAP_CONTROL_CRITICAL ) {
Statslog( LDAP_DEBUG_STATS, "%s EXT oid=%s\n",
op->o_log_prefix, op->ore_reqoid.bv_val, 0, 0, 0 );
send_ldap_error( op, rs,
LDAP_UNAVAILABLE_CRITICAL_EXTENSION,
"manageDSAit control inappropriate" );
@ -196,6 +198,8 @@ fe_extended( Operation *op, SlapReply *rs )
if( !(ext = find_extop(supp_ext_list, &op->ore_reqoid )))
{
Statslog( LDAP_DEBUG_STATS, "%s EXT oid=%s\n",
op->o_log_prefix, op->ore_reqoid.bv_val, 0, 0, 0 );
Debug( LDAP_DEBUG_ANY, "do_extended: unsupported operation \"%s\"\n",
op->ore_reqoid.bv_val, 0 ,0 );
send_ldap_error( op, rs, LDAP_PROTOCOL_ERROR,
@ -328,6 +332,9 @@ whoami_extop (
return LDAP_PROTOCOL_ERROR;
}
Statslog( LDAP_DEBUG_STATS, "%s WHOAMI\n",
op->o_log_prefix, 0, 0, 0, 0 );
op->o_bd = op->o_conn->c_authz_backend;
if( backend_check_restrictions( op, rs,
(struct berval *)&slap_EXOP_WHOAMI ) != LDAP_SUCCESS ) {

View File

@ -998,9 +998,9 @@ ppolicy_bind( Operation *op, SlapReply *rs )
/* Reset the restricted flag for the next session on this connection */
static int
ppolicy_unbind( Operation *op, SlapReply *rs )
ppolicy_connection_destroy( BackendDB *bd, Connection *conn )
{
pwcons[op->o_conn->c_conn_idx].restricted = 0;
pwcons[conn->c_conn_idx].restricted = 0;
return SLAP_CB_CONTINUE;
}
@ -1785,11 +1785,11 @@ int ppolicy_init()
ppolicy.on_bi.bi_op_add = ppolicy_add;
ppolicy.on_bi.bi_op_bind = ppolicy_bind;
ppolicy.on_bi.bi_op_unbind = ppolicy_unbind;
ppolicy.on_bi.bi_op_compare = ppolicy_restrict;
ppolicy.on_bi.bi_op_delete = ppolicy_restrict;
ppolicy.on_bi.bi_op_modify = ppolicy_modify;
ppolicy.on_bi.bi_op_search = ppolicy_restrict;
ppolicy.on_bi.bi_connection_destroy = ppolicy_connection_destroy;
return overlay_register( &ppolicy );
}

View File

@ -447,8 +447,8 @@ syncprov_findbase( Operation *op, fbase_cookie *fc )
* was not checkpointed at the previous shutdown.
*
* 2: when the current contextCSN is known and we have a sync cookie, we search
* for one entry with CSN <= the cookie CSN. (Used to search for =.) If an
* entry is found, the cookie CSN is valid, otherwise it is stale.
* for one entry with CSN = the cookie CSN. If not found, try <= cookie CSN.
* If an entry is found, the cookie CSN is valid, otherwise it is stale.
*
* 3: during a refresh phase, we search for all entries with CSN <= the cookie
* CSN, and generate Present records for them. We always collect this result
@ -555,6 +555,7 @@ syncprov_findcsn( Operation *op, int mode )
int i, rc = LDAP_SUCCESS;
fpres_cookie pcookie;
sync_control *srs = NULL;
int findcsn_retry = 1;
if ( mode != FIND_MAXCSN ) {
srs = op->o_controls[slap_cids.sc_LDAPsync];
@ -579,6 +580,7 @@ syncprov_findcsn( Operation *op, int mode )
fop.ors_filter = &cf;
fop.ors_filterstr.bv_val = buf;
again:
switch( mode ) {
case FIND_MAXCSN:
cf.f_choice = LDAP_FILTER_GE;
@ -595,10 +597,18 @@ syncprov_findcsn( Operation *op, int mode )
maxcsn.bv_len = si->si_ctxcsn.bv_len;
break;
case FIND_CSN:
cf.f_choice = LDAP_FILTER_LE;
cf.f_av_value = srs->sr_state.ctxcsn;
fop.ors_filterstr.bv_len = sprintf( buf, "(entryCSN<=%s)",
cf.f_av_value.bv_val );
/* Look for exact match the first time */
if ( findcsn_retry ) {
cf.f_choice = LDAP_FILTER_EQUALITY;
fop.ors_filterstr.bv_len = sprintf( buf, "(entryCSN=%s)",
cf.f_av_value.bv_val );
/* On retry, look for <= */
} else {
cf.f_choice = LDAP_FILTER_LE;
fop.ors_filterstr.bv_len = sprintf( buf, "(entryCSN<=%s)",
cf.f_av_value.bv_val );
}
fop.ors_attrsonly = 1;
fop.ors_attrs = slap_anlist_no_attrs;
fop.ors_slimit = 1;
@ -646,7 +656,14 @@ syncprov_findcsn( Operation *op, int mode )
break;
case FIND_CSN:
/* If matching CSN was not found, invalidate the context. */
if ( !cb.sc_private ) rc = LDAP_NO_SUCH_OBJECT;
if ( !cb.sc_private ) {
/* If we didn't find an exact match, then try for <= */
if ( findcsn_retry ) {
findcsn_retry = 0;
goto again;
}
rc = LDAP_NO_SUCH_OBJECT;
}
break;
case FIND_PRESENT:
op->o_tmpfree( pcookie.uuids, op->o_tmpmemctx );
@ -1592,6 +1609,8 @@ typedef struct searchstate {
slap_overinst *ss_on;
syncops *ss_so;
int ss_present;
struct berval ss_ctxcsn;
char ss_csnbuf[LDAP_LUTIL_CSNSTR_BUFSIZE];
} searchstate;
static int
@ -1690,6 +1709,7 @@ syncprov_search_response( Operation *op, SlapReply *rs )
sync_control *srs = op->o_controls[slap_cids.sc_LDAPsync];
if ( rs->sr_type == REP_SEARCH || rs->sr_type == REP_SEARCHREF ) {
Attribute *a;
/* If we got a referral without a referral object, there's
* something missing that we cannot replicate. Just ignore it.
* The consumer will abort because we didn't send the expected
@ -1700,12 +1720,15 @@ syncprov_search_response( Operation *op, SlapReply *rs )
Debug( LDAP_DEBUG_ANY, "bogus referral in context\n",0,0,0 );
return SLAP_CB_CONTINUE;
}
if ( !BER_BVISNULL( &srs->sr_state.ctxcsn )) {
Attribute *a = attr_find( rs->sr_entry->e_attrs,
slap_schema.si_ad_entryCSN );
a = attr_find( rs->sr_entry->e_attrs, slap_schema.si_ad_entryCSN );
if ( a ) {
/* Make sure entry is less than the snaphot'd contextCSN */
if ( ber_bvcmp( &a->a_nvals[0], &ss->ss_ctxcsn ) > 0 )
return LDAP_SUCCESS;
/* Don't send the ctx entry twice */
if ( a && bvmatch( &a->a_nvals[0], &srs->sr_state.ctxcsn ) )
if ( !BER_BVISNULL( &srs->sr_state.ctxcsn ) &&
bvmatch( &a->a_nvals[0], &srs->sr_state.ctxcsn ) )
return LDAP_SUCCESS;
}
rs->sr_ctrls = op->o_tmpalloc( sizeof(LDAPControl *)*2,
@ -1716,8 +1739,7 @@ syncprov_search_response( Operation *op, SlapReply *rs )
} else if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS ) {
struct berval cookie;
slap_compose_sync_cookie( op, &cookie,
&op->ors_filter->f_and->f_ava->aa_value,
slap_compose_sync_cookie( op, &cookie, &ss->ss_ctxcsn,
srs->sr_state.rid );
/* Is this a regular refresh? */
@ -1763,7 +1785,6 @@ syncprov_op_search( Operation *op, SlapReply *rs )
syncprov_info_t *si = (syncprov_info_t *)on->on_bi.bi_private;
slap_callback *cb;
int gotstate = 0, nochange = 0, do_present = 1;
Filter *fand, *fava;
syncops *sop = NULL;
searchstate *ss;
sync_control *srs;
@ -1887,21 +1908,15 @@ shortcut:
sop->s_filterstr= op->ors_filterstr;
}
fand = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );
fand->f_choice = LDAP_FILTER_AND;
fand->f_next = NULL;
fava = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );
fava->f_choice = LDAP_FILTER_LE;
fava->f_ava = op->o_tmpalloc( sizeof(AttributeAssertion), op->o_tmpmemctx );
fava->f_ava->aa_desc = slap_schema.si_ad_entryCSN;
#ifdef LDAP_COMP_MATCH
fava->f_ava->aa_cf = NULL;
#endif
ber_dupbv_x( &fava->f_ava->aa_value, &ctxcsn, op->o_tmpmemctx );
fand->f_and = fava;
if ( gotstate ) {
fava->f_next = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );
fava = fava->f_next;
/* If something changed, find the changes */
if ( gotstate && !nochange ) {
Filter *fand, *fava;
fand = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );
fand->f_choice = LDAP_FILTER_AND;
fand->f_next = NULL;
fava = op->o_tmpalloc( sizeof(Filter), op->o_tmpmemctx );
fand->f_and = fava;
fava->f_choice = LDAP_FILTER_GE;
fava->f_ava = op->o_tmpalloc( sizeof(AttributeAssertion), op->o_tmpmemctx );
fava->f_ava->aa_desc = slap_schema.si_ad_entryCSN;
@ -1909,10 +1924,10 @@ shortcut:
fava->f_ava->aa_cf = NULL;
#endif
ber_dupbv_x( &fava->f_ava->aa_value, &srs->sr_state.ctxcsn, op->o_tmpmemctx );
fava->f_next = op->ors_filter;
op->ors_filter = fand;
filter2bv_x( op, op->ors_filter, &op->ors_filterstr );
}
fava->f_next = op->ors_filter;
op->ors_filter = fand;
filter2bv_x( op, op->ors_filter, &op->ors_filterstr );
/* Let our callback add needed info to returned entries */
cb = op->o_tmpcalloc(1, sizeof(slap_callback)+sizeof(searchstate), op->o_tmpmemctx);
@ -1920,6 +1935,9 @@ shortcut:
ss->ss_on = on;
ss->ss_so = sop;
ss->ss_present = do_present;
ss->ss_ctxcsn.bv_len = ctxcsn.bv_len;
ss->ss_ctxcsn.bv_val = ss->ss_csnbuf;
strcpy( ss->ss_ctxcsn.bv_val, ctxcsn.bv_val );
cb->sc_response = syncprov_search_response;
cb->sc_cleanup = syncprov_search_cleanup;
cb->sc_private = ss;
@ -2000,7 +2018,7 @@ static ConfigTable spcfg[] = {
sp_cf_gen, "( OLcfgOvAt:1.1 NAME 'olcSpCheckpoint' "
"DESC 'ContextCSN checkpoint interval in ops and minutes' "
"SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
{ "syncprov-sessionlog", "size", 2, 2, 0, ARG_INT|ARG_MAGIC|SP_SESSL,
{ "syncprov-sessionlog", "ops", 2, 2, 0, ARG_INT|ARG_MAGIC|SP_SESSL,
sp_cf_gen, "( OLcfgOvAt:1.2 NAME 'olcSpSessionlog' "
"DESC 'Session log size in ops' "
"SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL },

View File

@ -62,6 +62,8 @@ int passwd_extop(
assert( ber_bvcmp( &slap_EXOP_MODIFY_PASSWD, &op->ore_reqoid ) == 0 );
if( op->o_dn.bv_len == 0 ) {
Statslog( LDAP_DEBUG_STATS, "%s PASSMOD\n",
op->o_log_prefix, 0, 0, 0, 0 );
rs->sr_text = "only authenticated users may change passwords";
return LDAP_STRONG_AUTH_REQUIRED;
}
@ -74,6 +76,16 @@ int passwd_extop(
rs->sr_err = slap_passwd_parse( op->ore_reqdata, &id, &qpw->rs_old,
&qpw->rs_new, &rs->sr_text );
if ( rs->sr_err == LDAP_SUCCESS && !BER_BVISEMPTY( &id ) ) {
Statslog( LDAP_DEBUG_STATS, "%s PASSMOD id=\"%s\"%s%s\n",
op->o_log_prefix, id.bv_val,
qpw->rs_old.bv_val ? " old" : "",
qpw->rs_new.bv_val ? " new" : "", 0 );
} else {
Statslog( LDAP_DEBUG_STATS, "%s PASSMOD\n",
op->o_log_prefix, 0, 0, 0, 0 );
}
if ( rs->sr_err != LDAP_SUCCESS ) {
return rs->sr_err;
}

View File

@ -31,6 +31,30 @@
LDAP_BEGIN_DECL
/*
* aci.c
*/
#ifdef SLAPD_ACI_ENABLED
LDAP_SLAPD_F (int) aci_mask LDAP_P((
Operation *op, Entry *e,
AttributeDescription *desc,
struct berval *val,
struct berval *aci,
int nmatch,
regmatch_t *matches,
slap_access_t *grant,
slap_access_t *deny,
slap_aci_scope_t scope));
LDAP_SLAPD_F (int) OpenLDAPaciValidate LDAP_P((
Syntax *syn, struct berval *in ));
LDAP_SLAPD_F (int) OpenLDAPaciPretty LDAP_P((
Syntax *syn, struct berval *val, struct berval *out, void *ctx ));
LDAP_SLAPD_F (slap_mr_normalize_func) OpenLDAPaciNormalize;
#ifdef SLAP_DYNACL
LDAP_SLAPD_F (int) dynacl_aci_init LDAP_P(( void ));
#endif /* SLAP_DYNACL */
#endif /* SLAPD_ACI_ENABLED */
/*
* acl.c
*/
@ -71,6 +95,22 @@ LDAP_SLAPD_F (slap_dynacl_t *) slap_dynacl_get LDAP_P(( const char *name ));
#endif /* SLAP_DYNACL */
LDAP_SLAPD_F (int) acl_init LDAP_P(( void ));
LDAP_SLAPD_V (const struct berval) aci_bv[];
LDAP_SLAPD_F (int) acl_get_part LDAP_P((
struct berval *list,
int ix,
char sep,
struct berval *bv ));
LDAP_SLAPD_F (int) acl_match_set LDAP_P((
struct berval *subj,
Operation *op,
Entry *e,
int setref ));
LDAP_SLAPD_F (int) acl_string_expand LDAP_P((
struct berval *newbuf, struct berval *pattern,
char *match, int nmatch, regmatch_t *matches ));
/*
* aclparse.c
*/
@ -577,7 +617,8 @@ LDAP_SLAPD_F (long) connection_init LDAP_P((
slap_ssf_t ssf,
struct berval *id ));
LDAP_SLAPD_F (void) connection_closing LDAP_P(( Connection *c ));
LDAP_SLAPD_F (void) connection_closing LDAP_P((
Connection *c, const char *why ));
LDAP_SLAPD_F (int) connection_state_closing LDAP_P(( Connection *c ));
LDAP_SLAPD_F (const char *) connection_state2str LDAP_P(( int state ))
LDAP_GCCATTR((const));
@ -1406,7 +1447,9 @@ LDAP_SLAPD_F (void) schema_destroy LDAP_P(( void ));
LDAP_SLAPD_F( slap_mr_indexer_func ) octetStringIndexer;
LDAP_SLAPD_F( slap_mr_filter_func ) octetStringFilter;
LDAP_SLAPD_F( int ) numericoidValidate LDAP_P((
struct slap_syntax *syntax,
struct berval *in ));
/*
* schema_prep.c

View File

@ -189,7 +189,7 @@ static long send_ldap_ber(
err, sock_errstr(err), 0 );
if ( err != EWOULDBLOCK && err != EAGAIN ) {
connection_closing( conn );
connection_closing( conn, "connection lost on write" );
ldap_pvt_thread_mutex_unlock( &conn->c_mutex );
ldap_pvt_thread_mutex_unlock( &conn->c_write_mutex );
@ -613,7 +613,12 @@ send_ldap_sasl( Operation *op, SlapReply *rs )
rs->sr_tag = req2res( op->o_tag );
rs->sr_msgid = (rs->sr_tag != LBER_SEQUENCE) ? op->o_msgid : 0;
send_ldap_response( op, rs );
if ( send_ldap_response( op, rs ) == SLAP_CB_CONTINUE ) {
Statslog( LDAP_DEBUG_STATS,
"%s RESULT tag=%lu err=%d text=%s\n",
op->o_log_prefix, rs->sr_tag, rs->sr_err,
rs->sr_text ? rs->sr_text : "", 0 );
}
}
void
@ -630,7 +635,12 @@ slap_send_ldap_extended( Operation *op, SlapReply *rs )
rs->sr_tag = req2res( op->o_tag );
rs->sr_msgid = (rs->sr_tag != LBER_SEQUENCE) ? op->o_msgid : 0;
send_ldap_response( op, rs );
if ( send_ldap_response( op, rs ) == SLAP_CB_CONTINUE ) {
Statslog( LDAP_DEBUG_STATS,
"%s RESULT oid=%s err=%d text=%s\n",
op->o_log_prefix, rs->sr_rspoid ? rs->sr_rspoid : "",
rs->sr_err, rs->sr_text ? rs->sr_text : "", 0 );
}
}
void
@ -644,7 +654,12 @@ slap_send_ldap_intermediate( Operation *op, SlapReply *rs )
rs->sr_rspdata != NULL ? rs->sr_rspdata->bv_len : 0 );
rs->sr_tag = LDAP_RES_INTERMEDIATE;
rs->sr_msgid = op->o_msgid;
send_ldap_response( op, rs );
if ( send_ldap_response( op, rs ) == SLAP_CB_CONTINUE ) {
Statslog( LDAP_DEBUG_STATS2,
"%s INTERM oid=%s\n",
op->o_log_prefix,
rs->sr_rspoid ? rs->sr_rspoid : "", 0, 0, 0 );
}
}
int

View File

@ -202,6 +202,14 @@ sasl_ap_lookup( Operation *op, SlapReply *rs )
"slap_ap_lookup: str2ad(%s): %s\n", name, text, 0 );
continue;
}
/* If it's the rootdn and a rootpw was present, we already set
* it so don't override it here.
*/
if ( ad == slap_schema.si_ad_userPassword && sl->list[i].values &&
be_isroot_dn( op->o_bd, &op->o_req_ndn ))
continue;
a = attr_find( rs->sr_entry->e_attrs, ad );
if ( !a ) continue;
if ( ! access_allowed( op, rs->sr_entry, ad, NULL, ACL_AUTH, NULL ) ) {
@ -318,26 +326,69 @@ slap_auxprop_lookup(
op.o_bd = select_backend( &op.o_req_ndn, 0, 1 );
if ( op.o_bd && op.o_bd->be_search ) {
SlapReply rs = {REP_RESULT};
op.o_hdr = conn->c_sasl_bindop->o_hdr;
op.o_tag = LDAP_REQ_SEARCH;
op.o_ndn = conn->c_ndn;
op.o_callback = &cb;
op.o_time = slap_get_time();
op.o_do_not_cache = 1;
op.o_is_auth_check = 1;
op.o_req_dn = op.o_req_ndn;
op.ors_scope = LDAP_SCOPE_BASE;
op.ors_deref = LDAP_DEREF_NEVER;
op.ors_tlimit = SLAP_NO_LIMIT;
op.ors_slimit = 1;
op.ors_filter = &generic_filter;
op.ors_filterstr = generic_filterstr;
/* FIXME: we want all attributes, right? */
op.ors_attrs = NULL;
if ( op.o_bd ) {
/* For rootdn, see if we can use the rootpw */
if ( be_isroot_dn( op.o_bd, &op.o_req_ndn ) &&
!BER_BVISEMPTY( &op.o_bd->be_rootpw )) {
struct berval cbv = BER_BVNULL;
op.o_bd->be_search( &op, &rs );
/* If there's a recognized scheme, see if it's CLEARTEXT */
if ( lutil_passwd_scheme( op.o_bd->be_rootpw.bv_val )) {
if ( !strncasecmp( op.o_bd->be_rootpw.bv_val,
sc_cleartext.bv_val, sc_cleartext.bv_len )) {
/* If it's CLEARTEXT, skip past scheme spec */
cbv.bv_len = op.o_bd->be_rootpw.bv_len -
sc_cleartext.bv_len;
if ( cbv.bv_len ) {
cbv.bv_val = op.o_bd->be_rootpw.bv_val +
sc_cleartext.bv_len;
}
}
/* No scheme, use the whole value */
} else {
cbv = op.o_bd->be_rootpw;
}
if ( !BER_BVISEMPTY( &cbv )) {
for( i = 0; sl.list[i].name; i++ ) {
const char *name = sl.list[i].name;
if ( name[0] == '*' ) {
if ( flags & SASL_AUXPROP_AUTHZID ) continue;
name++;
} else if ( !(flags & SASL_AUXPROP_AUTHZID ) )
continue;
if ( !strcasecmp(name,"userPassword") ) {
sl.sparams->utils->prop_set( sl.sparams->propctx,
sl.list[i].name, cbv.bv_val, cbv.bv_len );
break;
}
}
}
}
if ( op.o_bd->be_search ) {
SlapReply rs = {REP_RESULT};
op.o_hdr = conn->c_sasl_bindop->o_hdr;
op.o_tag = LDAP_REQ_SEARCH;
op.o_ndn = conn->c_ndn;
op.o_callback = &cb;
op.o_time = slap_get_time();
op.o_do_not_cache = 1;
op.o_is_auth_check = 1;
op.o_req_dn = op.o_req_ndn;
op.ors_scope = LDAP_SCOPE_BASE;
op.ors_deref = LDAP_DEREF_NEVER;
op.ors_tlimit = SLAP_NO_LIMIT;
op.ors_slimit = 1;
op.ors_filter = &generic_filter;
op.ors_filterstr = generic_filterstr;
/* FIXME: we want all attributes, right? */
op.ors_attrs = NULL;
op.o_bd->be_search( &op, &rs );
}
}
}
}

View File

@ -452,7 +452,7 @@ is_dn: bv.bv_len = in->bv_len - ( bv.bv_val - in->bv_val );
}
/* Grab the searchbase */
assert( ludp->lud_dn );
assert( ludp->lud_dn != NULL );
ber_str2bv( ludp->lud_dn, 0, 0, &bv );
rc = dnValidate( NULL, &bv );
@ -830,7 +830,7 @@ is_dn: bv.bv_len = val->bv_len - ( bv.bv_val - val->bv_val );
}
/* Grab the searchbase */
assert( ludp->lud_dn );
assert( ludp->lud_dn != NULL );
if ( ludp->lud_dn ) {
struct berval out = BER_BVNULL;

View File

@ -172,7 +172,7 @@ objectclass ( 1.3.6.1.1.1.2.1 NAME 'shadowAccount'
objectclass ( 1.3.6.1.1.1.2.2 NAME 'posixGroup'
DESC 'Abstraction of a group of accounts'
SUP top AUXILIARY
SUP top STRUCTURAL
MUST ( cn $ gidNumber )
MAY ( userPassword $ memberUid $ description ) )

View File

@ -50,7 +50,7 @@
#define HASH_Update(c,buf,len) lutil_HASHUpdate(c,buf,len)
#define HASH_Final(d,c) lutil_HASHFinal(d,c)
#define OpenLDAPaciMatch NULL
#define OpenLDAPaciMatch octetStringMatch
/* approx matching rules */
#define directoryStringApproxMatchOID "1.3.6.1.4.1.4203.666.4.4"
@ -1861,7 +1861,7 @@ telephoneNumberNormalize(
return LDAP_SUCCESS;
}
static int
int
numericoidValidate(
Syntax *syntax,
struct berval *in )
@ -3427,8 +3427,8 @@ static slap_syntax_defs_rec syntax_defs[] = {
/* OpenLDAP Experimental Syntaxes */
{"( 1.3.6.1.4.1.4203.666.2.1 DESC 'OpenLDAP Experimental ACI' )",
SLAP_SYNTAX_HIDE,
UTF8StringValidate /* THIS WILL CHANGE FOR NEW ACI SYNTAX */,
NULL},
OpenLDAPaciValidate,
OpenLDAPaciPretty},
#endif
#ifdef SLAPD_AUTHPASSWD
@ -3851,7 +3851,7 @@ static slap_mrule_defs_rec mrule_defs[] = {
{"( 1.3.6.1.4.1.4203.666.4.2 NAME 'OpenLDAPaciMatch' "
"SYNTAX 1.3.6.1.4.1.4203.666.2.1 )",
SLAP_MR_HIDE | SLAP_MR_EQUALITY, NULL,
NULL, NULL, OpenLDAPaciMatch,
NULL, OpenLDAPaciNormalize, OpenLDAPaciMatch,
NULL, NULL,
NULL},
#endif

View File

@ -914,7 +914,7 @@ struct slap_internal_schema {
#endif
AttributeDescription *si_ad_description;
AttributeDescription *si_ad_seeAlso;
/* Undefined Attribute Type */
AttributeType *si_at_undefined;
@ -1481,6 +1481,53 @@ typedef struct slap_acl_state {
#define ACL_STATE_INIT { ACL_STATE_NOT_RECORDED, NULL, NULL, 0UL, \
{ { 0, 0 } }, 0, NULL, 0, 0, NULL }
#ifdef SLAPD_ACI_ENABLED
typedef enum slap_aci_scope_t {
SLAP_ACI_SCOPE_ENTRY = 0x1,
SLAP_ACI_SCOPE_CHILDREN = 0x2,
SLAP_ACI_SCOPE_SUBTREE = ( SLAP_ACI_SCOPE_ENTRY | SLAP_ACI_SCOPE_CHILDREN )
} slap_aci_scope_t;
#endif /* SLAPD_ACI_ENABLED */
enum {
ACI_BV_ENTRY,
ACI_BV_CHILDREN,
ACI_BV_ONELEVEL,
ACI_BV_SUBTREE,
ACI_BV_BR_ENTRY,
ACI_BV_BR_ALL,
ACI_BV_ACCESS_ID,
#if 0
ACI_BV_ANONYMOUS = BER_BVC("anonymous"),
#endif
ACI_BV_PUBLIC,
ACI_BV_USERS,
ACI_BV_SELF,
ACI_BV_DNATTR,
ACI_BV_GROUP,
ACI_BV_ROLE,
ACI_BV_SET,
ACI_BV_SET_REF,
ACI_BV_GRANT,
ACI_BV_DENY,
ACI_BV_IP_EQ,
#ifdef LDAP_PF_LOCAL
ACI_BV_PATH_EQ,
#if 0
ACI_BV_DIRSEP,
#endif
#endif /* LDAP_PF_LOCAL */
ACI_BV_GROUP_CLASS,
ACI_BV_GROUP_ATTR,
ACI_BV_ROLE_CLASS,
ACI_BV_ROLE_ATTR,
ACI_BV_SET_ATTR,
ACI_BV_LAST
};
/*
* Backend-info
* represents a backend
@ -2535,6 +2582,7 @@ typedef struct slap_conn {
int c_struct_state; /* structure management state */
int c_conn_state; /* connection state */
int c_conn_idx; /* slot in connections array */
const char *c_close_reason; /* why connection is closing */
ldap_pvt_thread_mutex_t c_mutex; /* protect the connection */
Sockbuf *c_sb; /* ber connection stuff */

View File

@ -277,6 +277,7 @@ pblock_get_param_class( int param )
case SLAPI_X_GROUP_ATTRIBUTE:
case SLAPI_X_GROUP_OPERATION_DN:
case SLAPI_X_GROUP_TARGET_ENTRY:
case SLAPI_X_ADD_STRUCTURAL_CLASS:
case SLAPI_PLUGIN_AUDIT_DATA:
case SLAPI_IBM_PBLOCK:
case SLAPI_PLUGIN_VERSION:
@ -472,6 +473,20 @@ pblock_get( Slapi_PBlock *pb, int param, void **value )
PBLOCK_ASSERT_OP( pb, 0 );
*((int *)value) = get_no_schema_check( pb->pb_op );
break;
case SLAPI_X_ADD_STRUCTURAL_CLASS:
PBLOCK_ASSERT_OP( pb, 0 );
if ( pb->pb_op->o_tag == LDAP_REQ_ADD ) {
struct berval tmpval = BER_BVNULL;
rc = mods_structural_class( pb->pb_op->ora_modlist,
&tmpval, &pb->pb_rs->sr_text,
pb->pb_textbuf, sizeof( pb->pb_textbuf ));
*((char **)value) = tmpval.bv_val;
} else {
rc = PBLOCK_ERROR;
}
break;
case SLAPI_REQCONTROLS:
PBLOCK_ASSERT_OP( pb, 0 );
*((LDAPControl ***)value) = pb->pb_op->o_ctrls;
@ -1203,6 +1218,7 @@ pblock_set( Slapi_PBlock *pb, int param, void *value )
case SLAPI_X_CONN_CLIENTPATH:
case SLAPI_CONN_SERVERIP:
case SLAPI_X_CONN_SERVERPATH:
case SLAPI_X_ADD_STRUCTURAL_CLASS:
/* These parameters cannot be set */
rc = PBLOCK_ERROR;
break;

View File

@ -27,6 +27,9 @@ starttls_extop ( Operation *op, SlapReply *rs )
{
int rc;
Statslog( LDAP_DEBUG_STATS, "%s STARTTLS\n",
op->o_log_prefix, 0, 0, 0, 0 );
if ( op->ore_reqdata != NULL ) {
/* no request data should be provided */
rs->sr_text = "no request data expected";

View File

@ -291,9 +291,17 @@ retry:;
rc = ldap_bind_s( ld, manager, passwd, LDAP_AUTH_SIMPLE );
if ( rc != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_bind" );
if ( rc == LDAP_BUSY && do_retry > 0 ) {
do_retry--;
goto retry;
switch ( rc ) {
case LDAP_BUSY:
case LDAP_UNAVAILABLE:
if ( do_retry == 1 ) {
do_retry = 0;
sleep( 1 );
goto retry;
}
/* fallthru */
default:
break;
}
exit( EXIT_FAILURE );
}

View File

@ -185,9 +185,17 @@ retry:;
rc = ldap_bind_s( ld, manager, passwd, LDAP_AUTH_SIMPLE );
if ( rc != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_bind" );
if ( rc == LDAP_BUSY && do_retry > 0 ) {
do_retry--;
goto retry;
switch ( rc ) {
case LDAP_BUSY:
case LDAP_UNAVAILABLE:
if ( do_retry == 1 ) {
do_retry = 0;
sleep( 1 );
goto retry;
}
/* fallthru */
default:
break;
}
exit( EXIT_FAILURE );
}

View File

@ -177,9 +177,17 @@ retry:;
rc = ldap_bind_s( ld, manager, passwd, LDAP_AUTH_SIMPLE );
if ( rc != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_bind" );
if ( rc == LDAP_BUSY && do_retry > 0 ) {
do_retry--;
goto retry;
switch ( rc ) {
case LDAP_BUSY:
case LDAP_UNAVAILABLE:
if ( do_retry == 1 ) {
do_retry = 0;
sleep( 1 );
goto retry;
}
/* fallthru */
default:
break;
}
exit( EXIT_FAILURE );
}

View File

@ -140,9 +140,17 @@ retry:;
rc = ldap_bind_s( ld, NULL, NULL, LDAP_AUTH_SIMPLE );
if ( rc != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_bind" );
if ( rc == LDAP_BUSY && do_retry > 0 ) {
do_retry--;
goto retry;
switch ( rc ) {
case LDAP_BUSY:
case LDAP_UNAVAILABLE:
if ( do_retry == 1 ) {
do_retry = 0;
sleep( 1 );
goto retry;
}
/* fallthru */
default:
break;
}
exit( EXIT_FAILURE );
}

View File

@ -157,11 +157,19 @@ retry:;
rc = ldap_bind_s( ld, manager, passwd, LDAP_AUTH_SIMPLE );
if ( rc != LDAP_SUCCESS ) {
if ( rc == LDAP_BUSY && do_retry == 1 ) {
do_retry = 0;
goto retry;
}
ldap_perror( ld, "ldap_bind" );
switch ( rc ) {
case LDAP_BUSY:
case LDAP_UNAVAILABLE:
if ( do_retry > 0 ) {
do_retry--;
sleep( 1 );
goto retry;
}
/* fallthru */
default:
break;
}
exit( EXIT_FAILURE );
}
@ -172,8 +180,8 @@ retry:;
filter, attrs, 0, &res );
if ( rc != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_search" );
if ( rc == LDAP_BUSY && do_retry == 1 ) {
do_retry = 0;
if ( rc == LDAP_BUSY && do_retry > 0 ) {
do_retry--;
goto retry;
}
if ( rc != LDAP_NO_SUCH_OBJECT ) break;

View File

@ -71,7 +71,17 @@ static char argbuf[BUFSIZ];
static void
usage( char *name )
{
fprintf( stderr, "usage: %s -H <uri> | ([-h <host>] -p <port>) -D <manager> -w <passwd> -d <datadir> [-j <maxchild>] [-l <loops>] -P <progdir>\n", name );
fprintf( stderr,
"usage: %s "
"-H <uri> | ([-h <host>] -p <port>) "
"-D <manager> "
"-w <passwd> "
"-d <datadir> "
"[-j <maxchild>] "
"[-l <loops>] "
"-P <progdir> "
"[-r <maxretries>]\n",
name );
exit( EXIT_FAILURE );
}