Commit fbcb9174 authored by Robert Dubner's avatar Robert Dubner
Browse files

Merge branch 'master' into bobdev

parents a5cd3559 9b03a1ec
......@@ -4,71 +4,3 @@
H1: Changes Since Previous Release
The following sections attempt to summarize the new features and changes in OpenLDAP
software since the 2.4.x release and the OpenLDAP Admin Guide.
H2: New Guide Sections
In order to make the Admin Guide more thorough and cover the majority of questions
asked on the OpenLDAP mailing lists and scenarios discussed there, we have added the following new sections:
* {{SECT:When should I use LDAP?}}
* {{SECT:When should I not use LDAP?}}
* {{SECT:LDAP vs RDBMS}}
* {{SECT:Access Control}}
* {{SECT:Backends}}
* {{SECT:Overlays}}
* {{SECT:Replication}}
* {{SECT:Maintenance}}
* {{SECT:Monitoring}}
* {{SECT:Tuning}}
* {{SECT:Troubleshooting}}
* {{SECT:Changes Since Previous Release}}
* {{SECT:Upgrading from 2.4.x}}
* {{SECT:Common errors encountered when using OpenLDAP Software}}
* {{SECT:Recommended OpenLDAP Software Dependency Versions}}
* {{SECT:Real World OpenLDAP Deployments and Examples}}
* {{SECT:OpenLDAP Software Contributions}}
* {{SECT:Configuration File Examples}}
* {{SECT:LDAP Result Codes}}
* {{SECT:Glossary}}
Also, the table of contents is now 3 levels deep to ease navigation.
H2: New Features and Enhancements in 2.5
H3: Better {{B:cn=config}} functionality
H3: Better {{B:cn=schema}} functionality
H3: More sophisticated Syncrepl configurations
H3: Replicating {{slapd}} Configuration (syncrepl and {{B:cn=config}})
H3: More extensive TLS configuration control
H3: Performance enhancements
H3: New overlays
H3: New features in existing Overlays
H3: New features in slapd
H3: New features in libldap
H3: New clients, tools and tool enhancements
H3: New build options
H2: Obsolete Features Removed From 2.5
These features were strongly deprecated in 2.4 and removed in 2.5.
H3: back-bdb and back-hdb
back-bdb and back-hdb were significantly slower than back-mdb and
required significant tuning of multiple parameters to maximize
performance. back-mdb requires no tuning and provides all the
functionality previously provided via back-bdb and back-hdb.
......@@ -6,14 +6,14 @@
# Preamble for all OpenLDAP SDF documents
#
!default VERSION 2.5
!default VERSION 2.X
#
# Paths are relative to the main subdirectories
#
!define DOC_AUTHOR "The OpenLDAP Project <{{URL:https://www.openldap.org/}}>"
!define DOC_NAME "OpenLDAP Software 2.5"
!define DOC_NAME "OpenLDAP Software 2.X"
!define DOC_TYPE "Guide"
!define DOC_LOGO "../images/LDAPlogo.gif"
......
......@@ -23,7 +23,7 @@ NT_OBJS = ../slapd/nt_svc.o ../../libraries/liblutil/slapdmsg.res
SRCS += main.c value.c \
../slapd/ch_malloc.c ../slapd/logging.c ../slapd/proxyp.c \
../slapd/sl_malloc.c ../slapd/user.c
../slapd/sl_malloc.c ../slapd/user.c ../slapd/verbs.c
OBJS = $(patsubst %.c,%.o,$(SRCS)) $(@PLAT@_OBJS)
......
......@@ -46,6 +46,7 @@
#include "lutil.h"
#include "lutil_ldap.h"
#include "lload-config.h"
#include "../slapd/slap-cfglog.h"
#ifdef _WIN32
#define LUTIL_ATOULX lutil_atoullx
......@@ -121,7 +122,6 @@ static ConfigDriver config_restrict_oid;
static ConfigDriver config_tcp_buffer;
#endif /* LDAP_TCP_BUFFER */
static ConfigDriver config_restrict;
static ConfigDriver config_loglevel;
static ConfigDriver config_include;
static ConfigDriver config_feature;
#ifdef HAVE_TLS
......@@ -156,9 +156,6 @@ enum {
CFG_TLS_SHARE_CTX,
CFG_CONCUR,
CFG_THREADS,
CFG_LOGFILE,
CFG_LOGFILE_ONLY,
CFG_LOGFILE_ROTATE,
CFG_MIRRORMODE,
CFG_IOTHREADS,
CFG_MAXBUF_CLIENT,
......@@ -291,22 +288,22 @@ static ConfigTable config_back_cf_table[] = {
#endif /* BALANCER_MODULE */
{ "logfile", "file", 2, 2, 0,
ARG_STRING|ARG_MAGIC|CFG_LOGFILE,
&config_generic,
&config_logging,
NULL, NULL, NULL
},
{ "logfile-only", "on|off", 2, 2, 0,
ARG_ON_OFF|ARG_MAGIC|CFG_LOGFILE_ONLY,
&config_generic,
&config_logging,
NULL, NULL, NULL
},
{ "logfile-rotate", "max> <Mbyte> <hours", 4, 4, 0,
ARG_MAGIC|CFG_LOGFILE_ROTATE,
&config_generic,
&config_logging,
NULL, NULL, NULL
},
{ "loglevel", "level", 2, 0, 0,
ARG_MAGIC,
&config_loglevel,
ARG_MAGIC|CFG_LOGLEVEL,
&config_logging,
NULL, NULL, NULL
},
{ "pidfile", "file", 2, 2, 0,
......@@ -1039,60 +1036,6 @@ config_generic( ConfigArgs *c )
}
} break;
case CFG_LOGFILE: {
int rc = logfile_open( c->value_string );
ch_free( c->value_string );
return rc;
} break;
case CFG_LOGFILE_ONLY:
slap_debug = slap_debug_orig;
if ( c->value_int ) {
slap_debug |= config_syslog;
ldap_syslog = 0;
} else {
ldap_syslog = config_syslog;
}
logfile_only = c->value_int;
break;
case CFG_LOGFILE_ROTATE: {
unsigned lf_max, lf_mbyte, lf_hour;
if ( lutil_atoux( &lf_max, c->argv[1], 0 ) != 0 ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> "
"invalid max value \"%s\"",
c->argv[0], c->argv[1] );
goto fail;
}
if ( !lf_max || lf_max > 99 ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> "
"invalid max value \"%s\" must be 1-99",
c->argv[0], c->argv[1] );
goto fail;
}
if ( lutil_atoux( &lf_mbyte, c->argv[2], 0 ) != 0 ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> "
"invalid Mbyte value \"%s\"",
c->argv[0], c->argv[2] );
goto fail;
}
if ( lutil_atoux( &lf_hour, c->argv[3], 0 ) != 0 ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> "
"invalid hours value \"%s\"",
c->argv[0], c->argv[3] );
goto fail;
}
if ( !lf_mbyte && !lf_hour ) {
snprintf( c->cr_msg, sizeof( c->cr_msg ), "<%s> "
"Mbyte and hours cannot both be zero",
c->argv[0] );
goto fail;
}
logfile_max = lf_max;
logfile_fslimit = lf_mbyte * 1048576; /* Megabytes to bytes */
logfile_age = lf_hour * 3600; /* hours to seconds */
} break;
case CFG_RESCOUNT:
lload_conn_max_pdus_per_cycle = c->value_uint;
break;
......@@ -2033,146 +1976,6 @@ config_restrict( ConfigArgs *c )
return 0;
}
static slap_verbmasks *loglevel_ops;
static int
loglevel_init( void )
{
slap_verbmasks lo[] = {
{ BER_BVC("Any"), (slap_mask_t)LDAP_DEBUG_ANY },
{ BER_BVC("Trace"), LDAP_DEBUG_TRACE },
{ BER_BVC("Packets"), LDAP_DEBUG_PACKETS },
{ BER_BVC("Args"), LDAP_DEBUG_ARGS },
{ BER_BVC("Conns"), LDAP_DEBUG_CONNS },
{ BER_BVC("BER"), LDAP_DEBUG_BER },
{ BER_BVC("Filter"), LDAP_DEBUG_FILTER },
{ BER_BVC("Config"), LDAP_DEBUG_CONFIG },
{ BER_BVC("ACL"), LDAP_DEBUG_ACL },
{ BER_BVC("Stats"), LDAP_DEBUG_STATS },
{ BER_BVC("Stats2"), LDAP_DEBUG_STATS2 },
{ BER_BVC("Shell"), LDAP_DEBUG_SHELL },
{ BER_BVC("Parse"), LDAP_DEBUG_PARSE },
{ BER_BVC("Sync"), LDAP_DEBUG_SYNC },
{ BER_BVC("None"), LDAP_DEBUG_NONE },
{ BER_BVNULL, 0 }
};
return slap_verbmasks_init( &loglevel_ops, lo );
}
static void
loglevel_destroy( void )
{
if ( loglevel_ops ) {
(void)slap_verbmasks_destroy( loglevel_ops );
}
loglevel_ops = NULL;
}
int
str2loglevel( const char *s, int *l )
{
int i;
if ( loglevel_ops == NULL ) {
loglevel_init();
}
i = verb_to_mask( s, loglevel_ops );
if ( BER_BVISNULL( &loglevel_ops[i].word ) ) {
return -1;
}
*l = loglevel_ops[i].mask;
return 0;
}
int
loglevel2bvarray( int l, BerVarray *bva )
{
if ( loglevel_ops == NULL ) {
loglevel_init();
}
if ( l == 0 ) {
struct berval bv = BER_BVC("0");
return value_add_one( bva, &bv );
}
return mask_to_verbs( loglevel_ops, l, bva );
}
int
loglevel_print( FILE *out )
{
int i;
if ( loglevel_ops == NULL ) {
loglevel_init();
}
fprintf( out, "Installed log subsystems:\n\n" );
for ( i = 0; !BER_BVISNULL( &loglevel_ops[i].word ); i++ ) {
unsigned mask = loglevel_ops[i].mask & 0xffffffffUL;
fprintf( out,
( mask == ( (slap_mask_t)-1 & 0xffffffffUL ) ?
"\t%-30s (-1, 0xffffffff)\n" :
"\t%-30s (%u, 0x%x)\n" ),
loglevel_ops[i].word.bv_val, mask, mask );
}
return 0;
}
static int
config_loglevel( ConfigArgs *c )
{
int i;
if ( loglevel_ops == NULL ) {
loglevel_init();
}
for ( i = 1; i < c->argc; i++ ) {
int level;
if ( isdigit( (unsigned char)c->argv[i][0] ) || c->argv[i][0] == '-' ) {
if ( lutil_atoix( &level, c->argv[i], 0 ) != 0 ) {
snprintf( c->cr_msg, sizeof(c->cr_msg),
"<%s> unable to parse level",
c->argv[0] );
Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
c->log, c->cr_msg, c->argv[i] );
return 1;
}
} else {
if ( str2loglevel( c->argv[i], &level ) ) {
snprintf( c->cr_msg, sizeof(c->cr_msg), "<%s> unknown level",
c->argv[0] );
Debug( LDAP_DEBUG_ANY, "%s: %s \"%s\"\n",
c->log, c->cr_msg, c->argv[i] );
return 1;
}
}
/* Explicitly setting a zero clears all the levels */
if ( level )
config_syslog |= level;
else
config_syslog = 0;
}
if ( slapMode & SLAP_SERVER_MODE ) {
if ( logfile_only ) {
slap_debug = slap_debug_orig | config_syslog;
ldap_syslog = 0;
} else {
ldap_syslog = config_syslog;
}
}
return 0;
}
static int
config_include( ConfigArgs *c )
{
......@@ -2894,99 +2697,6 @@ lload_read_config( const char *fname, const char *dir )
return lload_read_config_file( fname, 0, NULL, config_back_cf_table );
}
/* restrictops, allows, disallows, requires, loglevel */
int
bverb_to_mask( struct berval *bword, slap_verbmasks *v )
{
int i;
for ( i = 0; !BER_BVISNULL( &v[i].word ); i++ ) {
if ( !ber_bvstrcasecmp( bword, &v[i].word ) ) break;
}
return i;
}
int
verb_to_mask( const char *word, slap_verbmasks *v )
{
struct berval bword;
ber_str2bv( word, 0, 0, &bword );
return bverb_to_mask( &bword, v );
}
int
verbs_to_mask( int argc, char *argv[], slap_verbmasks *v, slap_mask_t *m )
{
int i, j;
for ( i = 1; i < argc; i++ ) {
j = verb_to_mask( argv[i], v );
if ( BER_BVISNULL( &v[j].word ) ) return i;
while ( !v[j].mask )
j--;
*m |= v[j].mask;
}
return 0;
}
/* Mask keywords that represent multiple bits should occur before single
* bit keywords in the verbmasks array.
*/
int
mask_to_verbs( slap_verbmasks *v, slap_mask_t m, BerVarray *bva )
{
int i, rc = 1;
if ( m ) {
for ( i = 0; !BER_BVISNULL( &v[i].word ); i++ ) {
if ( !v[i].mask ) continue;
if ( (m & v[i].mask) == v[i].mask ) {
value_add_one( bva, &v[i].word );
rc = 0;
m ^= v[i].mask;
if ( !m ) break;
}
}
}
return rc;
}
int
slap_verbmasks_init( slap_verbmasks **vp, slap_verbmasks *v )
{
int i;
assert( *vp == NULL );
for ( i = 0; !BER_BVISNULL( &v[i].word ); i++ ) /* EMPTY */;
*vp = ch_calloc( i + 1, sizeof(slap_verbmasks) );
for ( i = 0; !BER_BVISNULL( &v[i].word ); i++ ) {
ber_dupbv( &(*vp)[i].word, &v[i].word );
*( (slap_mask_t *)&(*vp)[i].mask ) = v[i].mask;
}
BER_BVZERO( &(*vp)[i].word );
return 0;
}
int
slap_verbmasks_destroy( slap_verbmasks *v )
{
int i;
assert( v != NULL );
for ( i = 0; !BER_BVISNULL( &v[i].word ); i++ ) {
ch_free( v[i].word.bv_val );
}
ch_free( v );
return 0;
}
#ifndef BALANCER_MODULE
int
config_push_cleanup( ConfigArgs *ca, ConfigDriver *cleanup )
......@@ -3877,7 +3587,7 @@ lload_config_destroy( void )
free( line );
if ( slapd_args_file ) free( slapd_args_file );
if ( slapd_pid_file ) free( slapd_pid_file );
loglevel_destroy();
slap_loglevel_destroy();
}
/* See if the given URL (in plain and parsed form) matches
......
......@@ -27,7 +27,7 @@ SRCS = main.c globals.c bconfig.c config.c daemon.c \
connection.c search.c filter.c add.c cr.c \
attr.c entry.c backend.c result.c operation.c \
dn.c compare.c modify.c delete.c modrdn.c ch_malloc.c \
value.c ava.c bind.c unbind.c abandon.c filterentry.c \
value.c verbs.c ava.c bind.c unbind.c abandon.c filterentry.c \
phonetic.c acl.c str2filter.c aclparse.c init.c user.c \
lock.c logging.c controls.c extended.c passwd.c proxyp.c \
schema.c schema_check.c schema_init.c schema_prep.c \
......@@ -45,7 +45,7 @@ OBJS = main.o globals.o bconfig.o config.o daemon.o \
connection.o search.o filter.o add.o cr.o \
attr.o entry.o backend.o backends.o result.o operation.o \
dn.o compare.o modify.o delete.o modrdn.o ch_malloc.o \
value.o ava.o bind.o unbind.o abandon.o filterentry.o \
value.o verbs.o ava.o bind.o unbind.o abandon.o filterentry.o \
phonetic.o acl.o str2filter.o aclparse.o init.o user.o \
lock.o logging.o controls.o extended.o passwd.o proxyp.o \
schema.o schema_check.o schema_init.o schema_prep.o \
......
......@@ -138,6 +138,8 @@ typedef struct monitor_info_t {
AttributeDescription *mi_ad_monitorRuntimeConfig;
AttributeDescription *mi_ad_monitorSuperiorDN;
AttributeDescription *mi_ad_monitorConnectionOpsAsync;
AttributeDescription *mi_ad_monitorLogLevel;
AttributeDescription *mi_ad_monitorDebugLevel;
/*
* Generic description attribute
......
......@@ -131,7 +131,7 @@ static struct monitor_subsys_t known_monitor_subsys[] = {
SLAPD_MONITOR_LOG_NAME,
BER_BVNULL, BER_BVNULL, BER_BVNULL,
{ BER_BVC( "This subsystem contains information about logging." ),
BER_BVC( "Set the attribute \"managedInfo\" to the desired log levels." ),
BER_BVC( "Set the \"monitorLogLevel\" or \"monitorDebugLevel\" attributes to the desired levels." ),
BER_BVNULL },
MONITOR_F_NONE,
monitor_subsys_log_init,
......@@ -1940,6 +1940,22 @@ monitor_back_initialize(
"NO-USER-MODIFICATION "
"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
offsetof(monitor_info_t, mi_ad_monitorConnectionOpsAsync) },
{ "( 1.3.6.1.4.1.4203.666.1.55.32 "
"NAME 'monitorLogLevel' "
"DESC 'current slapd log level' "
"EQUALITY caseIgnoreMatch "
"SUBSTR caseIgnoreSubstringsMatch "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 "
"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
offsetof(monitor_info_t, mi_ad_monitorLogLevel) },
{ "( 1.3.6.1.4.1.4203.666.1.55.33 "
"NAME 'monitorDebugLevel' "
"DESC 'current slapd debug level' "
"EQUALITY caseIgnoreMatch "
"SUBSTR caseIgnoreSubstringsMatch "
"SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 "
"USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE,
offsetof(monitor_info_t, mi_ad_monitorDebugLevel) },
{ NULL, 0, -1 }
};
......
......@@ -59,12 +59,10 @@ monitor_subsys_log_init(
BackendDB *be,
monitor_subsys_t *ms )
{
ms->mss_open = monitor_subsys_log_open;
ms->mss_modify = monitor_subsys_log_modify;
ldap_pvt_thread_mutex_init( &monitor_log_mutex );
ms->mss_modify = monitor_subsys_log_modify;
return( 0 );
return monitor_subsys_log_open( be, ms );
}
/*
......@@ -76,14 +74,26 @@ monitor_subsys_log_open(
monitor_subsys_t *ms )
{
BerVarray bva = NULL;
monitor_info_t *mi = ( monitor_info_t * )be->be_private;
Entry *e = NULL;
if ( loglevel2bvarray( ldap_syslog, &bva ) == 0 && bva != NULL ) {
monitor_info_t *mi;
Entry *e;
if ( loglevel2bvarray( slap_debug_get(), &bva ) == 0 && bva != NULL ) {
if ( monitor_cache_get( mi, &ms->mss_ndn, &e ) ) {
Debug( LDAP_DEBUG_ANY,
"monitor_subsys_log_init: "
"unable to get entry \"%s\"\n",
ms->mss_ndn.bv_val );
ber_bvarray_free( bva );
return( -1 );
}
mi = ( monitor_info_t * )be->be_private;
attr_merge_normalize( e, mi->mi_ad_monitorDebugLevel, bva, NULL );
ber_bvarray_free( bva );
bva = NULL;
}
if ( monitor_cache_get( mi, &ms->mss_ndn, &e ) ) {
if ( loglevel2bvarray( slap_syslog_get(), &bva ) == 0 && bva != NULL ) {
if ( !e && monitor_cache_get( mi, &ms->mss_ndn, &e ) ) {
Debug( LDAP_DEBUG_ANY,
"monitor_subsys_log_init: "
"unable to get entry \"%s\"\n",
......@@ -92,11 +102,12 @@ monitor_subsys_log_open(
return( -1 );
}
attr_merge_normalize( e, mi->mi_ad_managedInfo, bva, NULL );
attr_merge_normalize( e, mi->mi_ad_monitorLogLevel, bva, NULL );
ber_bvarray_free( bva );
}
if ( e )
monitor_cache_release( mi, e );
}
return( 0 );
}
......@@ -109,13 +120,16 @@ monitor_subsys_log_modify(
{
monitor_info_t *mi = ( monitor_info_t * )op->o_bd->be_private;
int rc = LDAP_OTHER;
int newlevel = ldap_syslog;
int newdebug, newsyslog, *newptr;
Attribute *save_attrs;
Modifications *modlist = op->orm_modlist;
Modifications *ml;
ldap_pvt_thread_mutex_lock( &monitor_log_mutex );
newdebug = slap_debug_get();
newsyslog = slap_syslog_get();
save_attrs = e->e_attrs;
e->e_attrs = attrs_dup( e->e_attrs );
......@@ -137,24 +151,30 @@ monitor_subsys_log_modify(
continue;
/*
* only the "managedInfo" attribute can be modified
* only the monitorDebugLevel and monitorLogLevel attributes can be modified
*/
} else if ( mod->sm_desc != mi->mi_ad_managedInfo ) {