From d06f5e7c1b6ceaa1f74510c3c25436a58670cfda Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Tue, 21 Oct 2014 13:15:55 +0100 Subject: [PATCH] ITS#8007 Add maxentrysize config option --- doc/man/man5/slapd-mdb.5 | 5 +++++ servers/slapd/back-mdb/add.c | 8 ++++++-- servers/slapd/back-mdb/back-mdb.h | 2 +- servers/slapd/back-mdb/config.c | 21 +++++++++++++++++++-- servers/slapd/back-mdb/id2entry.c | 3 +++ servers/slapd/back-mdb/modify.c | 7 ++++++- servers/slapd/back-mdb/modrdn.c | 8 ++++++-- 7 files changed, 46 insertions(+), 8 deletions(-) diff --git a/doc/man/man5/slapd-mdb.5 b/doc/man/man5/slapd-mdb.5 index 58ba668f81..e6bd6e59ee 100644 --- a/doc/man/man5/slapd-mdb.5 +++ b/doc/man/man5/slapd-mdb.5 @@ -140,6 +140,11 @@ changing \fBindex\fP settings dynamically by LDAPModifying "cn=config" automatically causes rebuilding of the indices online in a background task. .TP +.BI maxentrysize \ +Specify the maximum size of an entry in bytes. Attempts to store +an entry larger than this size will be rejected with the error +LDAP_ADMINLIMIT_EXCEEDED. The default is 0, which is unlimited. +.TP .BI maxreaders \ Specify the maximum number of threads that may have concurrent read access to the database. Tools such as slapcat count as a single thread, diff --git a/servers/slapd/back-mdb/add.c b/servers/slapd/back-mdb/add.c index 36b76453d9..a300974f43 100644 --- a/servers/slapd/back-mdb/add.c +++ b/servers/slapd/back-mdb/add.c @@ -335,8 +335,12 @@ mdb_add(Operation *op, SlapReply *rs ) Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(mdb_add) ": id2entry_add failed\n", 0, 0, 0 ); - rs->sr_err = LDAP_OTHER; - rs->sr_text = "entry store failed"; + if ( rs->sr_err == LDAP_ADMINLIMIT_EXCEEDED ) { + rs->sr_text = "entry is too big"; + } else { + rs->sr_err = LDAP_OTHER; + rs->sr_text = "entry store failed"; + } goto return_results; } diff --git a/servers/slapd/back-mdb/back-mdb.h b/servers/slapd/back-mdb/back-mdb.h index 9d5d4b1960..224f05b912 100644 --- a/servers/slapd/back-mdb/back-mdb.h +++ b/servers/slapd/back-mdb/back-mdb.h @@ -61,13 +61,13 @@ struct mdb_info { MDB_env *mi_dbenv; /* DB_ENV parameters */ - /* The DB_ENV can be tuned via DB_CONFIG */ char *mi_dbenv_home; uint32_t mi_dbenv_flags; int mi_dbenv_mode; size_t mi_mapsize; ID mi_nextid; + size_t mi_maxentrysize; slap_mask_t mi_defaultmask; int mi_nattrs; diff --git a/servers/slapd/back-mdb/config.c b/servers/slapd/back-mdb/config.c index 5b402c55a1..3c05e778b4 100644 --- a/servers/slapd/back-mdb/config.c +++ b/servers/slapd/back-mdb/config.c @@ -39,7 +39,8 @@ enum { MDB_MAXREADERS, MDB_MAXSIZE, MDB_MODE, - MDB_SSTACK + MDB_SSTACK, + MDB_MAXENTSZ }; static ConfigTable mdbcfg[] = { @@ -66,6 +67,10 @@ static ConfigTable mdbcfg[] = { "DESC 'Attribute index parameters' " "EQUALITY caseIgnoreMatch " "SYNTAX OMsDirectoryString )", NULL, NULL }, + { "maxentrysize", "size", 2, 2, 0, ARG_ULONG|ARG_MAGIC|MDB_MAXENTSZ, + mdb_cf_gen, "( OLcfgDbAt:12.3 NAME 'olcDbMaxEntrySize' " + "DESC 'Maximum size of an entry in bytes' " + "SYNTAX OMsInteger SINGLE-VALUE )", NULL, NULL }, { "maxreaders", "num", 2, 2, 0, ARG_UINT|ARG_MAGIC|MDB_MAXREADERS, mdb_cf_gen, "( OLcfgDbAt:12.1 NAME 'olcDbMaxReaders' " "DESC 'Maximum number of threads that may access the DB concurrently' " @@ -95,7 +100,7 @@ static ConfigOCs mdbocs[] = { "MUST olcDbDirectory " "MAY ( olcDbCheckpoint $ olcDbEnvFlags $ " "olcDbNoSync $ olcDbIndex $ olcDbMaxReaders $ olcDbMaxsize $ " - "olcDbMode $ olcDbSearchStack ) )", + "olcDbMode $ olcDbSearchStack $ olcDbMaxEntrySize ) )", Cft_Database, mdbcfg }, { NULL, 0, NULL } }; @@ -329,6 +334,10 @@ mdb_cf_gen( ConfigArgs *c ) c->value_int = mdb->mi_search_stack_depth; break; + case MDB_MAXENTSZ: + c->value_ulong = mdb->mi_maxentrysize; + break; + case MDB_MAXREADERS: c->value_int = mdb->mi_readers; break; @@ -355,6 +364,10 @@ mdb_cf_gen( ConfigArgs *c ) case MDB_MAXSIZE: break; + case MDB_MAXENTSZ: + mdb->mi_maxentrysize = 0; + break; + case MDB_CHKPT: if ( mdb->mi_txn_cp_task ) { struct re_s *re = mdb->mi_txn_cp_task; @@ -651,6 +664,10 @@ mdb_cf_gen( ConfigArgs *c ) mdb->mi_search_stack_depth = c->value_int; break; + case MDB_MAXENTSZ: + mdb->mi_maxentrysize = c->value_ulong; + break; + case MDB_MAXREADERS: mdb->mi_readers = c->value_int; if ( mdb->mi_flags & MDB_IS_OPEN ) { diff --git a/servers/slapd/back-mdb/id2entry.c b/servers/slapd/back-mdb/id2entry.c index 4efdba6756..7e5b8cc2e2 100644 --- a/servers/slapd/back-mdb/id2entry.c +++ b/servers/slapd/back-mdb/id2entry.c @@ -63,6 +63,9 @@ static int mdb_id2entry_put( if (e->e_id < mdb->mi_nextid) flag &= ~MDB_APPEND; + if (mdb->mi_maxentrysize && ec.len > mdb->mi_maxentrysize) + return LDAP_ADMINLIMIT_EXCEEDED; + again: data.mv_size = ec.len; if ( mc ) diff --git a/servers/slapd/back-mdb/modify.c b/servers/slapd/back-mdb/modify.c index 9a261882b9..8e9443d696 100644 --- a/servers/slapd/back-mdb/modify.c +++ b/servers/slapd/back-mdb/modify.c @@ -601,7 +601,12 @@ mdb_modify( Operation *op, SlapReply *rs ) Debug( LDAP_DEBUG_TRACE, LDAP_XSTRING(mdb_modify) ": id2entry update failed " "(%d)\n", rs->sr_err, 0, 0 ); - rs->sr_text = "entry update failed"; + if ( rs->sr_err == LDAP_ADMINLIMIT_EXCEEDED ) { + rs->sr_text = "entry too big"; + } else { + rs->sr_err = LDAP_OTHER; + rs->sr_text = "entry update failed"; + } goto return_results; } diff --git a/servers/slapd/back-mdb/modrdn.c b/servers/slapd/back-mdb/modrdn.c index ba8c019209..aa1be8cf6b 100644 --- a/servers/slapd/back-mdb/modrdn.c +++ b/servers/slapd/back-mdb/modrdn.c @@ -487,8 +487,12 @@ mdb_modrdn( Operation *op, SlapReply *rs ) "<=- " LDAP_XSTRING(mdb_modrdn) ": id2entry failed: %s (%d)\n", mdb_strerror(rs->sr_err), rs->sr_err, 0 ); - rs->sr_err = LDAP_OTHER; - rs->sr_text = "entry update failed"; + if ( rs->sr_err == LDAP_ADMINLIMIT_EXCEEDED ) { + rs->sr_text = "entry too big"; + } else { + rs->sr_err = LDAP_OTHER; + rs->sr_text = "entry update failed"; + } goto return_results; } -- 2.39.5