mirror of
https://git.openldap.org/openldap/openldap.git
synced 2025-01-30 13:30:57 +08:00
Sync with HEAD
This commit is contained in:
parent
b2da42b873
commit
01fbca5974
36
contrib/slapd-modules/acl/README
Normal file
36
contrib/slapd-modules/acl/README
Normal 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.
|
||||
|
320
contrib/slapd-modules/acl/posixgroup.c
Normal file
320
contrib/slapd-modules/acl/posixgroup.c
Normal 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 */
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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"
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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
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
@ -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 );
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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 );
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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 );
|
||||
|
@ -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 ) )
|
||||
{
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 ) {
|
||||
|
@ -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 );
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 ) {
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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 },
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 ) )
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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";
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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 );
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user