]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/slap.h
Ditch LRU cache replacement in favor of 2nd-chance/clock.
[openldap] / servers / slapd / slap.h
index febec4f4d98bfb5cd54f1b90f7df68f07e17de19..95cb6c287606d2cc5d51472275bec273c387fddd 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2005 The OpenLDAP Foundation.
+ * Copyright 1998-2006 The OpenLDAP Foundation.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
 
 LDAP_BEGIN_DECL
 
-
-#ifdef LDAP_DEVEL
 #define SLAP_LIGHTWEIGHT_DISPATCHER /* experimental slapd architecture */
-#define SLAP_MULTI_CONN_ARRAY
 #ifdef LDAP_PVT_THREAD_POOL_SEM_LOAD_CONTROL
 #define SLAP_SEM_LOAD_CONTROL
-#endif /* LDAP_PVT_THREAD_POOL_SEM_LOAD_CONTROL */
+#endif
 
-#define SLAP_ACL_HONOR_DISCLOSE        /* partially implemented */
-#define SLAP_ACL_HONOR_MANAGE  /* not yet implemented */
-#define SLAP_DYNACL
-#define SLAP_OVERLAY_ACCESS
+#ifdef LDAP_DEVEL
+#define LDAP_COLLECTIVE_ATTRIBUTES
 #define LDAP_COMP_MATCH
-#define LDAP_DYNAMIC_OBJECTS
 #define LDAP_SYNC_TIMESTAMP
-#define LDAP_COLLECTIVE_ATTRIBUTES
-#define SLAPD_CONF_UNKNOWN_BAILOUT
-#define SLAP_CONTROL_X_TREE_DELETE LDAP_CONTROL_X_TREE_DELETE
+#define SLAP_SORTEDRESULTS
+#endif
 
-#define SLAP_ORDERED_PRETTYNORM
-#define SLAP_AUTHZ_SYNTAX
+#define LDAP_DYNAMIC_OBJECTS
+#define SLAP_CONTROL_X_TREE_DELETE LDAP_CONTROL_X_TREE_DELETE
+#define SLAP_DISTPROC
 
 #ifdef ENABLE_REWRITE
 #define SLAP_AUTH_REWRITE      1 /* use librewrite for sasl-regexp */
 #endif
-#endif
-
-#if defined(LDAP_SLAPI) && !defined(SLAP_OVERLAY_ACCESS)
-#define SLAP_OVERLAY_ACCESS
-#endif
-
-/*
- * ITS#3705: bail out if unknown config directives appear in slapd.conf
- */
-#ifdef SLAPD_CONF_UNKNOWN_BAILOUT
-#define        SLAPD_CONF_UNKNOWN_IGNORED      ""
-#define SLAPD_DEBUG_CONFIG_ERROR       LDAP_DEBUG_ANY
-#else /* ! SLAPD_CONF_UNKNOWN_BAILOUT */
-#define        SLAPD_CONF_UNKNOWN_IGNORED      " (ignored)"
-#define SLAPD_DEBUG_CONFIG_ERROR       LDAP_DEBUG_CONFIG
-#endif /* ! SLAPD_CONF_UNKNOWN_BAILOUT */
 
 /*
  * SLAPD Memory allocation macros
@@ -179,7 +157,7 @@ LDAP_BEGIN_DECL
  * on normalized/pretty DN, such that ';' is never used
  * as RDN separator, and all occurrences of ';' must be escaped */
 #define DN_SEPARATOR(c)        ((c) == ',')
-#define RDN_ATTRTYPEANDVALUE_SEPARATOR(c) ((c) == '+') /* RFC 2253 */
+#define RDN_ATTRTYPEANDVALUE_SEPARATOR(c) ((c) == '+') /* RFC 4514 */
 #define RDN_SEPARATOR(c) (DN_SEPARATOR(c) || RDN_ATTRTYPEANDVALUE_SEPARATOR(c))
 #define RDN_NEEDSESCAPE(c)     ((c) == '\\' || (c) == '"')
 
@@ -212,13 +190,6 @@ LDAP_BEGIN_DECL
 #define SLAPD_ROLE_ATTR                        "roleOccupant"
 #define SLAPD_ROLE_CLASS               "organizationalRole"
 
-#ifdef SLAPD_ACI_ENABLED
-#define SLAPD_ACI_SYNTAX               "1.3.6.1.4.1.4203.666.2.1"
-#endif /* SLAPD_ACI_ENABLED */
-
-/* change this to "OpenLDAPset" */
-#define SLAPD_ACI_SET_ATTR             "template"
-
 #define SLAPD_TOP_OID                  "2.5.6.0"
 
 LDAP_SLAPD_V (int) slap_debug;
@@ -490,7 +461,7 @@ typedef struct slap_matching_rule_use MatchingRuleUse;
 typedef struct slap_matching_rule {
        LDAPMatchingRule                smr_mrule;
        MatchingRuleUse                 *smr_mru;
-       /* RFC2252 string representation */
+       /* RFC 4512 string representation */
        struct berval                   smr_str;
        /*
         * Note: the former
@@ -511,6 +482,8 @@ typedef struct slap_matching_rule {
 #define SLAP_MR_HIDE                   0x8000U
 #endif
 
+#define SLAP_MR_MUTATION_NORMALIZER 0x4000U
+
 #define SLAP_MR_TYPE_MASK              0x0F00U
 #define SLAP_MR_SUBTYPE_MASK   0x00F0U
 #define SLAP_MR_USAGE                  0x000FU
@@ -617,7 +590,7 @@ typedef struct slap_matching_rule {
 struct slap_matching_rule_use {
        LDAPMatchingRuleUse             smru_mruleuse;
        MatchingRule                    *smru_mr;
-       /* RFC2252 string representation */
+       /* RFC 4512 string representation */
        struct berval                   smru_str;
 
        LDAP_SLIST_ENTRY(slap_matching_rule_use) smru_next;
@@ -688,6 +661,7 @@ typedef struct slap_attribute_type {
 #define        SLAP_AT_ORDERED                 0x0003U /* value has order index */
 
 #define        SLAP_AT_HARDCODE        0x10000U        /* hardcoded schema */
+#define        SLAP_AT_DELETED         0x20000U
 
        slap_mask_t                                     sat_flags;
 
@@ -770,6 +744,7 @@ typedef struct slap_object_class {
 #define SLAP_OC_HIDE           0x8000
 #endif
 #define        SLAP_OC_HARDCODE        0x10000U        /* This is hardcoded schema */
+#define        SLAP_OC_DELETED         0x20000U
 
 /*
  * DIT content rule
@@ -807,6 +782,7 @@ typedef struct slap_attr_desc {
 #define SLAP_DESC_NONE                 0x00U
 #define SLAP_DESC_BINARY               0x01U
 #define SLAP_DESC_TAG_RANGE            0x80U
+#define SLAP_DESC_TEMPORARY            0x1000U
 } AttributeDescription;
 
 /* flags to slap_*2undef_ad to register undefined (0, the default)
@@ -1002,18 +978,14 @@ typedef struct slap_mr_assertion {
  */
 typedef struct slap_filter {
        ber_tag_t       f_choice;       /* values taken from ldap.h, plus: */
-#define SLAPD_FILTER_COMPUTED          ((ber_tag_t) -1)
-#define SLAPD_FILTER_DN_ONE                    ((ber_tag_t) -2)
-#define SLAPD_FILTER_DN_SUBTREE                ((ber_tag_t) -3)
-#define SLAPD_FILTER_DN_CHILDREN       ((ber_tag_t) -4)
+#define SLAPD_FILTER_COMPUTED          0
+#define SLAPD_FILTER_MASK                      0x7fff
+#define SLAPD_FILTER_UNDEFINED         0x8000
 
        union f_un_u {
                /* precomputed result */
                ber_int_t f_un_result;
 
-               /* DN */
-               struct berval *f_un_dn;
-
                /* present */
                AttributeDescription *f_un_desc;
 
@@ -1026,7 +998,6 @@ typedef struct slap_filter {
                /* matching rule assertion */
                MatchingRuleAssertion *f_un_mra;
 
-#define f_dn                   f_un.f_un_dn
 #define f_desc                 f_un.f_un_desc
 #define f_ava                  f_un.f_un_ava
 #define f_av_desc              f_un.f_un_ava->aa_desc
@@ -1128,6 +1099,8 @@ typedef struct slap_attr {
        unsigned a_flags;
 #define SLAP_ATTR_IXADD                0x1U
 #define SLAP_ATTR_IXDEL                0x2U
+#define SLAP_ATTR_DONT_FREE_DATA       0x4U
+#define SLAP_ATTR_DONT_FREE_VALS       0x8U
 } Attribute;
 
 
@@ -1137,6 +1110,13 @@ typedef struct slap_attr {
 typedef unsigned long  ID;
 #define NOID   ((ID)~0)
 
+typedef struct slap_entry_header {
+       struct berval bv;
+       char *data;
+       int nattrs;
+       int nvals;
+} EntryHeader;
+
 /*
  * represents an entry in core
  */
@@ -1213,7 +1193,7 @@ typedef enum slap_access_e {
        ACL_COMPARE,
        ACL_SEARCH,
        ACL_READ,
-       ACL_WRITE,
+       ACL_WRITE_,
        ACL_MANAGE,
 
        /* always leave at end of levels but not greater than ACL_LEVEL_MASK */
@@ -1228,8 +1208,10 @@ typedef enum slap_access_e {
        ACL_QUALIFIER_MASK = 0x0f00,
 
        /* write granularity */
-       ACL_WADD = ACL_WRITE|ACL_QUALIFIER1,
-       ACL_WDEL = ACL_WRITE|ACL_QUALIFIER2
+       ACL_WADD = ACL_WRITE_|ACL_QUALIFIER1,
+       ACL_WDEL = ACL_WRITE_|ACL_QUALIFIER2,
+
+       ACL_WRITE = ACL_WADD|ACL_WDEL
 } slap_access_t;
 
 typedef enum slap_control_e {
@@ -1252,6 +1234,7 @@ typedef enum slap_style_e {
        ACL_STYLE_USERS,
        ACL_STYLE_SELF,
        ACL_STYLE_IP,
+       ACL_STYLE_IPV6,
        ACL_STYLE_PATH
 } slap_style_t;
 
@@ -1419,8 +1402,40 @@ typedef struct slap_access {
        /* connection related stuff */
        slap_style_t a_peername_style;
        struct berval   a_peername_pat;
+#ifdef LDAP_PF_INET6
+       union {
+               struct in6_addr ax6;
+               unsigned long   ax;
+       }       ax_peername_addr,
+               ax_peername_mask;
+#define        a_peername_addr6        ax_peername_addr.ax6
+#define        a_peername_addr         ax_peername_addr.ax
+#define        a_peername_mask6        ax_peername_mask.ax6
+#define        a_peername_mask         ax_peername_mask.ax
+/* apparently, only s6_addr is portable;
+ * define a portable address mask comparison */
+#define        slap_addr6_mask(val, msk, asr) ( \
+       (((val)->s6_addr[0] & (msk)->s6_addr[0]) == (asr)->s6_addr[0]) \
+       && (((val)->s6_addr[1] & (msk)->s6_addr[1]) == (asr)->s6_addr[1]) \
+       && (((val)->s6_addr[2] & (msk)->s6_addr[2]) == (asr)->s6_addr[2]) \
+       && (((val)->s6_addr[3] & (msk)->s6_addr[3]) == (asr)->s6_addr[3]) \
+       && (((val)->s6_addr[4] & (msk)->s6_addr[4]) == (asr)->s6_addr[4]) \
+       && (((val)->s6_addr[5] & (msk)->s6_addr[5]) == (asr)->s6_addr[5]) \
+       && (((val)->s6_addr[6] & (msk)->s6_addr[6]) == (asr)->s6_addr[6]) \
+       && (((val)->s6_addr[7] & (msk)->s6_addr[7]) == (asr)->s6_addr[7]) \
+       && (((val)->s6_addr[8] & (msk)->s6_addr[8]) == (asr)->s6_addr[8]) \
+       && (((val)->s6_addr[9] & (msk)->s6_addr[9]) == (asr)->s6_addr[9]) \
+       && (((val)->s6_addr[10] & (msk)->s6_addr[10]) == (asr)->s6_addr[10]) \
+       && (((val)->s6_addr[11] & (msk)->s6_addr[11]) == (asr)->s6_addr[11]) \
+       && (((val)->s6_addr[12] & (msk)->s6_addr[12]) == (asr)->s6_addr[12]) \
+       && (((val)->s6_addr[13] & (msk)->s6_addr[13]) == (asr)->s6_addr[13]) \
+       && (((val)->s6_addr[14] & (msk)->s6_addr[14]) == (asr)->s6_addr[14]) \
+       && (((val)->s6_addr[15] & (msk)->s6_addr[15]) == (asr)->s6_addr[15]) \
+       )
+#else /* ! LDAP_PF_INET6 */
        unsigned long   a_peername_addr,
                        a_peername_mask;
+#endif /* ! LDAP_PF_INET6 */
        int             a_peername_port;
 
        slap_style_t a_sockname_style;
@@ -1437,16 +1452,6 @@ typedef struct slap_access {
 
 #ifdef SLAP_DYNACL
        slap_dynacl_t           *a_dynacl;
-#else /* ! SLAP_DYNACL */
-#ifdef SLAPD_ACI_ENABLED
-       /* NOTE: ACIs have been moved under the "dynacl" interface,
-        * which is currently built only when LDAP_DEVEL is defined.
-        *
-        * In any case, SLAPD_ACI_ENABLED, set by --enable-aci,
-        * is required to enable ACI support.
-        */
-       AttributeDescription    *a_aci_at;
-#endif /* SLAPD_ACI_ENABLED */
 #endif /* SLAP_DYNACL */
 
        /* ACL Groups */
@@ -1477,36 +1482,26 @@ typedef struct slap_acl {
        struct slap_acl *acl_next;
 } AccessControl;
 
-typedef struct slap_acl_state {
-       unsigned as_recorded;
-#define ACL_STATE_NOT_RECORDED                 0x0
-#define ACL_STATE_RECORDED_VD                  0x1
-#define ACL_STATE_RECORDED_NV                  0x2
-#define ACL_STATE_RECORDED                             0x3
+typedef enum {
+       ACL_STATE_NOT_RECORDED                  = 0x0,
+       ACL_STATE_RECORDED_VD                   = 0x1,
+       ACL_STATE_RECORDED_NV                   = 0x2,
+       ACL_STATE_RECORDED                      = ( ACL_STATE_RECORDED_VD | ACL_STATE_RECORDED_NV )
+} slap_acl_state_t;
 
+typedef struct slap_acl_state {
        /* Access state */
-       AccessControl *as_vd_acl;
        AccessControl *as_vi_acl;
-       slap_mask_t as_vd_acl_mask;
-       regmatch_t as_vd_acl_matches[MAXREMATCHES];
-       int as_vd_acl_count;
+       AccessControl *as_vd_acl;
+       AttributeDescription *as_vd_ad;
 
-       Access *as_vd_access;
-       int as_vd_access_count;
 
+       slap_acl_state_t as_recorded;
+       int as_vd_acl_count;
        int as_result;
-       AttributeDescription *as_vd_ad;
 } AccessControlState;
-#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 */
+#define ACL_STATE_INIT { NULL, NULL, NULL, \
+       ACL_STATE_NOT_RECORDED, 0, 0 }
 
 /*
  * Backend-info
@@ -1534,6 +1529,7 @@ LDAP_SLAPD_V (int) slapMode;
 #define        SLAP_TOOL_READMAIN      0x0200
 #define        SLAP_TOOL_READONLY      0x0400
 #define        SLAP_TOOL_QUICK         0x0800
+#define SLAP_TOOL_NO_SCHEMA_CHECK      0x1000
 
 #define SB_TLS_DEFAULT         (-1)
 #define SB_TLS_OFF             0
@@ -1542,6 +1538,7 @@ LDAP_SLAPD_V (int) slapMode;
 
 typedef struct slap_bindconf {
        struct berval sb_uri;
+       int sb_version;
        int sb_tls;
        int sb_method;
        struct berval sb_binddn;
@@ -1551,6 +1548,19 @@ typedef struct slap_bindconf {
        struct berval sb_realm;
        struct berval sb_authcId;
        struct berval sb_authzId;
+#ifdef HAVE_TLS
+       void *sb_tls_ctx;
+       char *sb_tls_cert;
+       char *sb_tls_key;
+       char *sb_tls_cacert;
+       char *sb_tls_cacertdir;
+       char *sb_tls_reqcert;
+       char *sb_tls_cipher_suite;
+#ifdef HAVE_OPENSSL_CRL
+       char *sb_tls_crlcheck;
+#endif
+       int sb_tls_do_init;
+#endif
 } slap_bindconf;
 
 struct slap_replica_info {
@@ -1571,7 +1581,7 @@ typedef struct slap_cf_aux_table {
        int off;
        char type;
        char quote;
-       slap_verbmasks *aux;
+       void *aux;
 } slap_cf_aux_table;
 
 #define SLAP_LIMIT_TIME        1
@@ -1697,8 +1707,7 @@ struct slap_backend_db {
 
 /*
  * define to honor hasSubordinates operational attribute in search filters
- * (in previous use there was a flaw with back-bdb and back-ldbm; now it 
- * is fixed).
+ * (in previous use there was a flaw with back-bdb; now it is fixed).
  */
 #define                be_has_subordinates bd_info->bi_has_subordinates
 
@@ -1727,20 +1736,27 @@ struct slap_backend_db {
 /* Database flags */
 #define SLAP_DBFLAG_NOLASTMOD          0x0001U
 #define SLAP_DBFLAG_NO_SCHEMA_CHECK    0x0002U
+#define        SLAP_DBFLAG_HIDDEN              0x0004U
 #define        SLAP_DBFLAG_GLUE_INSTANCE       0x0010U /* a glue backend */
 #define        SLAP_DBFLAG_GLUE_SUBORDINATE    0x0020U /* child of a glue hierarchy */
 #define        SLAP_DBFLAG_GLUE_LINKED         0x0040U /* child is connected to parent */
 #define SLAP_DBFLAG_GLUE_ADVERTISE     0x0080U /* advertise in rootDSE */
 #define SLAP_DBFLAG_OVERLAY            0x0100U /* this db struct is an overlay */
 #define        SLAP_DBFLAG_GLOBAL_OVERLAY      0x0200U /* this db struct is a global overlay */
+#define SLAP_DBFLAG_DYNAMIC            0x0400U /* this db allows dynamicObjects */
+#define        SLAP_DBFLAG_MONITORING          0x0800U /* custom monitoring enabled */
 #define SLAP_DBFLAG_SHADOW             0x8000U /* a shadow */
+#define SLAP_DBFLAG_SINGLE_SHADOW      0x4000U /* a single-master shadow */
 #define SLAP_DBFLAG_SYNC_SHADOW                0x1000U /* a sync shadow */
 #define SLAP_DBFLAG_SLURP_SHADOW       0x2000U /* a slurp shadow */
        slap_mask_t     be_flags;
 #define SLAP_DBFLAGS(be)                       ((be)->be_flags)
 #define SLAP_NOLASTMOD(be)                     (SLAP_DBFLAGS(be) & SLAP_DBFLAG_NOLASTMOD)
 #define SLAP_LASTMOD(be)                       (!SLAP_NOLASTMOD(be))
+#define SLAP_DBHIDDEN(be)                      (SLAP_DBFLAGS(be) & SLAP_DBFLAG_HIDDEN)
 #define SLAP_ISOVERLAY(be)                     (SLAP_DBFLAGS(be) & SLAP_DBFLAG_OVERLAY)
+#define SLAP_ISGLOBALOVERLAY(be)               (SLAP_DBFLAGS(be) & SLAP_DBFLAG_GLOBAL_OVERLAY)
+#define SLAP_DBMONITORING(be)                  (SLAP_DBFLAGS(be) & SLAP_DBFLAG_MONITORING)
 #define SLAP_NO_SCHEMA_CHECK(be)       \
        (SLAP_DBFLAGS(be) & SLAP_DBFLAG_NO_SCHEMA_CHECK)
 #define        SLAP_GLUE_INSTANCE(be)          \
@@ -1754,6 +1770,8 @@ struct slap_backend_db {
 #define SLAP_SHADOW(be)                                (SLAP_DBFLAGS(be) & SLAP_DBFLAG_SHADOW)
 #define SLAP_SYNC_SHADOW(be)                   (SLAP_DBFLAGS(be) & SLAP_DBFLAG_SYNC_SHADOW)
 #define SLAP_SLURP_SHADOW(be)                  (SLAP_DBFLAGS(be) & SLAP_DBFLAG_SLURP_SHADOW)
+#define SLAP_SINGLE_SHADOW(be)                 (SLAP_DBFLAGS(be) & SLAP_DBFLAG_SINGLE_SHADOW)
+#define SLAP_MULTIMASTER(be)                   (!SLAP_SINGLE_SHADOW(be))
 
        slap_mask_t     be_restrictops;         /* restriction operations */
 #define SLAP_RESTRICT_OP_ADD           0x0001U
@@ -1785,13 +1803,15 @@ struct slap_backend_db {
 #define SLAP_RESTRICT_OP_ALL \
        ( SLAP_RESTRICT_OP_READS \
        | SLAP_RESTRICT_OP_WRITES \
+       | SLAP_RESTRICT_OP_BIND \
        | SLAP_RESTRICT_OP_EXTENDED )
 
-#define SLAP_ALLOW_BIND_V2                     0x0001U /* LDAPv2 bind */
+#define SLAP_ALLOW_BIND_V2             0x0001U /* LDAPv2 bind */
 #define SLAP_ALLOW_BIND_ANON_CRED      0x0002U /* cred should be empty */
 #define SLAP_ALLOW_BIND_ANON_DN                0x0004U /* dn should be empty */
 
 #define SLAP_ALLOW_UPDATE_ANON         0x0008U /* allow anonymous updates */
+#define SLAP_ALLOW_PROXY_AUTHZ_ANON    0x0010U /* allow anonymous proxyAuthz */
 
 #define SLAP_DISALLOW_BIND_ANON                0x0001U /* no anonymous */
 #define SLAP_DISALLOW_BIND_SIMPLE      0x0002U /* simple authentication */
@@ -1900,6 +1920,7 @@ typedef struct req_modify_s {
 } req_modify_s;
 
 typedef struct req_modrdn_s {
+       Modifications *rs_modlist;
        struct berval rs_newrdn;
        struct berval rs_nnewrdn;
        struct berval *rs_newSup;
@@ -1908,8 +1929,8 @@ typedef struct req_modrdn_s {
 } req_modrdn_s;
 
 typedef struct req_add_s {
-       Entry *rs_e;
        Modifications *rs_modlist;      /* FIXME: temporary */
+       Entry *rs_e;
 } req_add_s;
 
 typedef struct req_abandon_s {
@@ -1943,7 +1964,8 @@ typedef enum slap_reply_e {
        REP_EXTENDED,
        REP_SEARCH,
        REP_SEARCHREF,
-       REP_INTERMEDIATE
+       REP_INTERMEDIATE,
+       REP_GLUE_RESULT
 } slap_reply_t;
 
 typedef struct rep_sasl_s {
@@ -1993,8 +2015,17 @@ typedef struct slap_rep {
 #define REP_ENTRY_MODIFIABLE   0x0001U
 #define REP_ENTRY_MUSTBEFREED  0x0002U
 #define REP_ENTRY_MUSTRELEASE  0x0004U
+#define        REP_ENTRY_MASK          (REP_ENTRY_MODIFIABLE|REP_ENTRY_MUSTBEFREED|REP_ENTRY_MUSTRELEASE)
+
 #define REP_MATCHED_MUSTBEFREED        0x0010U
-#define REP_REF_MUSTBEFREED            0x0020U
+#define        REP_MATCHED_MASK        (REP_MATCHED_MUSTBEFREED)
+
+#define REP_REF_MUSTBEFREED    0x0020U
+#define REP_REF_MASK           (REP_REF_MUSTBEFREED)
+
+#define        REP_NO_ENTRYDN          0x1000U
+#define        REP_NO_SUBSCHEMA        0x2000U
+#define        REP_NO_OPERATIONALS     (REP_NO_ENTRYDN|REP_NO_SUBSCHEMA)
 } SlapReply;
 
 /* short hands for response members */
@@ -2029,7 +2060,6 @@ typedef int (BI_entry_get_rw) LDAP_P(( struct slap_op *op, struct berval *ndn,
 typedef int (BI_operational) LDAP_P(( struct slap_op *op, struct slap_rep *rs ));
 typedef int (BI_has_subordinates) LDAP_P(( struct slap_op *op,
        Entry *e, int *hasSubs ));
-#ifdef SLAP_OVERLAY_ACCESS
 typedef int (BI_access_allowed) LDAP_P(( struct slap_op *op, Entry *e,
        AttributeDescription *desc, struct berval *val, slap_access_t access,
        AccessControlState *state, slap_mask_t *maskp ));
@@ -2039,7 +2069,6 @@ typedef int (BI_acl_group) LDAP_P(( struct slap_op *op, Entry *target,
 typedef int (BI_acl_attribute) LDAP_P(( struct slap_op *op, Entry *target,
        struct berval *entry_ndn, AttributeDescription *entry_at,
        BerVarray *vals, slap_access_t access ));
-#endif /* SLAP_OVERLAY_ACCESS */
 
 typedef int (BI_conn_func) LDAP_P(( BackendDB *bd, struct slap_conn *c ));
 typedef BI_conn_func BI_connection_init;
@@ -2138,11 +2167,9 @@ struct slap_backend_info {
        BI_entry_release_rw     *bi_entry_release_rw;
 
        BI_has_subordinates     *bi_has_subordinates;
-#ifdef SLAP_OVERLAY_ACCESS
        BI_access_allowed       *bi_access_allowed;
        BI_acl_group            *bi_acl_group;
        BI_acl_attribute        *bi_acl_attribute;
-#endif /* SLAP_OVERLAY_ACCESS */
 
        BI_connection_init      *bi_connection_init;
        BI_connection_destroy   *bi_connection_destroy;
@@ -2174,6 +2201,12 @@ struct slap_backend_info {
 #define SLAP_BFLAG_SUBENTRIES          0x4000U
 #define SLAP_BFLAG_DYNAMIC                     0x8000U
 
+/* overlay specific */
+#define        SLAPO_BFLAG_SINGLE              0x01000000U
+#define        SLAPO_BFLAG_DBONLY              0x02000000U
+#define        SLAPO_BFLAG_GLOBONLY            0x04000000U
+#define        SLAPO_BFLAG_MASK                0xFF000000U
+
 #define SLAP_BFLAGS(be)                ((be)->bd_info->bi_flags)
 #define SLAP_MONITOR(be)       (SLAP_BFLAGS(be) & SLAP_BFLAG_MONITOR)
 #define SLAP_CONFIG(be)                (SLAP_BFLAGS(be) & SLAP_BFLAG_CONFIG)
@@ -2182,17 +2215,23 @@ struct slap_backend_info {
 #define SLAP_ALIASES(be)       (SLAP_BFLAGS(be) & SLAP_BFLAG_ALIASES)
 #define SLAP_REFERRALS(be)     (SLAP_BFLAGS(be) & SLAP_BFLAG_REFERRALS)
 #define SLAP_SUBENTRIES(be)    (SLAP_BFLAGS(be) & SLAP_BFLAG_SUBENTRIES)
-#define SLAP_DYNAMIC(be)       (SLAP_BFLAGS(be) & SLAP_BFLAG_DYNAMIC)
+#define SLAP_DYNAMIC(be)       ((SLAP_BFLAGS(be) & SLAP_BFLAG_DYNAMIC) || (SLAP_DBFLAGS(be) & SLAP_DBFLAG_DYNAMIC))
 #define SLAP_NOLASTMODCMD(be)  (SLAP_BFLAGS(be) & SLAP_BFLAG_NOLASTMODCMD)
 #define SLAP_LASTMODCMD(be)    (!SLAP_NOLASTMODCMD(be))
 
+/* overlay specific */
+#define SLAPO_SINGLE(be)       (SLAP_BFLAGS(be) & SLAPO_BFLAG_SINGLE)
+#define SLAPO_DBONLY(be)       (SLAP_BFLAGS(be) & SLAPO_BFLAG_DBONLY)
+#define SLAPO_GLOBONLY(be)     (SLAP_BFLAGS(be) & SLAPO_BFLAG_GLOBONLY)
+
        char    **bi_controls;          /* supported controls */
        char    bi_ctrls[SLAP_MAX_CIDS + 1];
 
        unsigned int bi_nDB;    /* number of databases of this type */
        struct ConfigOCs *bi_cf_ocs;
        char    **bi_obsolete_names;
-       void    *bi_private;    /* anything the backend type needs */
+       void    *bi_extra;              /* backend type-specific APIs */
+       void    *bi_private;    /* backend type-specific config data */
        LDAP_STAILQ_ENTRY(slap_backend_info) bi_next ;
 };
 
@@ -2259,6 +2298,7 @@ typedef struct slap_overinfo {
 
 /* Should successive callbacks in a chain be processed? */
 #define        SLAP_CB_FREEME          0x04000
+#define        SLAP_CB_BYPASS          0x08800
 #define        SLAP_CB_CONTINUE        0x08000
 
 /*
@@ -2300,7 +2340,6 @@ struct slap_control_ids {
        int sc_assert;
        int sc_domainScope;
        int sc_dontUseCopy;
-       int sc_manageDIT;
        int sc_manageDSAit;
        int sc_modifyIncrement;
        int sc_noOp;
@@ -2309,12 +2348,16 @@ struct slap_control_ids {
        int sc_postRead;
        int sc_preRead;
        int sc_proxyAuthz;
+       int sc_relax;
        int sc_searchOptions;
-#ifdef LDAP_DEVEL
+#ifdef SLAP_SORTEDRESULTS
        int sc_sortedResults;
 #endif
        int sc_subentries;
        int sc_treeDelete;
+#ifdef LDAP_X_TXN
+       int sc_txnSpec;
+#endif
        int sc_valuesReturnFilter;
 };
 
@@ -2342,6 +2385,19 @@ typedef struct slap_op_header {
 #endif
 } Opheader;
 
+typedef union slap_op_request {
+       req_add_s oq_add;
+       req_bind_s oq_bind;
+       req_compare_s oq_compare;
+       req_modify_s oq_modify;
+       req_modrdn_s oq_modrdn;
+       req_search_s oq_search;
+       req_abandon_s oq_abandon;
+       req_abandon_s oq_cancel;
+       req_extended_s oq_extended;
+       req_pwdexop_s oq_pwdexop;
+} OpRequest;
+
 typedef struct slap_op {
        Opheader *o_hdr;
 
@@ -2370,18 +2426,7 @@ typedef struct slap_op {
        struct berval   o_req_dn;       /* DN of target of request */
        struct berval   o_req_ndn;
 
-       union o_req_u {
-               req_add_s oq_add;
-               req_bind_s oq_bind;
-               req_compare_s oq_compare;
-               req_modify_s oq_modify;
-               req_modrdn_s oq_modrdn;
-               req_search_s oq_search;
-               req_abandon_s oq_abandon;
-               req_abandon_s oq_cancel;
-               req_extended_s oq_extended;
-               req_pwdexop_s oq_pwdexop;
-       } o_request;
+       OpRequest o_request;
 
 /* short hands for union members */
 #define oq_add o_request.oq_add
@@ -2417,6 +2462,7 @@ typedef struct slap_op {
 #define orr_newSup oq_modrdn.rs_newSup
 #define orr_nnewSup oq_modrdn.rs_nnewSup
 #define orr_deleteoldrdn oq_modrdn.rs_deleteoldrdn
+#define orr_modlist oq_modrdn.rs_modlist
 
 #define orc_ava oq_compare.rs_ava
 #define ora_e oq_add.rs_e
@@ -2443,6 +2489,8 @@ typedef struct slap_op {
        char o_delete_glue_parent;
        char o_no_schema_check;
 #define get_no_schema_check(op)                        ((op)->o_no_schema_check)
+       char o_no_subordinate_glue;
+#define get_no_subordinate_glue(op)            ((op)->o_no_subordinate_glue)
 
 #define SLAP_CONTROL_NONE      0
 #define SLAP_CONTROL_IGNORED   1
@@ -2457,7 +2505,6 @@ typedef struct slap_op {
 #define SLAP_CONTROL_DATA2     0x40
 #define SLAP_CONTROL_DATA3     0x80
 
-
 #define _SCM(x)        ((x) & SLAP_CONTROL_MASK)
 
        char o_ctrlflag[SLAP_MAX_CIDS]; /* per-control flags */
@@ -2466,8 +2513,8 @@ typedef struct slap_op {
 #define o_dontUseCopy                  o_ctrlflag[slap_cids.sc_dontUseCopy]
 #define get_dontUseCopy(op)            _SCM((op)->o_dontUseCopy)
 
-#define o_managedit                            o_ctrlflag[slap_cids.sc_manageDIT]
-#define get_manageDIT(op)              _SCM((op)->o_managedit)
+#define o_relax                                o_ctrlflag[slap_cids.sc_relax]
+#define get_relax(op)          _SCM((op)->o_relax)
 
 #define o_managedsait  o_ctrlflag[slap_cids.sc_manageDSAit]
 #define get_manageDSAit(op)                            _SCM((op)->o_managedsait)
@@ -2509,10 +2556,14 @@ typedef struct slap_op {
 #define o_pagedresults_state   o_controls[slap_cids.sc_pagedResults]
 #define get_pagedresults(op)                   ((int)(op)->o_pagedresults)
 
-#ifdef LDAP_DEVEL
+#ifdef SLAP_SORTEDRESULTS
 #define o_sortedresults                o_ctrlflag[slap_cids.sc_sortedResults]
 #endif
 
+#ifdef LDAP_X_TXN
+#define o_txnSpec              o_ctrlflag[slap_cids.sc_txnSpec]
+#endif
+
 #define o_sync                 o_ctrlflag[slap_cids.sc_LDAPsync]
 
        AuthorizationInformation o_authz;
@@ -2525,9 +2576,9 @@ typedef struct slap_op {
 
        void    *o_private;     /* anything the backend needs */
 
-       LDAP_STAILQ_ENTRY(slap_op)      o_next; /* next operation in list         */
-
+       LDAP_STAILQ_ENTRY(slap_op)      o_next; /* next operation in list */
 } Operation;
+
 #define        OPERATION_BUFFER_SIZE   ( sizeof(Operation) + sizeof(Opheader) + \
        SLAP_MAX_CIDS*sizeof(void *) )
 
@@ -2638,6 +2689,16 @@ typedef struct slap_conn {
        void    *c_sasl_extra;          /* SASL session extra stuff */
        struct slap_op  *c_sasl_bindop; /* set to current op if it's a bind */
 
+#ifdef LDAP_X_TXN
+#define CONN_TXN_INACTIVE 0
+#define CONN_TXN_SPECIFY 1
+#define CONN_TXN_SETTLE -1
+       int c_txn;
+
+       Backend *c_txn_backend;
+       LDAP_STAILQ_HEAD(c_to, slap_op) c_txn_ops; /* list of operations in txn */
+#endif
+
        PagedResultsState c_pagedresults_state; /* paged result state */
 
        long    c_n_ops_received;       /* num of ops received (next op_id) */
@@ -2649,7 +2710,6 @@ typedef struct slap_conn {
        long    c_n_read;               /* num of read calls */
        long    c_n_write;              /* num of write calls */
 
-       void    *c_pb;                  /* Netscape plugin */
        void    *c_extensions;          /* Netscape plugin */
 
        /*
@@ -2670,27 +2730,27 @@ typedef struct slap_conn {
        SEND_LDAP_INTERMEDIATE *c_send_ldap_intermediate;
 } Connection;
 
-#if defined(LDAP_SYSLOG) && defined(LDAP_DEBUG)
+#ifdef LDAP_DEBUG
+#ifdef LDAP_SYSLOG
+#ifdef LOG_LOCAL4
+#define SLAP_DEFAULT_SYSLOG_USER       LOG_LOCAL4
+#endif /* LOG_LOCAL4 */
+
 #define Statslog( level, fmt, connid, opid, arg1, arg2, arg3 ) \
-       do { \
-               if ( ldap_debug & (level) ) \
-                       fprintf( stderr, (fmt), (connid), (opid), (arg1), (arg2), (arg3) );\
-               if ( ldap_syslog & (level) ) \
-                       syslog( ldap_syslog_level, (fmt), (connid), (opid), (arg1), \
-                               (arg2), (arg3) ); \
-       } while (0)
+       Log5( (level), ldap_syslog_level, (fmt), (connid), (opid), (arg1), (arg2), (arg3) )
 #define StatslogTest( level ) ((ldap_debug | ldap_syslog) & (level))
-#elif defined(LDAP_DEBUG)
+#else /* !LDAP_SYSLOG */
 #define Statslog( level, fmt, connid, opid, arg1, arg2, arg3 ) \
        do { \
                if ( ldap_debug & (level) ) \
                        fprintf( stderr, (fmt), (connid), (opid), (arg1), (arg2), (arg3) );\
        } while (0)
 #define StatslogTest( level ) (ldap_debug & (level))
-#else
-#define Statslog( level, fmt, connid, opid, arg1, arg2, arg3 )
+#endif /* !LDAP_SYSLOG */
+#else /* !LDAP_DEBUG */
+#define Statslog( level, fmt, connid, opid, arg1, arg2, arg3 ) ((void) 0)
 #define StatslogTest( level ) (0)
-#endif
+#endif /* !LDAP_DEBUG */
 
 /*
  * listener; need to access it from monitor backend
@@ -2717,7 +2777,7 @@ struct slap_listener {
 /*
  * Operation indices
  */
-enum {
+typedef enum {
        SLAP_OP_BIND = 0,
        SLAP_OP_UNBIND,
        SLAP_OP_ADD,
@@ -2729,7 +2789,7 @@ enum {
        SLAP_OP_ABANDON,
        SLAP_OP_EXTENDED,
        SLAP_OP_LAST
-};
+} slap_op_t;
 
 typedef struct slap_counters_t {
        ldap_pvt_thread_mutex_t sc_sent_mutex;
@@ -2762,7 +2822,7 @@ typedef struct slap_counters_t {
 #define SLAP_CTRL_HIDE                         0x80000000U
 #endif
 
-#define SLAP_CTRL_REQUIRES_ROOT                0x40000000U /* for ManageDIT */
+#define SLAP_CTRL_REQUIRES_ROOT                0x40000000U /* for Relax */
 
 #define SLAP_CTRL_GLOBAL                       0x00800000U
 #define SLAP_CTRL_GLOBAL_SEARCH                0x00010000U     /* for NOOP */
@@ -2788,6 +2848,8 @@ typedef int (SLAP_CTRL_PARSE_FN) LDAP_P((
        SlapReply *rs,
        LDAPControl *ctrl ));
 
+typedef int (*SLAP_ENTRY_INFO_FN) LDAP_P(( void *arg, Entry *e ));
+
 #define SLAP_SLAB_SIZE (1024*1024)
 #define SLAP_SLAB_STACK 1
 #define SLAP_SLAB_SOBLOCK 64