Merge ~sergiodj/ubuntu/+source/openldap:MRE-2.5.17-jammy into ubuntu/+source/openldap:ubuntu/jammy-devel

Proposed by Sergio Durigan Junior
Status: Merged
Approved by: git-ubuntu bot
Approved revision: not available
Merged at revision: a2130beb84a0617b364fd2d7beca33aac443a08b
Proposed branch: ~sergiodj/ubuntu/+source/openldap:MRE-2.5.17-jammy
Merge into: ubuntu/+source/openldap:ubuntu/jammy-devel
Diff against target: 4842 lines (+1607/-800)
50 files modified
CHANGES (+32/-0)
build/version.var (+4/-4)
clients/tools/common.c (+4/-3)
clients/tools/ldappasswd.c (+12/-2)
clients/tools/ldapvc.c (+7/-2)
contrib/slapd-modules/lastmod/lastmod.c (+10/-2)
debian/changelog (+19/-0)
doc/guide/admin/guide.html (+1/-1)
doc/man/man5/lloadd.conf.5 (+26/-26)
doc/man/man5/slapo-dynlist.5 (+7/-0)
doc/man/man5/slapo-homedir.5 (+28/-1)
doc/man/man8/slapd.8 (+3/-1)
include/ac/string.h (+3/-3)
libraries/liblber/debug.c (+4/-1)
libraries/libldap/getdn.c (+8/-0)
libraries/libldap/init.c (+0/-3)
libraries/libldap/open.c (+1/-0)
libraries/libldap/tls2.c (+13/-1)
libraries/libldap/tls_o.c (+14/-4)
libraries/libldap/url.c (+4/-0)
libraries/libldap/util-int.c (+51/-123)
libraries/liblmdb/CHANGES (+6/-0)
libraries/liblmdb/Makefile (+1/-0)
libraries/liblmdb/lmdb.h (+2/-2)
libraries/liblmdb/mdb.c (+112/-37)
libraries/liblmdb/mdb_load.c (+4/-2)
libraries/liblmdb/midl.h (+2/-0)
libraries/liblmdb/mplay.c (+582/-0)
servers/lloadd/daemon.c (+15/-1)
servers/lloadd/libevent_support.c (+7/-1)
servers/lloadd/module_init.c (+0/-1)
servers/lloadd/upstream.c (+8/-3)
servers/slapd/aci.c (+14/-12)
servers/slapd/aclparse.c (+416/-448)
servers/slapd/back-asyncmeta/map.c (+11/-1)
servers/slapd/back-ldap/chain.c (+1/-1)
servers/slapd/back-null/null.c (+2/-2)
servers/slapd/bconfig.c (+30/-17)
servers/slapd/controls.c (+1/-0)
servers/slapd/overlays/dynlist.c (+35/-20)
servers/slapd/proto-slap.h (+1/-3)
servers/slapd/slap-config.h (+22/-22)
servers/slapd/slap.h (+4/-2)
servers/slapd/slapi/Makefile.in (+6/-6)
servers/slapd/slapi/plugin.c (+35/-36)
servers/slapd/slapi/printmsg.c (+20/-0)
servers/slapd/slapi/proto-slapi.h (+1/-2)
servers/slapd/slapi/slapi_utils.c (+6/-0)
servers/slapd/slappasswd.c (+9/-4)
tests/progs/slapd-tester.c (+3/-0)
Reviewer Review Type Date Requested Status
git-ubuntu bot Approve
Bryce Harrington (community) Approve
Canonical Server Reporter Pending
Review via email: mp+460353@code.launchpad.net

Description of the change

This is the MRE of OpenLDAP 2.5.17 to Jammy.

Nothing major to report here. Instead of trying to decide for a small set of upstream changes to list on d/changelog, I'm now listing everything.

PPA: https://launchpad.net/~sergiodj/+archive/ubuntu/openldap

dep8 results will be posted soon.

To post a comment you must log in.
Revision history for this message
Bryce Harrington (bryce) wrote :

LGTM, +1, presuming the autopkgtests pass.

I like the more detailed changelog personally, and if it saves some thinking time not to have to filter it, then that's a bonus.

I skimmed briefly through the upstream diff, nothing caught my eye. A healthy chunk of it is debug messaging, which is a good sign. There's an `mplay` command being added although that appears just for analysis/debugging (I can't tell if it gets installed but am guessing no.) The remainder does indeed look like bugfixes.

review: Approve
Revision history for this message
git-ubuntu bot (git-ubuntu-bot) wrote :

Approvers: sergiodj, bryce
Uploaders: sergiodj, bryce
MP auto-approved

review: Approve
Revision history for this message
Sergio Durigan Junior (sergiodj) wrote :

On Friday, February 09 2024, Bryce Harrington wrote:

> LGTM, +1, presuming the autopkgtests pass.

Thanks, Bryce.

I just got the results:

Results: (from http://autopkgtest.ubuntu.com/results/autopkgtest-jammy-sergiodj-openldap/?format=plain)
  openldap @ amd64:
    http://autopkgtest.ubuntu.com/results/autopkgtest-jammy-sergiodj-openldap/jammy/amd64/o/openldap/20240209_225823_2ec27@/log.gz
    09.02.24 22:58:23 ✅ Triggers: openldap/2.5.17+dfsg-0ubuntu0.22.04.1~ppa1
  openldap @ arm64:
    http://autopkgtest.ubuntu.com/results/autopkgtest-jammy-sergiodj-openldap/jammy/arm64/o/openldap/20240209_230358_34851@/log.gz
    09.02.24 23:03:58 ✅ Triggers: openldap/2.5.17+dfsg-0ubuntu0.22.04.1~ppa1
  openldap @ armhf:
    http://autopkgtest.ubuntu.com/results/autopkgtest-jammy-sergiodj-openldap/jammy/armhf/o/openldap/20240209_230114_34851@/log.gz
    09.02.24 23:01:14 ✅ Triggers: openldap/2.5.17+dfsg-0ubuntu0.22.04.1~ppa1
  openldap @ ppc64el:
    http://autopkgtest.ubuntu.com/results/autopkgtest-jammy-sergiodj-openldap/jammy/ppc64el/o/openldap/20240209_231213_2ec27@/log.gz
    09.02.24 23:12:13 ✅ Triggers: openldap/2.5.17+dfsg-0ubuntu0.22.04.1~ppa1
  openldap @ s390x:
    http://autopkgtest.ubuntu.com/results/autopkgtest-jammy-sergiodj-openldap/jammy/s390x/o/openldap/20240209_225840_2ec27@/log.gz
    09.02.24 22:58:40 ✅ Triggers: openldap/2.5.17+dfsg-0ubuntu0.22.04.1~ppa1

Therefore, I'm uploading the package now:

$ dput openldap_2.5.17+dfsg-0ubuntu0.22.04.1_source.changes
Trying to upload package to ubuntu
Checking signature on .changes
gpg: /home/sergio/work/openldap/openldap_2.5.17+dfsg-0ubuntu0.22.04.1_source.changes: Valid signature from 106DA1C8C3CBBF14
Checking signature on .dsc
gpg: /home/sergio/work/openldap/openldap_2.5.17+dfsg-0ubuntu0.22.04.1.dsc: Valid signature from 106DA1C8C3CBBF14
Package includes an .orig.tar.gz file although the debian revision suggests
that it might not be required. Multiple uploads of the .orig.tar.gz may be
rejected by the upload queue management software.
Uploading to ubuntu (via ftp to upload.ubuntu.com):
  Uploading openldap_2.5.17+dfsg-0ubuntu0.22.04.1.dsc: done.
  Uploading openldap_2.5.17+dfsg.orig.tar.gz: done.
  Uploading openldap_2.5.17+dfsg-0ubuntu0.22.04.1.debian.tar.xz: done.
  Uploading openldap_2.5.17+dfsg-0ubuntu0.22.04.1_source.buildinfo: done.
  Uploading openldap_2.5.17+dfsg-0ubuntu0.22.04.1_source.changes: done.
Successfully uploaded packages.

--
Sergio
GPG key ID: E92F D0B3 6B14 F1F4 D8E0 EB2F 106D A1C8 C3CB BF14

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/CHANGES b/CHANGES
index 23c0e5e..8b691f0 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,37 @@
1OpenLDAP 2.5 Change Log1OpenLDAP 2.5 Change Log
22
3OpenLDAP 2.5.17 Release (2024/01/29)
4 Added slapo-dynlist option to disable filter support (ITS#10025)
5 Fixed liblber missing newline on long msg (ITS#10105)
6 Fixed libldap exit handling with OpenSSL3 (ITS#9952)
7 Fixed libldap with TLS and multiple ldap URIs (ITS#10101)
8 Fixed libldap OpenSSL cipher suite handling (ITS#10094)
9 Fixed libldap OpenSSL 3.0 and Diffie-Hellman param files (ITS#10124)
10 Fixed libldap timestamps on Windows (ITS#10100)
11 Fixed lloadd to work when resolv.conf is missing (ITS#10070)
12 Fixed lloadd handling of closing connection (ITS#10083)
13 Fixed slapd to honour disclose in matchedDN handling (ITS#10139)
14 Fixed slapd handling of regex testing in ACLs (ITS#10089)
15 Fixed slapd-asyncmeta when remote suffix is empty (ITS#10076)
16 Fixed slapo-dynlist so it can't be global (ITS#10091)
17 Build
18 Fixed lloadd type mismatches (ITS#10074)
19 Fixed builds for Windows (ITS#10117)
20 Fixed build with clang16 (ITS#10123
21 Documentation
22 Fixed slapo-homedir(5) attribute name for olcHomedirArchivePath (ITS#10057)
23 Minor Cleanup
24 ITS#10059
25 ITS#10068
26 ITS#10109
27 ITS#10110
28 ITS#10129
29 ITS#10130
30 ITS#10135
31 ITS#10144
32 ITS#10145
33 ITS#10153
34
3OpenLDAP 2.5.16 Release (2023/07/31)35OpenLDAP 2.5.16 Release (2023/07/31)
4 Fixed slapd cn=config incorrect handling of paused (ITS#10045)36 Fixed slapd cn=config incorrect handling of paused (ITS#10045)
5 Fixed slapd-meta to account for MOD ops being optional (ITS#10067)37 Fixed slapd-meta to account for MOD ops being optional (ITS#10067)
diff --git a/build/version.var b/build/version.var
index cd4e7aa..e2d54d0 100644
--- a/build/version.var
+++ b/build/version.var
@@ -15,9 +15,9 @@
15ol_package=OpenLDAP15ol_package=OpenLDAP
16ol_major=216ol_major=2
17ol_minor=517ol_minor=5
18ol_patch=1618ol_patch=17
19ol_api_inc=2051619ol_api_inc=20517
20ol_api_current=120ol_api_current=1
21ol_api_revision=1121ol_api_revision=12
22ol_api_age=122ol_api_age=1
23ol_release_date="2023/07/31"23ol_release_date="2024/01/29"
diff --git a/clients/tools/common.c b/clients/tools/common.c
index b88f219..9dfbb53 100644
--- a/clients/tools/common.c
+++ b/clients/tools/common.c
@@ -1472,10 +1472,11 @@ tool_bind( LDAP *ld )
14721472
1473 } else {1473 } else {
1474 char *pw = getpassphrase( _("Enter LDAP Password: ") );1474 char *pw = getpassphrase( _("Enter LDAP Password: ") );
1475 if ( pw ) {1475 if ( pw == NULL ) { /* Allow EOF to exit. */
1476 passwd.bv_val = ber_strdup( pw );1476 tool_exit( ld, EXIT_FAILURE );
1477 passwd.bv_len = strlen( passwd.bv_val );
1478 }1477 }
1478 passwd.bv_val = ber_strdup( pw );
1479 passwd.bv_len = strlen( passwd.bv_val );
1479 }1480 }
1480 }1481 }
14811482
diff --git a/clients/tools/ldappasswd.c b/clients/tools/ldappasswd.c
index 2cf14d1..036e5e1 100644
--- a/clients/tools/ldappasswd.c
+++ b/clients/tools/ldappasswd.c
@@ -206,7 +206,12 @@ main( int argc, char *argv[] )
206 if( want_oldpw && oldpw.bv_val == NULL ) {206 if( want_oldpw && oldpw.bv_val == NULL ) {
207 /* prompt for old password */207 /* prompt for old password */
208 char *ckoldpw;208 char *ckoldpw;
209 oldpw.bv_val = strdup(getpassphrase(_("Old password: ")));209 ckoldpw = getpassphrase(_("Old password: "));
210 if ( ckoldpw == NULL ) { /* Allow EOF to exit. */
211 rc = EXIT_FAILURE;
212 goto done;
213 }
214 oldpw.bv_val = strdup( ckoldpw );
210 ckoldpw = getpassphrase(_("Re-enter old password: "));215 ckoldpw = getpassphrase(_("Re-enter old password: "));
211216
212 if( oldpw.bv_val == NULL || ckoldpw == NULL ||217 if( oldpw.bv_val == NULL || ckoldpw == NULL ||
@@ -231,7 +236,12 @@ main( int argc, char *argv[] )
231 if( want_newpw && newpw.bv_val == NULL ) {236 if( want_newpw && newpw.bv_val == NULL ) {
232 /* prompt for new password */237 /* prompt for new password */
233 char *cknewpw;238 char *cknewpw;
234 newpw.bv_val = strdup(getpassphrase(_("New password: ")));239 cknewpw = getpassphrase(_("New password: "));
240 if ( cknewpw == NULL ) { /* Allow EOF to exit. */
241 rc = EXIT_FAILURE;
242 goto done;
243 }
244 newpw.bv_val = strdup( cknewpw );
235 cknewpw = getpassphrase(_("Re-enter new password: "));245 cknewpw = getpassphrase(_("Re-enter new password: "));
236246
237 if( newpw.bv_val == NULL || cknewpw == NULL ||247 if( newpw.bv_val == NULL || cknewpw == NULL ||
diff --git a/clients/tools/ldapvc.c b/clients/tools/ldapvc.c
index 4f35025..264f293 100644
--- a/clients/tools/ldapvc.c
+++ b/clients/tools/ldapvc.c
@@ -309,8 +309,13 @@ main( int argc, char *argv[] )
309#endif309#endif
310 && !cred.bv_val)310 && !cred.bv_val)
311 {311 {
312 cred.bv_val = strdup(getpassphrase(_("User's password: ")));312 char *userpw = getpassphrase(_("User's password: "));
313 cred.bv_len = strlen(cred.bv_val);313 if ( userpw == NULL ) /* Allow EOF to exit. */
314 {
315 tool_exit( ld, EXIT_FAILURE );
316 }
317 cred.bv_val = strdup(userpw);
318 cred.bv_len = strlen(cred.bv_val);
314 }319 }
315320
316#ifdef LDAP_API_FEATURE_VERIFY_CREDENTIALS_INTERACTIVE321#ifdef LDAP_API_FEATURE_VERIFY_CREDENTIALS_INTERACTIVE
diff --git a/contrib/slapd-modules/lastmod/lastmod.c b/contrib/slapd-modules/lastmod/lastmod.c
index 116b9ae..b329ef7 100644
--- a/contrib/slapd-modules/lastmod/lastmod.c
+++ b/contrib/slapd-modules/lastmod/lastmod.c
@@ -372,7 +372,7 @@ best_guess( Operation *op,
372 372
373 entryCSN.bv_val = csnbuf;373 entryCSN.bv_val = csnbuf;
374 entryCSN.bv_len = sizeof( csnbuf );374 entryCSN.bv_len = sizeof( csnbuf );
375 slap_get_csn( NULL, &entryCSN, 0 );375 slap_get_csn( op, &entryCSN, 0 );
376376
377 ber_dupbv( bv_entryCSN, &entryCSN );377 ber_dupbv( bv_entryCSN, &entryCSN );
378 ber_dupbv( bv_nentryCSN, &entryCSN );378 ber_dupbv( bv_nentryCSN, &entryCSN );
@@ -833,6 +833,11 @@ lastmod_db_open( BackendDB *be, ConfigReply *cr )
833 static char tmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];833 static char tmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
834834
835 char csnbuf[ LDAP_PVT_CSNSTR_BUFSIZE ];835 char csnbuf[ LDAP_PVT_CSNSTR_BUFSIZE ];
836 void *thrctx = ldap_pvt_thread_pool_context();
837 Connection conn = { 0 };
838 OperationBuffer opbuf;
839 Operation *op;
840
836 struct berval entryCSN;841 struct berval entryCSN;
837 struct berval timestamp;842 struct berval timestamp;
838843
@@ -841,6 +846,9 @@ lastmod_db_open( BackendDB *be, ConfigReply *cr )
841 return -1;846 return -1;
842 }847 }
843848
849 connection_fake_init2( &conn, &opbuf, thrctx, 0 );
850 op = &opbuf.ob_op;
851
844 /*852 /*
845 * Start853 * Start
846 */854 */
@@ -850,7 +858,7 @@ lastmod_db_open( BackendDB *be, ConfigReply *cr )
850858
851 entryCSN.bv_val = csnbuf;859 entryCSN.bv_val = csnbuf;
852 entryCSN.bv_len = sizeof( csnbuf );860 entryCSN.bv_len = sizeof( csnbuf );
853 slap_get_csn( NULL, &entryCSN, 0 );861 slap_get_csn( op, &entryCSN, 0 );
854862
855 if ( BER_BVISNULL( &lmi->lmi_rdnvalue ) ) {863 if ( BER_BVISNULL( &lmi->lmi_rdnvalue ) ) {
856 ber_str2bv( "Lastmod", 0, 1, &lmi->lmi_rdnvalue );864 ber_str2bv( "Lastmod", 0, 1, &lmi->lmi_rdnvalue );
diff --git a/debian/changelog b/debian/changelog
index 96e71ea..5b5eb53 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,22 @@
1openldap (2.5.17+dfsg-0ubuntu0.22.04.1) jammy; urgency=medium
2
3 * New upstream version (LP: #2040465).
4 - Added slapo-dynlist option to disable filter support (ITS#10025)
5 - Fixed liblber missing newline on long msg (ITS#10105)
6 - Fixed libldap exit handling with OpenSSL3 (ITS#9952)
7 - Fixed libldap with TLS and multiple ldap URIs (ITS#10101)
8 - Fixed libldap OpenSSL cipher suite handling (ITS#10094)
9 - Fixed libldap OpenSSL 3.0 and Diffie-Hellman param files (ITS#10124)
10 - Fixed libldap timestamps on Windows (ITS#10100)
11 - Fixed lloadd to work when resolv.conf is missing (ITS#10070)
12 - Fixed lloadd handling of closing connection (ITS#10083)
13 - Fixed slapd to honour disclose in matchedDN handling (ITS#10139)
14 - Fixed slapd handling of regex testing in ACLs (ITS#10089)
15 - Fixed slapd-asyncmeta when remote suffix is empty (ITS#10076)
16 - Fixed slapo-dynlist so it can't be global (ITS#10091)
17
18 -- Sergio Durigan Junior <sergio.durigan@canonical.com> Fri, 09 Feb 2024 15:12:07 -0500
19
1openldap (2.5.16+dfsg-0ubuntu0.22.04.2) jammy-security; urgency=medium20openldap (2.5.16+dfsg-0ubuntu0.22.04.2) jammy-security; urgency=medium
221
3 * No change rebuild to fix CVE-2023-2953 in the -security pocket.22 * No change rebuild to fix CVE-2023-2953 in the -security pocket.
diff --git a/doc/guide/admin/guide.html b/doc/guide/admin/guide.html
index 679b61e..dc31ac2 100644
--- a/doc/guide/admin/guide.html
+++ b/doc/guide/admin/guide.html
@@ -23,7 +23,7 @@
23<DIV CLASS="title">23<DIV CLASS="title">
24<H1 CLASS="doc-title">OpenLDAP Software 2.5 Administrator's Guide</H1>24<H1 CLASS="doc-title">OpenLDAP Software 2.5 Administrator's Guide</H1>
25<ADDRESS CLASS="doc-author">The OpenLDAP Project &lt;<A HREF="https://www.openldap.org/">https://www.openldap.org/</A>&gt;</ADDRESS>25<ADDRESS CLASS="doc-author">The OpenLDAP Project &lt;<A HREF="https://www.openldap.org/">https://www.openldap.org/</A>&gt;</ADDRESS>
26<ADDRESS CLASS="doc-modified">31 July 2023</ADDRESS>26<ADDRESS CLASS="doc-modified">29 January 2024</ADDRESS>
27<BR CLEAR="All">27<BR CLEAR="All">
28</DIV>28</DIV>
29<DIV CLASS="contents">29<DIV CLASS="contents">
diff --git a/doc/man/man5/lloadd.conf.5 b/doc/man/man5/lloadd.conf.5
index 49c72b9..50269b3 100644
--- a/doc/man/man5/lloadd.conf.5
+++ b/doc/man/man5/lloadd.conf.5
@@ -598,7 +598,16 @@ option. The authentication configuration is shared between them.
598.B [secprops=<properties>]598.B [secprops=<properties>]
599.B [timeout=<seconds>]599.B [timeout=<seconds>]
600.B [network\-timeout=<seconds>]600.B [network\-timeout=<seconds>]
601.B [keepalive=<idle>:<probes>:<interval>]
601.B [tcp\-user\-timeout=<milliseconds>]602.B [tcp\-user\-timeout=<milliseconds>]
603.B [tls_cert=<file>]
604.B [tls_key=<file>]
605.B [tls_cacert=<file>]
606.B [tls_cacertdir=<path>]
607.B [tls_reqcert=never|allow|try|demand]
608.B [tls_cipher_suite=<ciphers>]
609.B [tls_crlcheck=none|peer|all]
610.B [tls_protocol_min=<major>[.<minor>]]
602611
603Specifies the bind credentials612Specifies the bind credentials
604.B lloadd613.B lloadd
@@ -658,6 +667,23 @@ Timeout set to 0 means no timeout is in effect and by default, no timeouts are
658in effect.667in effect.
659668
660The669The
670.B keepalive
671parameter sets the values of \fIidle\fP, \fIprobes\fP, and \fIinterval\fP
672used to check whether a socket is alive;
673.I idle
674is the number of seconds a connection needs to remain idle before TCP
675starts sending keepalive probes;
676.I probes
677is the maximum number of keepalive probes TCP should send before dropping
678the connection;
679.I interval
680is interval in seconds between individual keepalive probes.
681Only some systems support the customization of these values;
682the
683.B keepalive
684parameter is ignored otherwise, and system-wide settings are used.
685
686The
661.B tcp\-user\-timeout687.B tcp\-user\-timeout
662parameter, if non-zero, corresponds to the688parameter, if non-zero, corresponds to the
663.B TCP_USER_TIMEOUT689.B TCP_USER_TIMEOUT
@@ -671,16 +697,7 @@ ignored otherwise and system-wide settings are used.
671.B backend-server697.B backend-server
672.B uri=ldap[s]://<hostname>[:port]698.B uri=ldap[s]://<hostname>[:port]
673.B [retry=<retry interval in ms>]699.B [retry=<retry interval in ms>]
674.B [keepalive=<idle>:<probes>:<interval>]
675.B [starttls=yes|critical]700.B [starttls=yes|critical]
676.B [tls_cert=<file>]
677.B [tls_key=<file>]
678.B [tls_cacert=<file>]
679.B [tls_cacertdir=<path>]
680.B [tls_reqcert=never|allow|try|demand]
681.B [tls_cipher_suite=<ciphers>]
682.B [tls_crlcheck=none|peer|all]
683.B [tls_protocol_min=<major>[.<minor>]]
684.B [numconns=<conns>]701.B [numconns=<conns>]
685.B [bindconns=<conns>]702.B [bindconns=<conns>]
686.B [max-pending-ops=<ops>]703.B [max-pending-ops=<ops>]
@@ -725,23 +742,6 @@ connections,
725the default, means no limit will be imposed for this backend.742the default, means no limit will be imposed for this backend.
726743
727The744The
728.B keepalive
729parameter sets the values of \fIidle\fP, \fIprobes\fP, and \fIinterval\fP
730used to check whether a socket is alive;
731.I idle
732is the number of seconds a connection needs to remain idle before TCP
733starts sending keepalive probes;
734.I probes
735is the maximum number of keepalive probes TCP should send before dropping
736the connection;
737.I interval
738is interval in seconds between individual keepalive probes.
739Only some systems support the customization of these values;
740the
741.B keepalive
742parameter is ignored otherwise, and system-wide settings are used.
743
744The
745.B starttls745.B starttls
746parameter specifies use of the StartTLS extended operation746parameter specifies use of the StartTLS extended operation
747to establish a TLS session before Binding to the provider. If the747to establish a TLS session before Binding to the provider. If the
diff --git a/doc/man/man5/slapo-dynlist.5 b/doc/man/man5/slapo-dynlist.5
index 49a3d50..7fe0f70 100644
--- a/doc/man/man5/slapo-dynlist.5
+++ b/doc/man/man5/slapo-dynlist.5
@@ -134,6 +134,13 @@ character is also specified, then the member and memberOf values will be
134populated recursively, for nested groups. Note that currently nesting is134populated recursively, for nested groups. Note that currently nesting is
135only supported for Search operations, not Compares.135only supported for Search operations, not Compares.
136136
137.TP
138.B dynlist\-simple TRUE | FALSE
139This option downgrades to the behavior of the OpenLDAP 2.4 dynlist overlay.
140It disables memberOf processing, nested group support, and filter evaluation
141of dynamically generated values.
142The default is FALSE.
143
137.LP144.LP
138The dynlist overlay may be used with any backend, but it is mainly 145The dynlist overlay may be used with any backend, but it is mainly
139intended for use with local storage backends.146intended for use with local storage backends.
diff --git a/doc/man/man5/slapo-homedir.5 b/doc/man/man5/slapo-homedir.5
index 5cd4ee8..cb1ac5b 100644
--- a/doc/man/man5/slapo-homedir.5
+++ b/doc/man/man5/slapo-homedir.5
@@ -77,7 +77,7 @@ IGNORE.
77.TP77.TP
78.B homedir\-archive\-path <pathname>78.B homedir\-archive\-path <pathname>
79.TP79.TP
80.B olcArchivePath: pathname80.B olcHomedirArchivePath: pathname
81These options specify the destination path for TAR files created by81These options specify the destination path for TAR files created by
82the ARCHIVE delete style.82the ARCHIVE delete style.
83.SH REPLICATION83.SH REPLICATION
@@ -90,6 +90,32 @@ for more information on configure syncrepl.
9090
91Partial replication (e.g. with filters) is especially useful for91Partial replication (e.g. with filters) is especially useful for
92providing different provisioning options to different sets of users.92providing different provisioning options to different sets of users.
93.SH EXAMPLE
94The following LDIF could be used to add this overlay to
95.B cn=config
96(adjust to suit)
97.LP
98.RS
99.nf
100dn: cn=module{0},cn=config
101changetype: modify
102add: olcModuleLoad
103olcModuleLoad: homedir
104
105dn: olcOverlay=homedir,olcDatabase={1}mdb,cn=config
106changetype: add
107objectClass: olcOverlayConfig
108objectClass: olcHomedirConfig
109olcOverlay: homedir
110olcSkeletonPath: /etc/skel
111olcMinimumUidNumber: 1000
112olcHomedirRegexp: ^(/home/[-_/a-z0-9]+)$ /export/$1
113olcHomedirDeleteStyle: ARCHIVE
114olcHomedirArchivePath: /archive
115.fi
116.RE
117.LP
118
93.SH BUGS119.SH BUGS
94DELETE, MOD, and MODRDN operations that remove the unix attributes120DELETE, MOD, and MODRDN operations that remove the unix attributes
95when delete style is set to DELETE will recursively delete the (regex121when delete style is set to DELETE will recursively delete the (regex
@@ -113,6 +139,7 @@ resolve uid/gid into symbolic names.
113139
114No attempt is made to try to mkdir() the parent directories needed for140No attempt is made to try to mkdir() the parent directories needed for
115a given home directory or archive path.141a given home directory or archive path.
142
116.SH FILES143.SH FILES
117.TP144.TP
118ETCDIR/slapd.conf145ETCDIR/slapd.conf
diff --git a/doc/man/man8/slapd.8 b/doc/man/man8/slapd.8
index a93fcbc..809f9e7 100644
--- a/doc/man/man8/slapd.8
+++ b/doc/man/man8/slapd.8
@@ -12,7 +12,7 @@ slapd \- Stand-alone LDAP Daemon
12.BR \-4 | \-6 ]12.BR \-4 | \-6 ]
13[\c13[\c
14.BR \-T \ { acl \||\| a [ dd ]\||\| auth \||\| c [ at ]\||\|14.BR \-T \ { acl \||\| a [ dd ]\||\| auth \||\| c [ at ]\||\|
15.BR d [ n ]\||\| i [ ndex ]\||\| p [ asswd ]\||\| s [ chema ]\||\| t [ est ]}]15.BR d [ n ]\||\| i [ ndex ]\||\| m [ odify ]\||\| p [ asswd ]\||\| s [ chema ]\||\| t [ est ]}]
16[\c16[\c
17.BI \-d \ debug-level\fR]17.BI \-d \ debug-level\fR]
18[\c18[\c
@@ -87,6 +87,7 @@ Run in Tool mode. The \fItool\fP argument selects whether to run as
87.IR slapcat ,87.IR slapcat ,
88.IR slapdn ,88.IR slapdn ,
89.IR slapindex ,89.IR slapindex ,
90.IR slapmodify ,
90.IR slappasswd ,91.IR slappasswd ,
91.IR slapschema ,92.IR slapschema ,
92or93or
@@ -366,6 +367,7 @@ To test whether the configuration file is correct or not, type:
366.BR slapcat (8),367.BR slapcat (8),
367.BR slapdn (8),368.BR slapdn (8),
368.BR slapindex (8),369.BR slapindex (8),
370.BR slapmodify (8),
369.BR slappasswd (8),371.BR slappasswd (8),
370.BR slapschema (8),372.BR slapschema (8),
371.BR slaptest (8).373.BR slaptest (8).
diff --git a/include/ac/string.h b/include/ac/string.h
index c4c1354..20a68d7 100644
--- a/include/ac/string.h
+++ b/include/ac/string.h
@@ -58,7 +58,7 @@ LDAP_F(char *) ldap_pvt_strtok LDAP_P(( char *str,
58#elif !defined(_WIN32)58#elif !defined(_WIN32)
59 /* some systems fail to declare strdup */59 /* some systems fail to declare strdup */
60 /* Windows does not require this declaration */60 /* Windows does not require this declaration */
61 LDAP_LIBC_F(char *) (strdup)();61 LDAP_LIBC_F(char *) (strdup) LDAP_P((const char *s));
62#endif62#endif
6363
64/*64/*
@@ -68,8 +68,8 @@ LDAP_F(char *) ldap_pvt_strtok LDAP_P(( char *str,
6868
69/* we don't want these declared for Windows or Mingw */69/* we don't want these declared for Windows or Mingw */
70#ifndef _WIN3270#ifndef _WIN32
71int (strcasecmp)();71LDAP_LIBC_F(int) (strcasecmp) LDAP_P((const char *s1, const char *s2));
72int (strncasecmp)();72LDAP_LIBC_F(int) (strncasecmp) LDAP_P((const char *s1, const char *s2, size_t n));
73#endif73#endif
7474
75#ifndef SAFEMEMCPY75#ifndef SAFEMEMCPY
diff --git a/libraries/liblber/debug.c b/libraries/liblber/debug.c
index 1744e58..1f4fdbb 100644
--- a/libraries/liblber/debug.c
+++ b/libraries/liblber/debug.c
@@ -43,12 +43,15 @@ void (lutil_debug)( int debug, int level, const char *fmt, ... )
43{43{
44 char buffer[4096];44 char buffer[4096];
45 va_list vl;45 va_list vl;
46 int len;
4647
47 if ( !(level & debug ) ) return;48 if ( !(level & debug ) ) return;
4849
49 va_start( vl, fmt );50 va_start( vl, fmt );
50 vsnprintf( buffer, sizeof(buffer), fmt, vl );51 len = vsnprintf( buffer, sizeof(buffer), fmt, vl );
51 va_end( vl );52 va_end( vl );
53 if ( len >= sizeof(buffer)-2 )
54 buffer[sizeof(buffer)-2] = '\n';
52 ber_pvt_log_print( buffer );55 ber_pvt_log_print( buffer );
53}56}
5457
diff --git a/libraries/libldap/getdn.c b/libraries/libldap/getdn.c
index 6170596..7d8b52f 100644
--- a/libraries/libldap/getdn.c
+++ b/libraries/libldap/getdn.c
@@ -2562,6 +2562,8 @@ rdn2strlen( LDAPRDN rdn, unsigned flags, ber_len_t *len,
2562 l += vl;2562 l += vl;
2563 }2563 }
2564 }2564 }
2565 if ( !iAVA )
2566 return( -1 ); /* RDN ::= SET SIZE (1..MAX) OF AVA */
2565 2567
2566 *len = l;2568 *len = l;
2567 2569
@@ -2635,6 +2637,8 @@ rdn2DCEstrlen( LDAPRDN rdn, unsigned flags, ber_len_t *len )
2635 l += vl;2637 l += vl;
2636 }2638 }
2637 }2639 }
2640 if ( !iAVA )
2641 return( -1 ); /* RDN ::= SET SIZE (1..MAX) OF AVA */
2638 2642
2639 *len = l;2643 *len = l;
2640 2644
@@ -2716,6 +2720,8 @@ rdn2UFNstrlen( LDAPRDN rdn, unsigned flags, ber_len_t *len )
2716 l += vl;2720 l += vl;
2717 }2721 }
2718 }2722 }
2723 if ( !iAVA )
2724 return( -1 ); /* RDN ::= SET SIZE (1..MAX) OF AVA */
2719 2725
2720 *len = l;2726 *len = l;
2721 2727
@@ -2794,6 +2800,8 @@ rdn2ADstrlen( LDAPRDN rdn, unsigned flags, ber_len_t *len )
2794 l += vl;2800 l += vl;
2795 }2801 }
2796 }2802 }
2803 if ( !iAVA )
2804 return( -1 ); /* RDN ::= SET SIZE (1..MAX) OF AVA */
2797 2805
2798 *len = l;2806 *len = l;
2799 2807
diff --git a/libraries/libldap/init.c b/libraries/libldap/init.c
index 3a81790..b991553 100644
--- a/libraries/libldap/init.c
+++ b/libraries/libldap/init.c
@@ -544,9 +544,6 @@ ldap_int_destroy_global_options(void)
544 gopts->ldo_def_sasl_authcid = NULL;544 gopts->ldo_def_sasl_authcid = NULL;
545 }545 }
546#endif546#endif
547#ifdef HAVE_TLS
548 ldap_int_tls_destroy( gopts );
549#endif
550}547}
551548
552/* 549/*
diff --git a/libraries/libldap/open.c b/libraries/libldap/open.c
index bfdbb25..93720eb 100644
--- a/libraries/libldap/open.c
+++ b/libraries/libldap/open.c
@@ -543,6 +543,7 @@ ldap_int_open_connection(
543 LDAP_MUTEX_UNLOCK( &lo->ldo_mutex );543 LDAP_MUTEX_UNLOCK( &lo->ldo_mutex );
544 }544 }
545 ber_int_sb_close( conn->lconn_sb );545 ber_int_sb_close( conn->lconn_sb );
546 ber_int_sb_destroy( conn->lconn_sb );
546 return -1;547 return -1;
547 }548 }
548 }549 }
diff --git a/libraries/libldap/tls2.c b/libraries/libldap/tls2.c
index 4a5d42b..f9dcbfc 100644
--- a/libraries/libldap/tls2.c
+++ b/libraries/libldap/tls2.c
@@ -160,6 +160,14 @@ ldap_pvt_tls_destroy( void )
160 tls_imp->ti_tls_destroy();160 tls_imp->ti_tls_destroy();
161}161}
162162
163static void
164ldap_exit_tls_destroy( void )
165{
166 struct ldapoptions *lo = LDAP_INT_GLOBAL_OPT();
167
168 ldap_int_tls_destroy( lo );
169}
170
163/*171/*
164 * Initialize a particular TLS implementation.172 * Initialize a particular TLS implementation.
165 * Called once per implementation.173 * Called once per implementation.
@@ -168,6 +176,7 @@ static int
168tls_init(tls_impl *impl, int do_threads )176tls_init(tls_impl *impl, int do_threads )
169{177{
170 static int tls_initialized = 0;178 static int tls_initialized = 0;
179 int rc;
171180
172 if ( !tls_initialized++ ) {181 if ( !tls_initialized++ ) {
173#ifdef LDAP_R_COMPILE182#ifdef LDAP_R_COMPILE
@@ -183,7 +192,10 @@ tls_init(tls_impl *impl, int do_threads )
183#endif192#endif
184 }193 }
185194
186 return impl->ti_tls_init();195 rc = impl->ti_tls_init();
196
197 atexit( ldap_exit_tls_destroy );
198 return rc;
187}199}
188200
189/*201/*
diff --git a/libraries/libldap/tls_o.c b/libraries/libldap/tls_o.c
index d6405bc..055d140 100644
--- a/libraries/libldap/tls_o.c
+++ b/libraries/libldap/tls_o.c
@@ -294,7 +294,7 @@ tlso_stecpy( char *dst, const char *src, const char *end )
294 * Try to find any TLS1.3 ciphers in the given list of suites.294 * Try to find any TLS1.3 ciphers in the given list of suites.
295 */295 */
296static void296static void
297tlso_ctx_cipher13( tlso_ctx *ctx, char *suites )297tlso_ctx_cipher13( tlso_ctx *ctx, char *suites, char **oldsuites )
298{298{
299 char tls13_suites[1024], *ts = tls13_suites, *te = tls13_suites + sizeof(tls13_suites);299 char tls13_suites[1024], *ts = tls13_suites, *te = tls13_suites + sizeof(tls13_suites);
300 char *ptr, *colon, *nptr;300 char *ptr, *colon, *nptr;
@@ -303,6 +303,8 @@ tlso_ctx_cipher13( tlso_ctx *ctx, char *suites )
303 SSL *s = SSL_new( ctx );303 SSL *s = SSL_new( ctx );
304 int ret;304 int ret;
305305
306 *oldsuites = NULL;
307
306 if ( !s )308 if ( !s )
307 return;309 return;
308310
@@ -334,8 +336,15 @@ tlso_ctx_cipher13( tlso_ctx *ctx, char *suites )
334 if ( tls13_suites[0] )336 if ( tls13_suites[0] )
335 ts = tlso_stecpy( ts, ":", te );337 ts = tlso_stecpy( ts, ":", te );
336 ts = tlso_stecpy( ts, nptr, te );338 ts = tlso_stecpy( ts, nptr, te );
339 } else if (! *oldsuites) {
340 /* should never happen, set_ciphersuites should
341 * only succeed for TLSv1.3 and above
342 */
343 *oldsuites = ptr;
337 }344 }
338 }345 }
346 } else if (! *oldsuites) {
347 *oldsuites = ptr;
339 }348 }
340 if ( !colon || ts >= te )349 if ( !colon || ts >= te )
341 break;350 break;
@@ -415,10 +424,11 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
415 }424 }
416425
417 if ( lo->ldo_tls_ciphersuite ) {426 if ( lo->ldo_tls_ciphersuite ) {
427 char *oldsuites = lt->lt_ciphersuite;
418#if OPENSSL_VERSION_NUMBER >= 0x10101000428#if OPENSSL_VERSION_NUMBER >= 0x10101000
419 tlso_ctx_cipher13( ctx, lt->lt_ciphersuite );429 tlso_ctx_cipher13( ctx, lt->lt_ciphersuite, &oldsuites );
420#endif430#endif
421 if ( !SSL_CTX_set_cipher_list( ctx, lt->lt_ciphersuite ) )431 if ( oldsuites && !SSL_CTX_set_cipher_list( ctx, oldsuites ) )
422 {432 {
423 Debug1( LDAP_DEBUG_ANY,433 Debug1( LDAP_DEBUG_ANY,
424 "TLS: could not set cipher list %s.\n",434 "TLS: could not set cipher list %s.\n",
@@ -529,7 +539,7 @@ tlso_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server )
529 if ( is_server && lo->ldo_tls_dhfile ) {539 if ( is_server && lo->ldo_tls_dhfile ) {
530#if OPENSSL_VERSION_MAJOR >= 3540#if OPENSSL_VERSION_MAJOR >= 3
531 EVP_PKEY *dh;541 EVP_PKEY *dh;
532#define bio_params( bio, dh ) dh = PEM_read_bio_Parameters( bio, &dh )542#define bio_params( bio, dh ) dh = PEM_read_bio_Parameters( bio, NULL )
533#else543#else
534 DH *dh;544 DH *dh;
535#define bio_params( bio, dh ) dh = PEM_read_bio_DHparams( bio, NULL, NULL, NULL )545#define bio_params( bio, dh ) dh = PEM_read_bio_DHparams( bio, NULL, NULL, NULL )
diff --git a/libraries/libldap/url.c b/libraries/libldap/url.c
index 493fd7c..a56af30 100644
--- a/libraries/libldap/url.c
+++ b/libraries/libldap/url.c
@@ -867,6 +867,10 @@ ldap_url_parse_ext( LDAP_CONST char *url_in, LDAPURLDesc **ludpp, unsigned flags
867 }867 }
868868
869 if ( enclosed ) {869 if ( enclosed ) {
870 if ( ! *url ) {
871 LDAP_FREE( url );
872 return LDAP_URL_ERR_BADENCLOSURE;
873 }
870 p = &url[strlen(url)-1];874 p = &url[strlen(url)-1];
871875
872 if( *p != '>' ) {876 if( *p != '>' ) {
diff --git a/libraries/libldap/util-int.c b/libraries/libldap/util-int.c
index 57c6523..7cab9ea 100644
--- a/libraries/libldap/util-int.c
+++ b/libraries/libldap/util-int.c
@@ -182,116 +182,65 @@ static int _ldap_pvt_gt_subs;
182 * This is pretty clunky.182 * This is pretty clunky.
183 */183 */
184static LARGE_INTEGER _ldap_pvt_gt_freq;184static LARGE_INTEGER _ldap_pvt_gt_freq;
185static LARGE_INTEGER _ldap_pvt_gt_prev;185static LARGE_INTEGER _ldap_pvt_gt_start_count;
186static int _ldap_pvt_gt_offset;186static long _ldap_pvt_gt_start_sec;
187static long _ldap_pvt_gt_start_nsec;
188static double _ldap_pvt_gt_nanoticks;
187189
188#define SEC_TO_UNIX_EPOCH 11644473600LL190#define SEC_TO_UNIX_EPOCH 11644473600LL
189#define TICKS_PER_SECOND 10000000191#define TICKS_PER_SECOND 10000000
190#define BILLION 1000000000L192#define BILLION 1000000000L
191193
192static int194static int
193ldap_pvt_gettimensec(int *sec)195ldap_pvt_gettimensec(long *sec)
194{196{
195 LARGE_INTEGER count;197 LARGE_INTEGER count;
198 LARGE_INTEGER freq;
199 int nsec;
196200
197 QueryPerformanceCounter( &count );201 QueryPerformanceFrequency( &freq );
198
199 /* It shouldn't ever go backwards, but multiple CPUs might
200 * be able to hit in the same tick.
201 */
202 LDAP_MUTEX_LOCK( &ldap_int_gettime_mutex );
203 /* We assume Windows has at least a vague idea of202 /* We assume Windows has at least a vague idea of
204 * when a second begins. So we align our nanosecond count203 * when a second begins. So we align our nanosecond count
205 * with the Windows millisecond count using this offset.204 * with the Windows millisecond count.
206 * We retain the submillisecond portion of our own count.
207 *
208 * Note - this also assumes that the relationship between
209 * the PerformanceCounter and SystemTime stays constant;
210 * that assumption breaks if the SystemTime is adjusted by
211 * an external action.
212 */205 */
213 if ( !_ldap_pvt_gt_freq.QuadPart ) {206 if ( freq.QuadPart != _ldap_pvt_gt_freq.QuadPart ) {
214 LARGE_INTEGER c2;
215 ULARGE_INTEGER ut;207 ULARGE_INTEGER ut;
216 FILETIME ft0, ft1;208 FILETIME ft0, ft1;
217 long long t;209 /* initialize */
218 int nsec;210 LDAP_MUTEX_LOCK( &ldap_int_gettime_mutex );
219
220 /* Initialize our offset */
221 QueryPerformanceFrequency( &_ldap_pvt_gt_freq );
222
223 /* Wait for a tick of the system time: 10-15ms */211 /* Wait for a tick of the system time: 10-15ms */
224 GetSystemTimeAsFileTime( &ft0 );212 GetSystemTimeAsFileTime( &ft0 );
225 do {213 do {
226 GetSystemTimeAsFileTime( &ft1 );214 GetSystemTimeAsFileTime( &ft1 );
227 } while ( ft1.dwLowDateTime == ft0.dwLowDateTime );215 } while ( ft1.dwLowDateTime == ft0.dwLowDateTime );
216 QueryPerformanceCounter( &_ldap_pvt_gt_start_count );
228217
229 ut.LowPart = ft1.dwLowDateTime;218 ut.LowPart = ft1.dwLowDateTime;
230 ut.HighPart = ft1.dwHighDateTime;219 ut.HighPart = ft1.dwHighDateTime;
231 QueryPerformanceCounter( &c2 );220 _ldap_pvt_gt_start_nsec = ut.QuadPart % TICKS_PER_SECOND * 100;
232221 _ldap_pvt_gt_start_sec = ut.QuadPart / TICKS_PER_SECOND - SEC_TO_UNIX_EPOCH;
233 /* get second and fraction portion of counter */222 _ldap_pvt_gt_freq = freq;
234 t = c2.QuadPart % (_ldap_pvt_gt_freq.QuadPart*10);223 _ldap_pvt_gt_nanoticks = (double)BILLION / freq.QuadPart;
235224 LDAP_MUTEX_UNLOCK( &ldap_int_gettime_mutex );
236 /* convert to nanoseconds */
237 t *= BILLION;
238 nsec = t / _ldap_pvt_gt_freq.QuadPart;
239
240 ut.QuadPart /= 10;
241 ut.QuadPart %= (10 * BILLION);
242 _ldap_pvt_gt_offset = nsec - ut.QuadPart;
243 count = c2;
244 }225 }
245 if ( count.QuadPart <= _ldap_pvt_gt_prev.QuadPart ) {226 QueryPerformanceCounter( &count );
246 _ldap_pvt_gt_subs++;227 count.QuadPart -= _ldap_pvt_gt_start_count.QuadPart;
247 } else {228 *sec = _ldap_pvt_gt_start_sec + count.QuadPart / freq.QuadPart;
248 _ldap_pvt_gt_subs = 0;229 nsec = _ldap_pvt_gt_start_nsec + (double)(count.QuadPart % freq.QuadPart) * _ldap_pvt_gt_nanoticks;
249 _ldap_pvt_gt_prev = count;230 if ( nsec > BILLION) {
231 nsec -= BILLION;
232 (*sec)++;
250 }233 }
251 LDAP_MUTEX_UNLOCK( &ldap_int_gettime_mutex );234 return nsec;
252
253 /* convert to nanoseconds */
254 count.QuadPart %= _ldap_pvt_gt_freq.QuadPart*10;
255 count.QuadPart *= BILLION;
256 count.QuadPart /= _ldap_pvt_gt_freq.QuadPart;
257 count.QuadPart -= _ldap_pvt_gt_offset;
258
259 /* We've extracted the 1s and nanoseconds.
260 * The 1sec digit is used to detect wraparound in nanosecnds.
261 */
262 if (count.QuadPart < 0)
263 count.QuadPart += (10 * BILLION);
264 else if (count.QuadPart >= (10 * BILLION))
265 count.QuadPart -= (10 * BILLION);
266
267 *sec = count.QuadPart / BILLION;
268 return count.QuadPart % BILLION;
269}235}
270236
271
272/* emulate POSIX clock_gettime */237/* emulate POSIX clock_gettime */
273int238int
274ldap_pvt_clock_gettime( int clk_id, struct timespec *tv )239ldap_pvt_clock_gettime( int clk_id, struct timespec *tv )
275{240{
276 FILETIME ft;241 long sec;
277 ULARGE_INTEGER ut;242 tv->tv_nsec = ldap_pvt_gettimensec( &sec );
278 int sec, sec0;243 tv->tv_sec = sec;
279
280 GetSystemTimeAsFileTime( &ft );
281 ut.LowPart = ft.dwLowDateTime;
282 ut.HighPart = ft.dwHighDateTime;
283
284 /* convert to sec */
285 ut.QuadPart /= TICKS_PER_SECOND;
286
287 tv->tv_nsec = ldap_pvt_gettimensec(&sec);
288 tv->tv_sec = ut.QuadPart - SEC_TO_UNIX_EPOCH;
289
290 /* check for carry from microseconds */
291 sec0 = tv->tv_sec % 10;
292 if (sec0 < sec || (sec0 == 9 && !sec))
293 tv->tv_sec++;
294
295 return 0;244 return 0;
296}245}
297246
@@ -306,6 +255,8 @@ ldap_pvt_gettimeofday( struct timeval *tv, void *unused )
306 return 0;255 return 0;
307}256}
308257
258static long _ldap_pvt_gt_prevsec;
259static int _ldap_pvt_gt_prevnsec;
309260
310/* return a broken out time, with nanoseconds261/* return a broken out time, with nanoseconds
311 */262 */
@@ -313,17 +264,18 @@ void
313ldap_pvt_gettime( struct lutil_tm *tm )264ldap_pvt_gettime( struct lutil_tm *tm )
314{265{
315 SYSTEMTIME st;266 SYSTEMTIME st;
316 int sec, sec0;267 LARGE_INTEGER ft;
317 static const char daysPerMonth[] = {268 long sec;
318 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
319269
320 GetSystemTime( &st );270 /* Convert sec/nsec to Windows FILETIME,
271 * then turn that into broken out SYSTEMTIME */
321 tm->tm_nsec = ldap_pvt_gettimensec(&sec);272 tm->tm_nsec = ldap_pvt_gettimensec(&sec);
322 tm->tm_usub = _ldap_pvt_gt_subs;273 ft.QuadPart = sec;
274 ft.QuadPart += SEC_TO_UNIX_EPOCH;
275 ft.QuadPart *= TICKS_PER_SECOND;
276 ft.QuadPart += tm->tm_nsec / 100;
277 FileTimeToSystemTime( (FILETIME *)&ft, &st );
323278
324 /* any difference larger than nanoseconds is
325 * already reflected in st
326 */
327 tm->tm_sec = st.wSecond;279 tm->tm_sec = st.wSecond;
328 tm->tm_min = st.wMinute;280 tm->tm_min = st.wMinute;
329 tm->tm_hour = st.wHour;281 tm->tm_hour = st.wHour;
@@ -331,42 +283,18 @@ ldap_pvt_gettime( struct lutil_tm *tm )
331 tm->tm_mon = st.wMonth - 1;283 tm->tm_mon = st.wMonth - 1;
332 tm->tm_year = st.wYear - 1900;284 tm->tm_year = st.wYear - 1900;
333285
334 /* check for carry from nanoseconds */286 LDAP_MUTEX_LOCK( &ldap_int_gettime_mutex );
335 sec0 = tm->tm_sec % 10;287 if ( tm->tm_sec < _ldap_pvt_gt_prevsec
336 if (sec0 < sec || (sec0 == 9 && !sec)) {288 || ( tm->tm_sec == _ldap_pvt_gt_prevsec
337 tm->tm_sec++;289 && tm->tm_nsec <= _ldap_pvt_gt_prevnsec )) {
338 /* FIXME: we don't handle leap seconds */290 _ldap_pvt_gt_subs++;
339 if (tm->tm_sec > 59) {291 } else {
340 tm->tm_sec = 0;292 _ldap_pvt_gt_subs = 0;
341 tm->tm_min++;293 _ldap_pvt_gt_prevsec = sec;
342 if (tm->tm_min > 59) {294 _ldap_pvt_gt_prevnsec = tm->tm_nsec;
343 tm->tm_min = 0;
344 tm->tm_hour++;
345 if (tm->tm_hour > 23) {
346 int days = daysPerMonth[tm->tm_mon];
347 tm->tm_hour = 0;
348 tm->tm_mday++;
349
350 /* if it's February of a leap year,
351 * add 1 day to this month
352 */
353 if (tm->tm_mon == 1 &&
354 ((!(st.wYear % 4) && (st.wYear % 100)) ||
355 !(st.wYear % 400)))
356 days++;
357
358 if (tm->tm_mday > days) {
359 tm->tm_mday = 1;
360 tm->tm_mon++;
361 if (tm->tm_mon > 11) {
362 tm->tm_mon = 0;
363 tm->tm_year++;
364 }
365 }
366 }
367 }
368 }
369 }295 }
296 LDAP_MUTEX_UNLOCK( &ldap_int_gettime_mutex );
297 tm->tm_usub = _ldap_pvt_gt_subs;
370}298}
371#else299#else
372300
diff --git a/libraries/liblmdb/CHANGES b/libraries/liblmdb/CHANGES
index 76dd591..10e81d5 100644
--- a/libraries/liblmdb/CHANGES
+++ b/libraries/liblmdb/CHANGES
@@ -1,5 +1,11 @@
1LMDB 0.9 Change Log1LMDB 0.9 Change Log
22
3LMDB 0.9.32 Release (2024/01/29)
4 ITS#9378 - Add ability to replay log and replay log tool
5 ITS#10095 - partial revert of ITS#9278. The patch was incorrect and introduced numerous race conditions.
6 ITS#10125 - mdb_load: fix cursor reinit in Append mode
7 ITS#10137 - Allow users to define MDB_IDL_LOGN
8
3LMDB 0.9.31 Release (2023/07/10)9LMDB 0.9.31 Release (2023/07/10)
4 ITS#8447 - Fix cursor_put(MDB_CURRENT) on DUPSORT DB with different sized data10 ITS#8447 - Fix cursor_put(MDB_CURRENT) on DUPSORT DB with different sized data
511
diff --git a/libraries/liblmdb/Makefile b/libraries/liblmdb/Makefile
index f254511..000f1f9 100644
--- a/libraries/liblmdb/Makefile
+++ b/libraries/liblmdb/Makefile
@@ -78,6 +78,7 @@ mtest3: mtest3.o liblmdb.a
78mtest4: mtest4.o liblmdb.a78mtest4: mtest4.o liblmdb.a
79mtest5: mtest5.o liblmdb.a79mtest5: mtest5.o liblmdb.a
80mtest6: mtest6.o liblmdb.a80mtest6: mtest6.o liblmdb.a
81mplay: mplay.o liblmdb.a
8182
82mdb.o: mdb.c lmdb.h midl.h83mdb.o: mdb.c lmdb.h midl.h
83 $(CC) $(CFLAGS) $(CPPFLAGS) -c mdb.c84 $(CC) $(CFLAGS) $(CPPFLAGS) -c mdb.c
diff --git a/libraries/liblmdb/lmdb.h b/libraries/liblmdb/lmdb.h
index ff03c22..d638a67 100644
--- a/libraries/liblmdb/lmdb.h
+++ b/libraries/liblmdb/lmdb.h
@@ -200,7 +200,7 @@ typedef int mdb_filehandle_t;
200/** Library minor version */200/** Library minor version */
201#define MDB_VERSION_MINOR 9201#define MDB_VERSION_MINOR 9
202/** Library patch version */202/** Library patch version */
203#define MDB_VERSION_PATCH 31203#define MDB_VERSION_PATCH 32
204204
205/** Combine args a,b,c into a single integer for easy version comparisons */205/** Combine args a,b,c into a single integer for easy version comparisons */
206#define MDB_VERINT(a,b,c) (((a) << 24) | ((b) << 16) | (c))206#define MDB_VERINT(a,b,c) (((a) << 24) | ((b) << 16) | (c))
@@ -210,7 +210,7 @@ typedef int mdb_filehandle_t;
210 MDB_VERINT(MDB_VERSION_MAJOR,MDB_VERSION_MINOR,MDB_VERSION_PATCH)210 MDB_VERINT(MDB_VERSION_MAJOR,MDB_VERSION_MINOR,MDB_VERSION_PATCH)
211211
212/** The release date of this library version */212/** The release date of this library version */
213#define MDB_VERSION_DATE "July 10, 2023"213#define MDB_VERSION_DATE "January 29, 2024"
214214
215/** A stringifier for the version info */215/** A stringifier for the version info */
216#define MDB_VERSTR(a,b,c,d) "LMDB " #a "." #b "." #c ": (" d ")"216#define MDB_VERSTR(a,b,c,d) "LMDB " #a "." #b "." #c ": (" d ")"
diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c
index deb6779..0570dea 100644
--- a/libraries/liblmdb/mdb.c
+++ b/libraries/liblmdb/mdb.c
@@ -481,18 +481,26 @@ typedef MDB_ID txnid_t;
481#define MDB_DEBUG 0481#define MDB_DEBUG 0
482#endif482#endif
483483
484#define MDB_DBG_INFO 1
485#define MDB_DBG_TRACE 2
486
484#if MDB_DEBUG487#if MDB_DEBUG
485static int mdb_debug;488static int mdb_debug = MDB_DBG_TRACE;
486static txnid_t mdb_debug_start;489static txnid_t mdb_debug_start;
487490
488 /** Print a debug message with printf formatting.491 /** Print a debug message with printf formatting.
489 * Requires double parenthesis around 2 or more args.492 * Requires double parenthesis around 2 or more args.
490 */493 */
491# define DPRINTF(args) ((void) ((mdb_debug) && DPRINTF0 args))494# define DPRINTF(args) ((void) ((mdb_debug & MDB_DBG_INFO) && DPRINTF0 args))
492# define DPRINTF0(fmt, ...) \495# define DPRINTF0(fmt, ...) \
493 fprintf(stderr, "%s:%d " fmt "\n", mdb_func_, __LINE__, __VA_ARGS__)496 fprintf(stderr, "%s:%d " fmt "\n", mdb_func_, __LINE__, __VA_ARGS__)
497 /** Trace info for replaying */
498# define MDB_TRACE(args) ((void) ((mdb_debug & MDB_DBG_TRACE) && DPRINTF1 args))
499# define DPRINTF1(fmt, ...) \
500 fprintf(stderr, ">%d:%s: " fmt "\n", getpid(), mdb_func_, __VA_ARGS__)
494#else501#else
495# define DPRINTF(args) ((void) 0)502# define DPRINTF(args) ((void) 0)
503# define MDB_TRACE(args) ((void) 0)
496#endif504#endif
497 /** Print a debug string.505 /** Print a debug string.
498 * The string is printed literally, with no format processing.506 * The string is printed literally, with no format processing.
@@ -589,6 +597,11 @@ static txnid_t mdb_debug_start;
589 * This is used for printing a hex dump of a key's contents.597 * This is used for printing a hex dump of a key's contents.
590 */598 */
591#define DKBUF char kbuf[DKBUF_MAXKEYSIZE*2+1]599#define DKBUF char kbuf[DKBUF_MAXKEYSIZE*2+1]
600 /** A data value buffer.
601 * @ingroup debug
602 * This is used for printing a hex dump of a #MDB_DUPSORT value's contents.
603 */
604#define DDBUF char dbuf[DKBUF_MAXKEYSIZE*2+1+2]
592 /** Display a key in hex.605 /** Display a key in hex.
593 * @ingroup debug606 * @ingroup debug
594 * Invoke a function to display a key in hex.607 * Invoke a function to display a key in hex.
@@ -596,6 +609,7 @@ static txnid_t mdb_debug_start;
596#define DKEY(x) mdb_dkey(x, kbuf)609#define DKEY(x) mdb_dkey(x, kbuf)
597#else610#else
598#define DKBUF611#define DKBUF
612#define DDBUF
599#define DKEY(x) 0613#define DKEY(x) 0
600#endif614#endif
601615
@@ -1423,6 +1437,9 @@ static int mdb_update_key(MDB_cursor *mc, MDB_val *key);
1423static void mdb_cursor_pop(MDB_cursor *mc);1437static void mdb_cursor_pop(MDB_cursor *mc);
1424static int mdb_cursor_push(MDB_cursor *mc, MDB_page *mp);1438static int mdb_cursor_push(MDB_cursor *mc, MDB_page *mp);
14251439
1440static int _mdb_cursor_del(MDB_cursor *mc, unsigned int flags);
1441static int _mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data, unsigned int flags);
1442
1426static int mdb_cursor_del0(MDB_cursor *mc);1443static int mdb_cursor_del0(MDB_cursor *mc);
1427static int mdb_del0(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data, unsigned flags);1444static int mdb_del0(MDB_txn *txn, MDB_dbi dbi, MDB_val *key, MDB_val *data, unsigned flags);
1428static int mdb_cursor_sibling(MDB_cursor *mc, int move_right);1445static int mdb_cursor_sibling(MDB_cursor *mc, int move_right);
@@ -1614,6 +1631,18 @@ mdb_dkey(MDB_val *key, char *buf)
1614 return buf;1631 return buf;
1615}1632}
16161633
1634static char *
1635mdb_dval(MDB_txn *txn, MDB_dbi dbi, MDB_val *data, char *buf)
1636{
1637 if (txn->mt_dbs[dbi].md_flags & MDB_DUPSORT) {
1638 mdb_dkey(data, buf+1);
1639 *buf = '[';
1640 strcpy(buf + data->mv_size * 2 + 1, "]");
1641 } else
1642 *buf = '\0';
1643 return buf;
1644}
1645
1617static const char *1646static const char *
1618mdb_leafnode_type(MDB_node *n)1647mdb_leafnode_type(MDB_node *n)
1619{1648{
@@ -2786,7 +2815,7 @@ mdb_txn_renew0(MDB_txn *txn)
2786 txn->mt_txnid++;2815 txn->mt_txnid++;
2787#if MDB_DEBUG2816#if MDB_DEBUG
2788 if (txn->mt_txnid == mdb_debug_start)2817 if (txn->mt_txnid == mdb_debug_start)
2789 mdb_debug = 1;2818 mdb_debug = MDB_DBG_INFO;
2790#endif2819#endif
2791 txn->mt_child = NULL;2820 txn->mt_child = NULL;
2792 txn->mt_loose_pgs = NULL;2821 txn->mt_loose_pgs = NULL;
@@ -2945,6 +2974,7 @@ renew:
2945 txn->mt_txnid, (flags & MDB_RDONLY) ? 'r' : 'w',2974 txn->mt_txnid, (flags & MDB_RDONLY) ? 'r' : 'w',
2946 (void *) txn, (void *) env, txn->mt_dbs[MAIN_DBI].md_root));2975 (void *) txn, (void *) env, txn->mt_dbs[MAIN_DBI].md_root));
2947 }2976 }
2977 MDB_TRACE(("%p, %p, %u = %p", env, parent, flags, txn));
29482978
2949 return rc;2979 return rc;
2950}2980}
@@ -3080,18 +3110,25 @@ mdb_txn_reset(MDB_txn *txn)
3080 mdb_txn_end(txn, MDB_END_RESET);3110 mdb_txn_end(txn, MDB_END_RESET);
3081}3111}
30823112
3083void3113static void
3084mdb_txn_abort(MDB_txn *txn)3114_mdb_txn_abort(MDB_txn *txn)
3085{3115{
3086 if (txn == NULL)3116 if (txn == NULL)
3087 return;3117 return;
30883118
3089 if (txn->mt_child)3119 if (txn->mt_child)
3090 mdb_txn_abort(txn->mt_child);3120 _mdb_txn_abort(txn->mt_child);
30913121
3092 mdb_txn_end(txn, MDB_END_ABORT|MDB_END_SLOT|MDB_END_FREE);3122 mdb_txn_end(txn, MDB_END_ABORT|MDB_END_SLOT|MDB_END_FREE);
3093}3123}
30943124
3125void
3126mdb_txn_abort(MDB_txn *txn)
3127{
3128 MDB_TRACE(("%p", txn));
3129 _mdb_txn_abort(txn);
3130}
3131
3095/** Save the freelist as of this transaction to the freeDB.3132/** Save the freelist as of this transaction to the freeDB.
3096 * This changes the freelist. Keep trying until it stabilizes.3133 * This changes the freelist. Keep trying until it stabilizes.
3097 */3134 */
@@ -3182,7 +3219,7 @@ mdb_freelist_save(MDB_txn *txn)
3182 pglast = head_id = *(txnid_t *)key.mv_data;3219 pglast = head_id = *(txnid_t *)key.mv_data;
3183 total_room = head_room = 0;3220 total_room = head_room = 0;
3184 mdb_tassert(txn, pglast <= env->me_pglast);3221 mdb_tassert(txn, pglast <= env->me_pglast);
3185 rc = mdb_cursor_del(&mc, 0);3222 rc = _mdb_cursor_del(&mc, 0);
3186 if (rc)3223 if (rc)
3187 return rc;3224 return rc;
3188 }3225 }
@@ -3202,7 +3239,7 @@ mdb_freelist_save(MDB_txn *txn)
3202 do {3239 do {
3203 freecnt = free_pgs[0];3240 freecnt = free_pgs[0];
3204 data.mv_size = MDB_IDL_SIZEOF(free_pgs);3241 data.mv_size = MDB_IDL_SIZEOF(free_pgs);
3205 rc = mdb_cursor_put(&mc, &key, &data, MDB_RESERVE);3242 rc = _mdb_cursor_put(&mc, &key, &data, MDB_RESERVE);
3206 if (rc)3243 if (rc)
3207 return rc;3244 return rc;
3208 /* Retry if mt_free_pgs[] grew during the Put() */3245 /* Retry if mt_free_pgs[] grew during the Put() */
@@ -3251,7 +3288,7 @@ mdb_freelist_save(MDB_txn *txn)
3251 key.mv_size = sizeof(head_id);3288 key.mv_size = sizeof(head_id);
3252 key.mv_data = &head_id;3289 key.mv_data = &head_id;
3253 data.mv_size = (head_room + 1) * sizeof(pgno_t);3290 data.mv_size = (head_room + 1) * sizeof(pgno_t);
3254 rc = mdb_cursor_put(&mc, &key, &data, MDB_RESERVE);3291 rc = _mdb_cursor_put(&mc, &key, &data, MDB_RESERVE);
3255 if (rc)3292 if (rc)
3256 return rc;3293 return rc;
3257 /* IDL is initially empty, zero out at least the length */3294 /* IDL is initially empty, zero out at least the length */
@@ -3306,7 +3343,7 @@ mdb_freelist_save(MDB_txn *txn)
3306 data.mv_data = mop -= len;3343 data.mv_data = mop -= len;
3307 save = mop[0];3344 save = mop[0];
3308 mop[0] = len;3345 mop[0] = len;
3309 rc = mdb_cursor_put(&mc, &key, &data, MDB_CURRENT);3346 rc = _mdb_cursor_put(&mc, &key, &data, MDB_CURRENT);
3310 mop[0] = save;3347 mop[0] = save;
3311 if (rc || !(mop_len -= len))3348 if (rc || !(mop_len -= len))
3312 break;3349 break;
@@ -3467,8 +3504,8 @@ done:
3467 return MDB_SUCCESS;3504 return MDB_SUCCESS;
3468}3505}
34693506
3470int3507static int
3471mdb_txn_commit(MDB_txn *txn)3508_mdb_txn_commit(MDB_txn *txn)
3472{3509{
3473 int rc;3510 int rc;
3474 unsigned int i, end_mode;3511 unsigned int i, end_mode;
@@ -3481,7 +3518,7 @@ mdb_txn_commit(MDB_txn *txn)
3481 end_mode = MDB_END_EMPTY_COMMIT|MDB_END_UPDATE|MDB_END_SLOT|MDB_END_FREE;3518 end_mode = MDB_END_EMPTY_COMMIT|MDB_END_UPDATE|MDB_END_SLOT|MDB_END_FREE;
34823519
3483 if (txn->mt_child) {3520 if (txn->mt_child) {
3484 rc = mdb_txn_commit(txn->mt_child);3521 rc = _mdb_txn_commit(txn->mt_child);
3485 if (rc)3522 if (rc)
3486 goto fail;3523 goto fail;
3487 }3524 }
@@ -3661,7 +3698,7 @@ mdb_txn_commit(MDB_txn *txn)
3661 goto fail;3698 goto fail;
3662 }3699 }
3663 data.mv_data = &txn->mt_dbs[i];3700 data.mv_data = &txn->mt_dbs[i];
3664 rc = mdb_cursor_put(&mc, &txn->mt_dbxs[i].md_name, &data,3701 rc = _mdb_cursor_put(&mc, &txn->mt_dbxs[i].md_name, &data,
3665 F_SUBDATA);3702 F_SUBDATA);
3666 if (rc)3703 if (rc)
3667 goto fail;3704 goto fail;
@@ -3692,10 +3729,17 @@ done:
3692 return MDB_SUCCESS;3729 return MDB_SUCCESS;
36933730
3694fail:3731fail:
3695 mdb_txn_abort(txn);3732 _mdb_txn_abort(txn);
3696 return rc;3733 return rc;
3697}3734}
36983735
3736int
3737mdb_txn_commit(MDB_txn *txn)
3738{
3739 MDB_TRACE(("%p", txn));
3740 return _mdb_txn_commit(txn);
3741}
3742
3699/** Read the environment parameters of a DB environment before3743/** Read the environment parameters of a DB environment before
3700 * mapping it into memory.3744 * mapping it into memory.
3701 * @param[in] env the environment handle3745 * @param[in] env the environment handle
@@ -3992,6 +4036,7 @@ mdb_env_create(MDB_env **env)
3992 GET_PAGESIZE(e->me_os_psize);4036 GET_PAGESIZE(e->me_os_psize);
3993 VGMEMP_CREATE(e,0,0);4037 VGMEMP_CREATE(e,0,0);
3994 *env = e;4038 *env = e;
4039 MDB_TRACE(("%p", e));
3995 return MDB_SUCCESS;4040 return MDB_SUCCESS;
3996}4041}
39974042
@@ -4115,6 +4160,7 @@ mdb_env_set_mapsize(MDB_env *env, size_t size)
4115 env->me_mapsize = size;4160 env->me_mapsize = size;
4116 if (env->me_psize)4161 if (env->me_psize)
4117 env->me_maxpg = env->me_mapsize / env->me_psize;4162 env->me_maxpg = env->me_mapsize / env->me_psize;
4163 MDB_TRACE(("%p, %"Yu"", env, size));
4118 return MDB_SUCCESS;4164 return MDB_SUCCESS;
4119}4165}
41204166
@@ -4124,6 +4170,7 @@ mdb_env_set_maxdbs(MDB_env *env, MDB_dbi dbs)
4124 if (env->me_map)4170 if (env->me_map)
4125 return EINVAL;4171 return EINVAL;
4126 env->me_maxdbs = dbs + CORE_DBS;4172 env->me_maxdbs = dbs + CORE_DBS;
4173 MDB_TRACE(("%p, %u", env, dbs));
4127 return MDB_SUCCESS;4174 return MDB_SUCCESS;
4128}4175}
41294176
@@ -4133,6 +4180,7 @@ mdb_env_set_maxreaders(MDB_env *env, unsigned int readers)
4133 if (env->me_map || readers < 1)4180 if (env->me_map || readers < 1)
4134 return EINVAL;4181 return EINVAL;
4135 env->me_maxreaders = readers;4182 env->me_maxreaders = readers;
4183 MDB_TRACE(("%p, %u", env, readers));
4136 return MDB_SUCCESS;4184 return MDB_SUCCESS;
4137}4185}
41384186
@@ -5076,6 +5124,7 @@ mdb_env_open(MDB_env *env, const char *path, unsigned int flags, mdb_mode_t mode
5076 }5124 }
50775125
5078leave:5126leave:
5127 MDB_TRACE(("%p, %s, %u, %04o", env, path, flags & (CHANGEABLE|CHANGELESS), mode));
5079 if (rc) {5128 if (rc) {
5080 mdb_env_close0(env, excl);5129 mdb_env_close0(env, excl);
5081 }5130 }
@@ -5162,17 +5211,6 @@ mdb_env_close0(MDB_env *env, int excl)
5162 sem_unlink(env->me_txns->mti_wmname);5211 sem_unlink(env->me_txns->mti_wmname);
5163 }5212 }
5164 }5213 }
5165#elif defined(MDB_ROBUST_SUPPORTED)
5166 /* If we have the filelock: If we are the
5167 * only remaining user, clean up robust
5168 * mutexes.
5169 */
5170 if (excl == 0)
5171 mdb_env_excl_lock(env, &excl);
5172 if (excl > 0) {
5173 pthread_mutex_destroy(env->me_txns->mti_rmutex);
5174 pthread_mutex_destroy(env->me_txns->mti_wmutex);
5175 }
5176#endif5214#endif
5177 munmap((void *)env->me_txns, (env->me_maxreaders-1)*sizeof(MDB_reader)+sizeof(MDB_txninfo));5215 munmap((void *)env->me_txns, (env->me_maxreaders-1)*sizeof(MDB_reader)+sizeof(MDB_txninfo));
5178 }5216 }
@@ -5199,6 +5237,7 @@ mdb_env_close(MDB_env *env)
5199 if (env == NULL)5237 if (env == NULL)
5200 return;5238 return;
52015239
5240 MDB_TRACE(("%p", env));
5202 VGMEMP_DESTROY(env);5241 VGMEMP_DESTROY(env);
5203 while ((dp = env->me_dpages) != NULL) {5242 while ((dp = env->me_dpages) != NULL) {
5204 VGMEMP_DEFINED(&dp->mp_next, sizeof(dp->mp_next));5243 VGMEMP_DEFINED(&dp->mp_next, sizeof(dp->mp_next));
@@ -6570,8 +6609,8 @@ mdb_cursor_touch(MDB_cursor *mc)
6570/** Do not spill pages to disk if txn is getting full, may fail instead */6609/** Do not spill pages to disk if txn is getting full, may fail instead */
6571#define MDB_NOSPILL 0x80006610#define MDB_NOSPILL 0x8000
65726611
6573int6612static int
6574mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,6613_mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
6575 unsigned int flags)6614 unsigned int flags)
6576{6615{
6577 MDB_env *env;6616 MDB_env *env;
@@ -7034,7 +7073,7 @@ put_sub:
7034 new_dupdata = (int)dkey.mv_size;7073 new_dupdata = (int)dkey.mv_size;
7035 /* converted, write the original data first */7074 /* converted, write the original data first */
7036 if (dkey.mv_size) {7075 if (dkey.mv_size) {
7037 rc = mdb_cursor_put(&mc->mc_xcursor->mx_cursor, &dkey, &xdata, xflags);7076 rc = _mdb_cursor_put(&mc->mc_xcursor->mx_cursor, &dkey, &xdata, xflags);
7038 if (rc)7077 if (rc)
7039 goto bad_sub;7078 goto bad_sub;
7040 /* we've done our job */7079 /* we've done our job */
@@ -7062,7 +7101,7 @@ put_sub:
7062 ecount = mc->mc_xcursor->mx_db.md_entries;7101 ecount = mc->mc_xcursor->mx_db.md_entries;
7063 if (flags & MDB_APPENDDUP)7102 if (flags & MDB_APPENDDUP)
7064 xflags |= MDB_APPEND;7103 xflags |= MDB_APPEND;
7065 rc = mdb_cursor_put(&mc->mc_xcursor->mx_cursor, data, &xdata, xflags);7104 rc = _mdb_cursor_put(&mc->mc_xcursor->mx_cursor, data, &xdata, xflags);
7066 if (flags & F_SUBDATA) {7105 if (flags & F_SUBDATA) {
7067 void *db = NODEDATA(leaf);7106 void *db = NODEDATA(leaf);
7068 memcpy(db, &mc->mc_xcursor->mx_db, sizeof(MDB_db));7107 memcpy(db, &mc->mc_xcursor->mx_db, sizeof(MDB_db));
@@ -7103,7 +7142,20 @@ bad_sub:
7103}7142}
71047143
7105int7144int
7106mdb_cursor_del(MDB_cursor *mc, unsigned int flags)7145mdb_cursor_put(MDB_cursor *mc, MDB_val *key, MDB_val *data,
7146 unsigned int flags)
7147{
7148 DKBUF;
7149 DDBUF;
7150 int rc = _mdb_cursor_put(mc, key, data, flags);
7151 MDB_TRACE(("%p, %"Z"u[%s], %"Z"u%s, %u",
7152 mc, key ? key->mv_size:0, DKEY(key), data ? data->mv_size:0,
7153 data ? mdb_dval(mc->mc_txn, mc->mc_dbi, data, dbuf):"", flags));
7154 return rc;
7155}
7156
7157static int
7158_mdb_cursor_del(MDB_cursor *mc, unsigned int flags)
7107{7159{
7108 MDB_node *leaf;7160 MDB_node *leaf;
7109 MDB_page *mp;7161 MDB_page *mp;
@@ -7141,7 +7193,7 @@ mdb_cursor_del(MDB_cursor *mc, unsigned int flags)
7141 if (!F_ISSET(leaf->mn_flags, F_SUBDATA)) {7193 if (!F_ISSET(leaf->mn_flags, F_SUBDATA)) {
7142 mc->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf);7194 mc->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(leaf);
7143 }7195 }
7144 rc = mdb_cursor_del(&mc->mc_xcursor->mx_cursor, MDB_NOSPILL);7196 rc = _mdb_cursor_del(&mc->mc_xcursor->mx_cursor, MDB_NOSPILL);
7145 if (rc)7197 if (rc)
7146 return rc;7198 return rc;
7147 /* If sub-DB still has entries, we're done */7199 /* If sub-DB still has entries, we're done */
@@ -7205,6 +7257,14 @@ fail:
7205 return rc;7257 return rc;
7206}7258}
72077259
7260int
7261mdb_cursor_del(MDB_cursor *mc, unsigned int flags)
7262{
7263 MDB_TRACE(("%p, %u",
7264 mc, flags));
7265 return _mdb_cursor_del(mc, flags);
7266}
7267
7208/** Allocate and initialize new pages for a database.7268/** Allocate and initialize new pages for a database.
7209 * Set #MDB_TXN_ERROR on failure.7269 * Set #MDB_TXN_ERROR on failure.
7210 * @param[in] mc a cursor on the database being added to.7270 * @param[in] mc a cursor on the database being added to.
@@ -7698,6 +7758,7 @@ mdb_cursor_open(MDB_txn *txn, MDB_dbi dbi, MDB_cursor **ret)
7698 return ENOMEM;7758 return ENOMEM;
7699 }7759 }
77007760
7761 MDB_TRACE(("%p, %u = %p", txn, dbi, mc));
7701 *ret = mc;7762 *ret = mc;
77027763
7703 return MDB_SUCCESS;7764 return MDB_SUCCESS;
@@ -7761,6 +7822,7 @@ mdb_cursor_count(MDB_cursor *mc, size_t *countp)
7761void7822void
7762mdb_cursor_close(MDB_cursor *mc)7823mdb_cursor_close(MDB_cursor *mc)
7763{7824{
7825 MDB_TRACE(("%p", mc));
7764 if (mc && !mc->mc_backup) {7826 if (mc && !mc->mc_backup) {
7765 /* remove from txn, if tracked */7827 /* remove from txn, if tracked */
7766 if ((mc->mc_flags & C_UNTRACK) && mc->mc_txn->mt_cursors) {7828 if ((mc->mc_flags & C_UNTRACK) && mc->mc_txn->mt_cursors) {
@@ -8570,6 +8632,8 @@ int
8570mdb_del(MDB_txn *txn, MDB_dbi dbi,8632mdb_del(MDB_txn *txn, MDB_dbi dbi,
8571 MDB_val *key, MDB_val *data)8633 MDB_val *key, MDB_val *data)
8572{8634{
8635 DKBUF;
8636 DDBUF;
8573 if (!key || !TXN_DBI_EXIST(txn, dbi, DB_USRVALID))8637 if (!key || !TXN_DBI_EXIST(txn, dbi, DB_USRVALID))
8574 return EINVAL;8638 return EINVAL;
85758639
@@ -8581,6 +8645,9 @@ mdb_del(MDB_txn *txn, MDB_dbi dbi,
8581 data = NULL;8645 data = NULL;
8582 }8646 }
85838647
8648 MDB_TRACE(("%p, %u, %"Z"u[%s], %"Z"u%s",
8649 txn, dbi, key ? key->mv_size:0, DKEY(key), data ? data->mv_size:0,
8650 data ? mdb_dval(txn, dbi, data, dbuf):""));
8584 return mdb_del0(txn, dbi, key, data, 0);8651 return mdb_del0(txn, dbi, key, data, 0);
8585}8652}
85868653
@@ -8621,7 +8688,7 @@ mdb_del0(MDB_txn *txn, MDB_dbi dbi,
8621 mc.mc_flags |= C_UNTRACK;8688 mc.mc_flags |= C_UNTRACK;
8622 mc.mc_next = txn->mt_cursors[dbi];8689 mc.mc_next = txn->mt_cursors[dbi];
8623 txn->mt_cursors[dbi] = &mc;8690 txn->mt_cursors[dbi] = &mc;
8624 rc = mdb_cursor_del(&mc, flags);8691 rc = _mdb_cursor_del(&mc, flags);
8625 txn->mt_cursors[dbi] = mc.mc_next;8692 txn->mt_cursors[dbi] = mc.mc_next;
8626 }8693 }
8627 return rc;8694 return rc;
@@ -9063,6 +9130,8 @@ mdb_put(MDB_txn *txn, MDB_dbi dbi,
9063 MDB_cursor mc;9130 MDB_cursor mc;
9064 MDB_xcursor mx;9131 MDB_xcursor mx;
9065 int rc;9132 int rc;
9133 DKBUF;
9134 DDBUF;
90669135
9067 if (!key || !data || !TXN_DBI_EXIST(txn, dbi, DB_USRVALID))9136 if (!key || !data || !TXN_DBI_EXIST(txn, dbi, DB_USRVALID))
9068 return EINVAL;9137 return EINVAL;
@@ -9073,10 +9142,12 @@ mdb_put(MDB_txn *txn, MDB_dbi dbi,
9073 if (txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_BLOCKED))9142 if (txn->mt_flags & (MDB_TXN_RDONLY|MDB_TXN_BLOCKED))
9074 return (txn->mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN;9143 return (txn->mt_flags & MDB_TXN_RDONLY) ? EACCES : MDB_BAD_TXN;
90759144
9145 MDB_TRACE(("%p, %u, %"Z"u[%s], %"Z"u%s, %u",
9146 txn, dbi, key ? key->mv_size:0, DKEY(key), data->mv_size, mdb_dval(txn, dbi, data, dbuf), flags));
9076 mdb_cursor_init(&mc, txn, dbi, &mx);9147 mdb_cursor_init(&mc, txn, dbi, &mx);
9077 mc.mc_next = txn->mt_cursors[dbi];9148 mc.mc_next = txn->mt_cursors[dbi];
9078 txn->mt_cursors[dbi] = &mc;9149 txn->mt_cursors[dbi] = &mc;
9079 rc = mdb_cursor_put(&mc, key, data, flags);9150 rc = _mdb_cursor_put(&mc, key, data, flags);
9080 txn->mt_cursors[dbi] = mc.mc_next;9151 txn->mt_cursors[dbi] = mc.mc_next;
9081 return rc;9152 return rc;
9082}9153}
@@ -9479,7 +9550,7 @@ finish:
9479 my.mc_error = rc;9550 my.mc_error = rc;
9480 mdb_env_cthr_toggle(&my, 1 | MDB_EOF);9551 mdb_env_cthr_toggle(&my, 1 | MDB_EOF);
9481 rc = THREAD_FINISH(thr);9552 rc = THREAD_FINISH(thr);
9482 mdb_txn_abort(txn);9553 _mdb_txn_abort(txn);
94839554
9484done:9555done:
9485#ifdef _WIN329556#ifdef _WIN32
@@ -9591,7 +9662,7 @@ mdb_env_copyfd0(MDB_env *env, HANDLE fd)
9591 }9662 }
95929663
9593leave:9664leave:
9594 mdb_txn_abort(txn);9665 _mdb_txn_abort(txn);
9595 return rc;9666 return rc;
9596}9667}
95979668
@@ -9806,6 +9877,7 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *db
9806 }9877 }
9807 }9878 }
9808 mdb_default_cmp(txn, MAIN_DBI);9879 mdb_default_cmp(txn, MAIN_DBI);
9880 MDB_TRACE(("%p, (null), %u = %u", txn, flags, MAIN_DBI));
9809 return MDB_SUCCESS;9881 return MDB_SUCCESS;
9810 }9882 }
98119883
@@ -9867,7 +9939,7 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *db
9867 dummy.md_root = P_INVALID;9939 dummy.md_root = P_INVALID;
9868 dummy.md_flags = flags & PERSISTENT_FLAGS;9940 dummy.md_flags = flags & PERSISTENT_FLAGS;
9869 WITH_CURSOR_TRACKING(mc,9941 WITH_CURSOR_TRACKING(mc,
9870 rc = mdb_cursor_put(&mc, &key, &data, F_SUBDATA));9942 rc = _mdb_cursor_put(&mc, &key, &data, F_SUBDATA));
9871 dbflag |= DB_DIRTY;9943 dbflag |= DB_DIRTY;
9872 }9944 }
98739945
@@ -9892,6 +9964,7 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned int flags, MDB_dbi *db
9892 if (!unused) {9964 if (!unused) {
9893 txn->mt_numdbs++;9965 txn->mt_numdbs++;
9894 }9966 }
9967 MDB_TRACE(("%p, %s, %u = %u", txn, name, flags, slot));
9895 }9968 }
98969969
9897 return rc;9970 return rc;
@@ -9923,6 +9996,7 @@ void mdb_dbi_close(MDB_env *env, MDB_dbi dbi)
9923 ptr = env->me_dbxs[dbi].md_name.mv_data;9996 ptr = env->me_dbxs[dbi].md_name.mv_data;
9924 /* If there was no name, this was already closed */9997 /* If there was no name, this was already closed */
9925 if (ptr) {9998 if (ptr) {
9999 MDB_TRACE(("%p, %u", env, dbi));
9926 env->me_dbxs[dbi].md_name.mv_data = NULL;10000 env->me_dbxs[dbi].md_name.mv_data = NULL;
9927 env->me_dbxs[dbi].md_name.mv_size = 0;10001 env->me_dbxs[dbi].md_name.mv_size = 0;
9928 env->me_dbflags[dbi] = 0;10002 env->me_dbflags[dbi] = 0;
@@ -10057,6 +10131,7 @@ int mdb_drop(MDB_txn *txn, MDB_dbi dbi, int del)
10057 if (rc)10131 if (rc)
10058 return rc;10132 return rc;
1005910133
10134 MDB_TRACE(("%u, %d", dbi, del));
10060 rc = mdb_drop0(mc, mc->mc_db->md_flags & MDB_DUPSORT);10135 rc = mdb_drop0(mc, mc->mc_db->md_flags & MDB_DUPSORT);
10061 /* Invalidate the dropped DB's cursors */10136 /* Invalidate the dropped DB's cursors */
10062 for (m2 = txn->mt_cursors[dbi]; m2; m2 = m2->mc_next)10137 for (m2 = txn->mt_cursors[dbi]; m2; m2 = m2->mc_next)
diff --git a/libraries/liblmdb/mdb_load.c b/libraries/liblmdb/mdb_load.c
index d2a3cec..cba6c06 100644
--- a/libraries/liblmdb/mdb_load.c
+++ b/libraries/liblmdb/mdb_load.c
@@ -449,7 +449,7 @@ int main(int argc, char *argv[])
449 if (rc == MDB_KEYEXIST && putflags)449 if (rc == MDB_KEYEXIST && putflags)
450 continue;450 continue;
451 if (rc) {451 if (rc) {
452 fprintf(stderr, "mdb_cursor_put failed, error %d %s\n", rc, mdb_strerror(rc));452 fprintf(stderr, "%s: line %" Z "d: mdb_cursor_put failed, error %d %s\n", prog, lineno, rc, mdb_strerror(rc));
453 goto txn_abort;453 goto txn_abort;
454 }454 }
455 batch++;455 batch++;
@@ -470,9 +470,11 @@ int main(int argc, char *argv[])
470 fprintf(stderr, "mdb_cursor_open failed, error %d %s\n", rc, mdb_strerror(rc));470 fprintf(stderr, "mdb_cursor_open failed, error %d %s\n", rc, mdb_strerror(rc));
471 goto txn_abort;471 goto txn_abort;
472 }472 }
473 if (appflag & MDB_APPENDDUP) {473 if (append) {
474 MDB_val k, d;474 MDB_val k, d;
475 mdb_cursor_get(mc, &k, &d, MDB_LAST);475 mdb_cursor_get(mc, &k, &d, MDB_LAST);
476 memcpy(prevk.mv_data, k.mv_data, k.mv_size);
477 prevk.mv_size = k.mv_size;
476 }478 }
477 batch = 0;479 batch = 0;
478 }480 }
diff --git a/libraries/liblmdb/midl.h b/libraries/liblmdb/midl.h
index 2075206..ff740ae 100644
--- a/libraries/liblmdb/midl.h
+++ b/libraries/liblmdb/midl.h
@@ -56,7 +56,9 @@ typedef MDB_ID *MDB_IDL;
56/* IDL sizes - likely should be even bigger56/* IDL sizes - likely should be even bigger
57 * limiting factors: sizeof(ID), thread stack size57 * limiting factors: sizeof(ID), thread stack size
58 */58 */
59#ifndef MDB_IDL_LOGN
59#define MDB_IDL_LOGN 16 /* DB_SIZE is 2^16, UM_SIZE is 2^17 */60#define MDB_IDL_LOGN 16 /* DB_SIZE is 2^16, UM_SIZE is 2^17 */
61#endif
60#define MDB_IDL_DB_SIZE (1<<MDB_IDL_LOGN)62#define MDB_IDL_DB_SIZE (1<<MDB_IDL_LOGN)
61#define MDB_IDL_UM_SIZE (1<<(MDB_IDL_LOGN+1))63#define MDB_IDL_UM_SIZE (1<<(MDB_IDL_LOGN+1))
6264
diff --git a/libraries/liblmdb/mplay.c b/libraries/liblmdb/mplay.c
63new file mode 10064465new file mode 100644
index 0000000..0fef74f
--- /dev/null
+++ b/libraries/liblmdb/mplay.c
@@ -0,0 +1,582 @@
1/* mplay.c - memory-mapped database log replay */
2/*
3 * Copyright 2011-2023 Howard Chu, Symas Corp.
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted only as authorized by the OpenLDAP
8 * Public License.
9 *
10 * A copy of this license is available in the file LICENSE in the
11 * top-level directory of the distribution or, alternatively, at
12 * <http://www.OpenLDAP.org/license.html>.
13 */
14#include <stdio.h>
15#include <stdlib.h>
16#include <unistd.h>
17#include <time.h>
18#include <string.h>
19#include <ctype.h>
20#include <assert.h>
21#include <sys/types.h>
22#include <sys/wait.h>
23
24#include "lmdb.h"
25
26#define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr)
27#define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0))
28#define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \
29 "%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort()))
30
31#define MDB_SCNy(t) "z" #t
32
33#define SCMP(s) s, (sizeof(s)-1)
34char inbuf[8192];
35char *dbuf, *kbuf;
36size_t dbufsize;
37int maxkey;
38
39#define SOFF(s) (sizeof(s)+1)
40
41#define MAXENVS 16
42#define MAXTXNS 16
43#define MAXCRSS 16
44
45#define MAXPIDS 16
46
47typedef struct crspair {
48 void *tcrs; /* scanned text pointer */
49 MDB_cursor *rcrs;
50} crspair;
51
52typedef struct txnpair {
53 void *ttxn; /* scanned text pointer */
54 MDB_txn *rtxn;
55 crspair cursors[MAXCRSS];
56 int ncursors;
57} txnpair;
58
59typedef struct envpair {
60 void *tenv;
61 MDB_env *renv;
62 txnpair txns[MAXTXNS];
63 int ntxns;
64} envpair;
65
66envpair envs[MAXENVS];
67int nenvs;
68
69envpair *lastenv;
70txnpair *lasttxn;
71crspair *lastcrs;
72
73typedef struct pidpair {
74 int tpid;
75 pid_t rpid;
76 int fdout, fdin;
77} pidpair;
78
79pidpair *lastpid;
80
81pidpair pids[MAXPIDS];
82int npids;
83
84unsigned long lcount;
85
86static int unhex(unsigned char *c2)
87{
88 int x, c;
89 x = *c2++ & 0x4f;
90 if (x & 0x40)
91 x -= 55;
92 c = x << 4;
93 x = *c2 & 0x4f;
94 if (x & 0x40)
95 x -= 55;
96 c |= x;
97 return c;
98}
99
100int inhex(char *in, char *out)
101{
102 char *c2 = out;
103 while (isxdigit(*in)) {
104 *c2++ = unhex((unsigned char *)in);
105 in += 2;
106 }
107 return c2 - out;
108}
109
110static void addenv(void *tenv, MDB_env *renv)
111{
112 assert(nenvs < MAXENVS);
113 envs[nenvs].tenv = tenv;
114 envs[nenvs].renv = renv;
115 envs[nenvs].ntxns = 0;
116 lastenv = envs+nenvs;
117 nenvs++;
118}
119
120static envpair *findenv(void *tenv)
121{
122 int i;
123 if (!lastenv || lastenv->tenv != tenv) {
124 for (i=0; i<nenvs; i++)
125 if (envs[i].tenv == tenv)
126 break;
127 assert(i < nenvs);
128 lastenv = &envs[i];
129 }
130 return lastenv;
131}
132
133static void delenv(envpair *ep)
134{
135 int i = ep - envs;
136 for (; i<nenvs-1; i++)
137 envs[i] = envs[i+1];
138 nenvs--;
139 lastenv = NULL;
140}
141
142static void addtxn(void *tenv, void *ttxn, MDB_txn *rtxn)
143{
144 envpair *ep;
145 txnpair *tp;
146
147 ep = findenv(tenv);
148 assert(ep->ntxns < MAXTXNS);
149 tp = ep->txns+ep->ntxns;
150 tp->ttxn = ttxn;
151 tp->rtxn = rtxn;
152 tp->ncursors = 0;
153 ep->ntxns++;
154 lasttxn = tp;
155}
156
157static txnpair *findtxn(void *ttxn)
158{
159 int i, j;
160 if (lasttxn && lasttxn->ttxn == ttxn)
161 return lasttxn;
162 if (lastenv) {
163 for (i=0; i<lastenv->ntxns; i++) {
164 if (lastenv->txns[i].ttxn == ttxn) {
165 lasttxn = lastenv->txns+i;
166 return lasttxn;
167 }
168 }
169 }
170 for (i=0; i<nenvs; i++) {
171 if (envs+i == lastenv) continue;
172 for (j=0; j<envs[i].ntxns; j++) {
173 if (envs[i].txns[j].ttxn == ttxn) {
174 lastenv = envs+i;
175 lasttxn = envs[i].txns+j;
176 return lasttxn;
177 }
178 }
179 }
180 assert(0); /* should have found it */
181}
182
183static void deltxn(txnpair *tp)
184{
185 int i = tp - lastenv->txns;
186 for (; i<lastenv->ntxns-1; i++)
187 lastenv->txns[i] = lastenv->txns[i+1];
188 lastenv->ntxns--;
189 lasttxn = NULL;
190}
191
192static void addcrs(txnpair *tp, void *tcrs, MDB_cursor *rcrs)
193{
194 int j = tp->ncursors;
195 assert(tp->ncursors < MAXCRSS);
196
197 tp->cursors[j].tcrs = tcrs;
198 tp->cursors[j].rcrs = rcrs;
199 tp->ncursors++;
200 lastcrs = tp->cursors+j;
201}
202
203static crspair *findcrs(void *tcrs)
204{
205 int i, j, k;
206 envpair *ep;
207 txnpair *tp;
208 crspair *cp;
209 if (lastcrs && lastcrs->tcrs == tcrs)
210 return lastcrs;
211 if (lasttxn) {
212 for (k=0, cp=lasttxn->cursors; k<lasttxn->ncursors; k++, cp++) {
213 if (cp->tcrs == tcrs) {
214 lastcrs = cp;
215 return lastcrs;
216 }
217 }
218 }
219 if (lastenv) {
220 for (j=0, tp=lastenv->txns; j<lastenv->ntxns; j++, tp++){
221 if (tp == lasttxn)
222 continue;
223 for (k=0, cp = tp->cursors; k<tp->ncursors; k++, cp++) {
224 if (cp->tcrs == tcrs) {
225 lastcrs = cp;
226 lasttxn = tp;
227 return lastcrs;
228 }
229 }
230 }
231 }
232 for (i=0, ep=envs; i<nenvs; i++, ep++) {
233 for (j=0, tp=ep->txns; j<ep->ntxns; j++, tp++) {
234 if (tp == lasttxn)
235 continue;
236 for (k=0, cp = tp->cursors; k<tp->ncursors; k++, cp++) {
237 if (cp->tcrs == tcrs) {
238 lastcrs = cp;
239 lasttxn = tp;
240 lastenv = ep;
241 return lastcrs;
242 }
243 }
244 }
245 }
246 assert(0); /* should have found it already */
247}
248
249static void delcrs(void *tcrs)
250{
251 int i;
252 crspair *cp = findcrs(tcrs);
253 mdb_cursor_close(cp->rcrs);
254 for (i = cp - lasttxn->cursors; i<lasttxn->ncursors-1; i++)
255 lasttxn->cursors[i] = lasttxn->cursors[i+1];
256 lasttxn->ncursors--;
257 lastcrs = NULL;
258}
259
260void child()
261{
262 int rc;
263 MDB_val key, data;
264 char *ptr;
265
266 while (fgets(inbuf, sizeof(inbuf), stdin)) {
267 ptr = inbuf;
268 if (!strncmp(ptr, SCMP("exit")))
269 break;
270
271 if (!strncmp(ptr, SCMP("mdb_env_create"))) {
272 void *tenv;
273 MDB_env *renv;
274 sscanf(ptr+SOFF("mdb_env_create"), "%p", &tenv);
275 E(mdb_env_create(&renv));
276 addenv(tenv, renv);
277 } else if (!strncmp(ptr, SCMP("mdb_env_set_maxdbs"))) {
278 void *tenv;
279 envpair *ep;
280 unsigned int maxdbs;
281 sscanf(ptr+SOFF("mdb_env_set_maxdbs"), "%p, %u", &tenv, &maxdbs);
282 ep = findenv(tenv);
283 E(mdb_env_set_maxdbs(ep->renv, maxdbs));
284 } else if (!strncmp(ptr, SCMP("mdb_env_set_mapsize"))) {
285 void *tenv;
286 envpair *ep;
287 size_t mapsize;
288 sscanf(ptr+SOFF("mdb_env_set_mapsize"), "%p, %"MDB_SCNy(u), &tenv, &mapsize);
289 ep = findenv(tenv);
290 E(mdb_env_set_mapsize(ep->renv, mapsize));
291 } else if (!strncmp(ptr, SCMP("mdb_env_open"))) {
292 void *tenv;
293 envpair *ep;
294 char *path;
295 int len;
296 unsigned int flags, mode;
297 sscanf(ptr+SOFF("mdb_env_open"), "%p, %n", &tenv, &len);
298 path = ptr+SOFF("mdb_env_open")+len;
299 ptr = strchr(path, ',');
300 *ptr++ = '\0';
301 sscanf(ptr, "%u, %o", &flags, &mode);
302 ep = findenv(tenv);
303 E(mdb_env_open(ep->renv, path, flags, mode));
304 if (!maxkey) {
305 maxkey = mdb_env_get_maxkeysize(ep->renv);
306 kbuf = malloc(maxkey+2);
307 dbuf = malloc(maxkey+2);
308 dbufsize = maxkey;
309 }
310 } else if (!strncmp(ptr, SCMP("mdb_env_close"))) {
311 void *tenv;
312 envpair *ep;
313 sscanf(ptr+SOFF("mdb_env_close"), "%p", &tenv);
314 ep = findenv(tenv);
315 mdb_env_close(ep->renv);
316 delenv(ep);
317 if (!nenvs) /* if no other envs left, this process is done */
318 break;
319 } else if (!strncmp(ptr, SCMP("mdb_txn_begin"))) {
320 unsigned int flags;
321 void *tenv, *ttxn;
322 envpair *ep;
323 MDB_txn *rtxn;
324 sscanf(ptr+SOFF("mdb_txn_begin"), "%p, %*p, %u = %p", &tenv, &flags, &ttxn);
325 ep = findenv(tenv);
326 E(mdb_txn_begin(ep->renv, NULL, flags, &rtxn));
327 addtxn(tenv, ttxn, rtxn);
328 } else if (!strncmp(ptr, SCMP("mdb_txn_commit"))) {
329 void *ttxn;
330 txnpair *tp;
331 sscanf(ptr+SOFF("mdb_txn_commit"), "%p", &ttxn);
332 tp = findtxn(ttxn);
333 E(mdb_txn_commit(tp->rtxn));
334 deltxn(tp);
335 } else if (!strncmp(ptr, SCMP("mdb_txn_abort"))) {
336 void *ttxn;
337 txnpair *tp;
338 sscanf(ptr+SOFF("mdb_txn_abort"), "%p", &ttxn);
339 tp = findtxn(ttxn);
340 mdb_txn_abort(tp->rtxn);
341 deltxn(tp);
342 } else if (!strncmp(ptr, SCMP("mdb_dbi_open"))) {
343 void *ttxn;
344 txnpair *tp;
345 char *dbname;
346 unsigned int flags;
347 unsigned int tdbi;
348 MDB_dbi dbi;
349 sscanf(ptr+SOFF("mdb_dbi_open"), "%p, ", &ttxn);
350 dbname = strchr(ptr+SOFF("mdb_dbi_open"), ',');
351 dbname += 2;
352 ptr = strchr(dbname, ',');
353 *ptr++ = '\0';
354 if (!strcmp(dbname, "(null)"))
355 dbname = NULL;
356 sscanf(ptr, "%u = %u", &flags, &tdbi);
357 tp = findtxn(ttxn);
358 E(mdb_dbi_open(tp->rtxn, dbname, flags, &dbi));
359 } else if (!strncmp(ptr, SCMP("mdb_dbi_close"))) {
360 void *tenv;
361 envpair *ep;
362 unsigned int tdbi;
363 sscanf(ptr+SOFF("mdb_dbi_close"), "%p, %u", &tenv, &tdbi);
364 ep = findenv(tenv);
365 mdb_dbi_close(ep->renv, tdbi);
366 } else if (!strncmp(ptr, SCMP("mdb_cursor_open"))) {
367 void *ttxn, *tcrs;
368 txnpair *tp;
369 MDB_cursor *rcrs;
370 unsigned int tdbi;
371 sscanf(ptr+SOFF("mdb_cursor_open"), "%p, %u = %p", &ttxn, &tdbi, &tcrs);
372 tp = findtxn(ttxn);
373 E(mdb_cursor_open(tp->rtxn, tdbi, &rcrs));
374 addcrs(tp, tcrs, rcrs);
375 } else if (!strncmp(ptr, SCMP("mdb_cursor_close"))) {
376 void *tcrs;
377 sscanf(ptr+SOFF("mdb_cursor_close"), "%p", &tcrs);
378 delcrs(tcrs);
379 } else if (!strncmp(ptr, SCMP("mdb_cursor_put"))) {
380 void *tcrs;
381 crspair *cp;
382 unsigned int flags;
383 int len;
384 sscanf(ptr+SOFF("mdb_cursor_put"), "%p, ", &tcrs);
385 cp = findcrs(tcrs);
386 ptr = strchr(ptr+SOFF("mdb_cursor_put"), ',');
387 sscanf(ptr+1, "%"MDB_SCNy(u)",", &key.mv_size);
388 if (key.mv_size) {
389 ptr = strchr(ptr, '[');
390 inhex(ptr+1, kbuf);
391 key.mv_data = kbuf;
392 ptr += key.mv_size * 2 + 2;
393 }
394 ptr = strchr(ptr+1, ',');
395 sscanf(ptr+1, "%"MDB_SCNy(u)"%n", &data.mv_size, &len);
396 if (data.mv_size > dbufsize) {
397 dbuf = realloc(dbuf, data.mv_size+2);
398 assert(dbuf != NULL);
399 dbufsize = data.mv_size;
400 }
401 ptr += len+1;
402 if (*ptr == '[') {
403 inhex(ptr+1, dbuf);
404 data.mv_data = dbuf;
405 ptr += data.mv_size * 2 + 2;
406 } else {
407 sprintf(dbuf, "%09ld", (long)mdb_txn_id(lasttxn->rtxn));
408 }
409 sscanf(ptr+1, "%u", &flags);
410 E(mdb_cursor_put(cp->rcrs, &key, &data, flags));
411 } else if (!strncmp(ptr, SCMP("mdb_cursor_del"))) {
412 void *tcrs;
413 crspair *cp;
414 unsigned int flags;
415 sscanf(ptr+SOFF("mdb_cursor_del"), "%p, %u", &tcrs, &flags);
416 cp = findcrs(tcrs);
417 E(mdb_cursor_del(cp->rcrs, flags));
418 } else if (!strncmp(ptr, SCMP("mdb_put"))) {
419 void *ttxn;
420 txnpair *tp;
421 unsigned int tdbi, flags;
422 int len;
423 sscanf(ptr+SOFF("mdb_put"),"%p, %u, %"MDB_SCNy(u), &ttxn, &tdbi, &key.mv_size);
424 tp = findtxn(ttxn);
425 ptr = strchr(ptr+SOFF("mdb_put"), '[');
426 inhex(ptr+1, kbuf);
427 key.mv_data = kbuf;
428 ptr += key.mv_size * 2 + 2;
429 sscanf(ptr+1, "%"MDB_SCNy(u)"%n", &data.mv_size, &len);
430 if (data.mv_size > dbufsize) {
431 dbuf = realloc(dbuf, data.mv_size+2);
432 assert(dbuf != NULL);
433 dbufsize = data.mv_size;
434 }
435 ptr += len+1;
436 if (*ptr == '[') {
437 inhex(ptr+1, dbuf);
438 ptr += data.mv_size * 2 + 2;
439 } else {
440 sprintf(dbuf, "%09ld", (long)mdb_txn_id(tp->rtxn));
441 }
442 data.mv_data = dbuf;
443 sscanf(ptr+1, "%u", &flags);
444 RES(MDB_KEYEXIST,mdb_put(tp->rtxn, tdbi, &key, &data, flags));
445 } else if (!strncmp(ptr, SCMP("mdb_del"))) {
446 void *ttxn;
447 txnpair *tp;
448 unsigned int tdbi;
449 int len;
450 sscanf(ptr+SOFF("mdb_del"),"%p, %u, %"MDB_SCNy(u), &ttxn, &tdbi, &key.mv_size);
451 tp = findtxn(ttxn);
452 ptr = strchr(ptr+SOFF("mdb_del"), '[');
453 inhex(ptr+1, kbuf);
454 key.mv_data = kbuf;
455 ptr += key.mv_size * 2 + 2;
456 sscanf(ptr+1, "%"MDB_SCNy(u)"%n", &data.mv_size, &len);
457 if (data.mv_size > dbufsize) {
458 dbuf = realloc(dbuf, data.mv_size+2);
459 assert(dbuf != NULL);
460 dbufsize = data.mv_size;
461 }
462 ptr += len+1;
463 if (*ptr == '[') {
464 inhex(ptr+1, dbuf);
465 } else {
466 sprintf(dbuf, "%09ld", (long)mdb_txn_id(tp->rtxn));
467 }
468 data.mv_data = dbuf;
469 RES(MDB_NOTFOUND,mdb_del(tp->rtxn, tdbi, &key, &data));
470 }
471 write(1, "\n", 1);
472 }
473 exit(0);
474}
475
476static pidpair *addpid(int tpid)
477{
478 int fdout[2], fdin[2];
479 pid_t pid;
480 assert(npids < MAXPIDS);
481 pids[npids].tpid = tpid;
482 pipe(fdout);
483 pipe(fdin);
484 if ((pid = fork()) == 0) {
485 /* child */
486 fclose(stdin);
487 fclose(stdout);
488 dup2(fdout[0], 0);
489 dup2(fdin[1], 1);
490 stdin = fdopen(0, "r");
491 stdout = fdopen(1, "w");
492 child();
493 return 0; /* NOTREACHED */
494 } else {
495 pids[npids].rpid = pid;
496 pids[npids].fdout = fdout[1];
497 pids[npids].fdin = fdin[0];
498 lastpid = pids+npids;
499 npids++;
500 return lastpid;
501 }
502}
503
504static pidpair *findpid(int tpid)
505{
506 int i;
507 if (!lastpid || lastpid->tpid != tpid) {
508 for (i=0; i<npids; i++)
509 if (pids[i].tpid == tpid)
510 break;
511 if (i == npids)
512 return NULL;
513 lastpid = &pids[i];
514 }
515 return lastpid;
516}
517
518volatile pid_t killpid;
519
520static void delpid(int tpid)
521{
522 pidpair *pp = findpid(tpid);
523 if (pp) {
524 pid_t kpid = pp->rpid;
525 killpid = kpid;
526 write(pp->fdout, "exit\n", sizeof("exit"));
527 while (killpid == kpid)
528 usleep(10000);
529 }
530}
531
532static void reaper(int sig)
533{
534 int status, i;
535 pid_t pid = waitpid(-1, &status, 0);
536 if (pid > 0) {
537 fprintf(stderr, "# %s %d\n", WIFEXITED(status) ? "exited" : "killed", pid);
538 for (i=0; i<npids; i++)
539 if (pids[i].rpid == pid)
540 break;
541 assert(i < npids);
542 close(pids[i].fdout);
543 close(pids[i].fdin);
544 for (;i<npids-1; i++)
545 pids[i] = pids[i+1];
546 npids--;
547 killpid = 0;
548 }
549}
550
551int main(int argc,char * argv[])
552{
553 signal(SIGCHLD, reaper);
554
555 while (fgets(inbuf, sizeof(inbuf), stdin)) {
556 pidpair *pp;
557 int tpid, len;
558 char c, *ptr;
559 lcount++;
560
561 if (inbuf[0] == '#' && !strncmp(inbuf+1, SCMP(" killed"))) {
562 sscanf(inbuf+SOFF("killed"),"%d", &tpid);
563 delpid(tpid);
564 continue;
565 }
566
567 if (inbuf[0] != '>')
568 continue;
569 ptr = inbuf+1;
570 sscanf(ptr, "%d:%n", &tpid, &len);
571 pp = findpid(tpid);
572 if (!pp)
573 pp = addpid(tpid); /* new process */
574
575 ptr = inbuf+len+1;
576 len = strlen(ptr);
577 write(pp->fdout, ptr, len); /* send command and wait for ack */
578 read(pp->fdin, &c, 1);
579 }
580 while (npids)
581 delpid(pids[0].tpid);
582}
diff --git a/servers/lloadd/daemon.c b/servers/lloadd/daemon.c
index b88fd68..e048936 100644
--- a/servers/lloadd/daemon.c
+++ b/servers/lloadd/daemon.c
@@ -92,6 +92,11 @@ struct event_base *listener_base = NULL;
92LloadListener **lload_listeners = NULL;92LloadListener **lload_listeners = NULL;
93static ldap_pvt_thread_t listener_tid, *daemon_tid;93static ldap_pvt_thread_t listener_tid, *daemon_tid;
9494
95#ifndef RESOLV_CONF_PATH
96#define RESOLV_CONF_PATH "/etc/resolv.conf"
97#endif
98char *lload_resolvconf_path = RESOLV_CONF_PATH;
99
95struct event_base *daemon_base = NULL;100struct event_base *daemon_base = NULL;
96struct evdns_base *dnsbase;101struct evdns_base *dnsbase;
97102
@@ -1238,13 +1243,22 @@ lloadd_daemon( struct event_base *daemon_base )
12381243
1239 assert( daemon_base != NULL );1244 assert( daemon_base != NULL );
12401245
1241 dnsbase = evdns_base_new( daemon_base, EVDNS_BASE_INITIALIZE_NAMESERVERS );1246 dnsbase = evdns_base_new( daemon_base, 0 );
1242 if ( !dnsbase ) {1247 if ( !dnsbase ) {
1243 Debug( LDAP_DEBUG_ANY, "lloadd startup: "1248 Debug( LDAP_DEBUG_ANY, "lloadd startup: "
1244 "failed to set up for async name resolution\n" );1249 "failed to set up for async name resolution\n" );
1245 return -1;1250 return -1;
1246 }1251 }
12471252
1253 /*
1254 * ITS#10070: Allow both operation without working DNS (test environments)
1255 * and e.g. containers that don't have a /etc/resolv.conf but do have a
1256 * server listening on 127.0.0.1 which is the default.
1257 */
1258 (void)evdns_base_resolv_conf_parse( dnsbase,
1259 DNS_OPTION_NAMESERVERS|DNS_OPTION_HOSTSFILE,
1260 lload_resolvconf_path );
1261
1248 if ( lload_daemon_threads > SLAPD_MAX_DAEMON_THREADS )1262 if ( lload_daemon_threads > SLAPD_MAX_DAEMON_THREADS )
1249 lload_daemon_threads = SLAPD_MAX_DAEMON_THREADS;1263 lload_daemon_threads = SLAPD_MAX_DAEMON_THREADS;
12501264
diff --git a/servers/lloadd/libevent_support.c b/servers/lloadd/libevent_support.c
index 2f94c5e..8d7378c 100644
--- a/servers/lloadd/libevent_support.c
+++ b/servers/lloadd/libevent_support.c
@@ -131,6 +131,12 @@ lload_libevent_cond_timedwait(
131 return ldap_pvt_thread_cond_wait( cond, mutex );131 return ldap_pvt_thread_cond_wait( cond, mutex );
132}132}
133133
134unsigned long
135lload_libevent_thread_self( void )
136{
137 return (unsigned long)ldap_pvt_thread_self();
138}
139
134int140int
135lload_libevent_init( void )141lload_libevent_init( void )
136{142{
@@ -160,7 +166,7 @@ lload_libevent_init( void )
160166
161 evthread_set_lock_callbacks( &cbs );167 evthread_set_lock_callbacks( &cbs );
162 evthread_set_condition_callbacks( &cond_cbs );168 evthread_set_condition_callbacks( &cond_cbs );
163 evthread_set_id_callback( ldap_pvt_thread_self );169 evthread_set_id_callback( lload_libevent_thread_self );
164 return 0;170 return 0;
165}171}
166172
diff --git a/servers/lloadd/module_init.c b/servers/lloadd/module_init.c
index 1475538..d4eebf6 100644
--- a/servers/lloadd/module_init.c
+++ b/servers/lloadd/module_init.c
@@ -145,7 +145,6 @@ lload_back_initialize( BackendInfo *bi )
145{145{
146 bi->bi_flags = SLAP_BFLAG_STANDALONE;146 bi->bi_flags = SLAP_BFLAG_STANDALONE;
147 bi->bi_open = lload_back_open;147 bi->bi_open = lload_back_open;
148 bi->bi_config = config_generic_wrapper;
149 bi->bi_pause = lload_pause_cb;148 bi->bi_pause = lload_pause_cb;
150 bi->bi_unpause = lload_unpause_cb;149 bi->bi_unpause = lload_unpause_cb;
151 bi->bi_close = lload_back_close;150 bi->bi_close = lload_back_close;
diff --git a/servers/lloadd/upstream.c b/servers/lloadd/upstream.c
index 6824fa8..5e64029 100644
--- a/servers/lloadd/upstream.c
+++ b/servers/lloadd/upstream.c
@@ -118,17 +118,22 @@ static int
118handle_unsolicited( LloadConnection *c, BerElement *ber )118handle_unsolicited( LloadConnection *c, BerElement *ber )
119{119{
120 CONNECTION_ASSERT_LOCKED(c);120 CONNECTION_ASSERT_LOCKED(c);
121 if ( c->c_state != LLOAD_C_PREPARING ) {121
122 c->c_state = LLOAD_C_CLOSING;122 assert( c->c_state != LLOAD_C_INVALID );
123 if ( c->c_state == LLOAD_C_DYING ) {
124 CONNECTION_UNLOCK(c);
125 goto out;
123 }126 }
127 c->c_state = LLOAD_C_CLOSING;
124128
125 Debug( LDAP_DEBUG_STATS, "handle_unsolicited: "129 Debug( LDAP_DEBUG_STATS, "handle_unsolicited: "
126 "teardown for upstream connection connid=%lu\n",130 "teardown for upstream connection connid=%lu\n",
127 c->c_connid );131 c->c_connid );
128132
129 CONNECTION_DESTROY(c);133 CONNECTION_DESTROY(c);
130 ber_free( ber, 1 );
131134
135out:
136 ber_free( ber, 1 );
132 return -1;137 return -1;
133}138}
134139
diff --git a/servers/slapd/aci.c b/servers/slapd/aci.c
index 33e6074..c8cc41d 100644
--- a/servers/slapd/aci.c
+++ b/servers/slapd/aci.c
@@ -39,6 +39,7 @@
39#include "slap.h"39#include "slap.h"
40#include "lber_pvt.h"40#include "lber_pvt.h"
41#include "lutil.h"41#include "lutil.h"
42#include "slap-config.h"
4243
43/* use most appropriate size */44/* use most appropriate size */
44#define ACI_BUF_SIZE 102445#define ACI_BUF_SIZE 1024
@@ -741,8 +742,7 @@ aci_init( void )
741742
742static int743static int
743dynacl_aci_parse(744dynacl_aci_parse(
744 const char *fname,745 ConfigArgs *c,
745 int lineno,
746 const char *opts,746 const char *opts,
747 slap_style_t sty,747 slap_style_t sty,
748 const char *right,748 const char *right,
@@ -752,17 +752,19 @@ dynacl_aci_parse(
752 const char *text = NULL;752 const char *text = NULL;
753753
754 if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {754 if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {
755 fprintf( stderr, "%s: line %d: "755 snprintf( c->cr_msg, sizeof( c->cr_msg ),
756 "inappropriate style \"%s\" in \"aci\" by clause\n",756 "inappropriate style \"%s\" in \"aci\" by clause",
757 fname, lineno, style_strings[sty] );757 style_strings[sty] );
758 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
758 return -1;759 return -1;
759 }760 }
760761
761 if ( right != NULL && *right != '\0' ) {762 if ( right != NULL && *right != '\0' ) {
762 if ( slap_str2ad( right, &ad, &text ) != LDAP_SUCCESS ) {763 if ( slap_str2ad( right, &ad, &text ) != LDAP_SUCCESS ) {
763 fprintf( stderr,764 snprintf( c->cr_msg, sizeof( c->cr_msg ),
764 "%s: line %d: aci \"%s\": %s\n",765 "aci \"%s\": %s",
765 fname, lineno, right, text );766 right, text );
767 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
766 return -1;768 return -1;
767 }769 }
768770
@@ -771,10 +773,10 @@ dynacl_aci_parse(
771 }773 }
772774
773 if ( !is_at_syntax( ad->ad_type, SLAPD_ACI_SYNTAX) ) {775 if ( !is_at_syntax( ad->ad_type, SLAPD_ACI_SYNTAX) ) {
774 fprintf( stderr, "%s: line %d: "776 snprintf( c->cr_msg, sizeof( c->cr_msg ),
775 "aci \"%s\": inappropriate syntax: %s\n",777 "aci \"%s\": inappropriate syntax: %s",
776 fname, lineno, right,778 right, ad->ad_type->sat_syntax_oid );
777 ad->ad_type->sat_syntax_oid );779 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
778 return -1;780 return -1;
779 }781 }
780782
diff --git a/servers/slapd/aclparse.c b/servers/slapd/aclparse.c
index 60b74e3..f08de6a 100644
--- a/servers/slapd/aclparse.c
+++ b/servers/slapd/aclparse.c
@@ -37,6 +37,7 @@
37#include "slap.h"37#include "slap.h"
38#include "lber_pvt.h"38#include "lber_pvt.h"
39#include "lutil.h"39#include "lutil.h"
40#include "slap-config.h"
4041
41static const char style_base[] = "base";42static const char style_base[] = "base";
42const char *style_strings[] = {43const char *style_strings[] = {
@@ -76,8 +77,7 @@ static int check_scope( BackendDB *be, AccessControl *a );
76#ifdef SLAP_DYNACL77#ifdef SLAP_DYNACL
77static int78static int
78slap_dynacl_config(79slap_dynacl_config(
79 const char *fname,80 struct config_args_s *c,
80 int lineno,
81 Access *b,81 Access *b,
82 const char *name,82 const char *name,
83 const char *opts,83 const char *opts,
@@ -89,9 +89,10 @@ slap_dynacl_config(
8989
90 for ( da = b->a_dynacl; da; da = da->da_next ) {90 for ( da = b->a_dynacl; da; da = da->da_next ) {
91 if ( strcasecmp( da->da_name, name ) == 0 ) {91 if ( strcasecmp( da->da_name, name ) == 0 ) {
92 Debug( LDAP_DEBUG_ANY,92 snprintf( c->cr_msg, sizeof( c->cr_msg ),
93 "%s: line %d: dynacl \"%s\" already specified.\n",93 "dynacl \"%s\" already specified",
94 fname, lineno, name );94 name );
95 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
95 return acl_usage();96 return acl_usage();
96 }97 }
97 }98 }
@@ -105,7 +106,7 @@ slap_dynacl_config(
105 *tmp = *da;106 *tmp = *da;
106107
107 if ( tmp->da_parse ) {108 if ( tmp->da_parse ) {
108 rc = ( *tmp->da_parse )( fname, lineno, opts, sty, right, &tmp->da_private );109 rc = ( *tmp->da_parse )( c, opts, sty, right, &tmp->da_private );
109 if ( rc ) {110 if ( rc ) {
110 ch_free( tmp );111 ch_free( tmp );
111 return rc;112 return rc;
@@ -119,8 +120,8 @@ slap_dynacl_config(
119}120}
120#endif /* SLAP_DYNACL */121#endif /* SLAP_DYNACL */
121122
122static void123static int
123regtest(const char *fname, int lineno, char *pat) {124regtest(struct config_args_s *c, char *pat) {
124 int e;125 int e;
125 regex_t re;126 regex_t re;
126127
@@ -156,25 +157,27 @@ regtest(const char *fname, int lineno, char *pat) {
156157
157 *dp = '\0';158 *dp = '\0';
158 if ( size >= (sizeof(buf) - 1) ) {159 if ( size >= (sizeof(buf) - 1) ) {
159 Debug( LDAP_DEBUG_ANY,160 snprintf( c->cr_msg, sizeof( c->cr_msg),
160 "%s: line %d: regular expression \"%s\" too large\n",161 "regular expression too large \"%s\"", pat);
161 fname, lineno, pat );162 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
162 (void)acl_usage();163 (void)acl_usage();
163 exit( EXIT_FAILURE );164 return -1;
164 }165 }
165166
166 if ((e = regcomp(&re, buf, REG_EXTENDED|REG_ICASE))) {167 if ( (e = regcomp(&re, buf, REG_EXTENDED|REG_ICASE)) ) {
167 char error[ SLAP_TEXT_BUFLEN ];168 char error[ SLAP_TEXT_BUFLEN ];
168169
169 regerror(e, &re, error, sizeof(error));170 regerror(e, &re, error, sizeof(error));
170171
171 Debug(LDAP_DEBUG_ANY,172 snprintf( c->cr_msg, sizeof ( c->cr_msg ),
172 "%s: line %d: regular expression \"%s\" bad because of %s\n",173 "regular expression \"%s\" bad because of %s", pat, error);
173 fname, lineno, pat, error );174 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
174 acl_usage();175 acl_usage();
175 exit( EXIT_FAILURE );176 regfree(&re);
177 return -1;
176 }178 }
177 regfree(&re);179 regfree(&re);
180 return 0;
178}181}
179182
180/*183/*
@@ -212,7 +215,7 @@ check_scope( BackendDB *be, AccessControl *a )
212 ber_len_t rebuflen;215 ber_len_t rebuflen;
213 regex_t re;216 regex_t re;
214 int rc;217 int rc;
215 218
216 /* add trailing '$' to database suffix to form219 /* add trailing '$' to database suffix to form
217 * a simple trial regex pattern "<suffix>$" */220 * a simple trial regex pattern "<suffix>$" */
218 AC_MEMCPY( dnbuf, be->be_nsuffix[0].bv_val,221 AC_MEMCPY( dnbuf, be->be_nsuffix[0].bv_val,
@@ -319,11 +322,7 @@ regex_done:;
319322
320int323int
321parse_acl(324parse_acl(
322 Backend *be,325 struct config_args_s *c,
323 const char *fname,
324 int lineno,
325 int argc,
326 char **argv,
327 int pos )326 int pos )
328{327{
329 int i;328 int i;
@@ -333,14 +332,19 @@ parse_acl(
333 Access *b = NULL;332 Access *b = NULL;
334 int rc;333 int rc;
335 const char *text;334 const char *text;
335 Backend *be = c->be;
336 const char *fname = c->fname;
337 int lineno = c->lineno;
338 int argc = c->argc;
339 char **argv = c->argv;
336340
337 for ( i = 1; i < argc; i++ ) {341 for ( i = 1; i < argc; i++ ) {
338 /* to clause - select which entries are protected */342 /* to clause - select which entries are protected */
339 if ( strcasecmp( argv[i], "to" ) == 0 ) {343 if ( strcasecmp( argv[i], "to" ) == 0 ) {
340 if ( a != NULL ) {344 if ( a != NULL ) {
341 Debug( LDAP_DEBUG_ANY, "%s: line %d: "345 snprintf( c->cr_msg, sizeof( c->cr_msg ),
342 "only one to clause allowed in access line\n",346 "only one to clause allowed in access line" );
343 fname, lineno );347 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
344 goto fail;348 goto fail;
345 }349 }
346 a = (AccessControl *) ch_calloc( 1, sizeof(AccessControl) );350 a = (AccessControl *) ch_calloc( 1, sizeof(AccessControl) );
@@ -355,10 +359,9 @@ parse_acl(
355 if ( !BER_BVISEMPTY( &a->acl_dn_pat ) ||359 if ( !BER_BVISEMPTY( &a->acl_dn_pat ) ||
356 a->acl_dn_style != ACL_STYLE_REGEX )360 a->acl_dn_style != ACL_STYLE_REGEX )
357 {361 {
358 Debug( LDAP_DEBUG_ANY,362 snprintf( c->cr_msg, sizeof( c->cr_msg ),
359 "%s: line %d: dn pattern"363 "dn pattern already specified in to clause." );
360 " already specified in to clause.\n",364 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
361 fname, lineno );
362 goto fail;365 goto fail;
363 }366 }
364367
@@ -370,9 +373,9 @@ parse_acl(
370 split( left, '.', &left, &style );373 split( left, '.', &left, &style );
371374
372 if ( right == NULL ) {375 if ( right == NULL ) {
373 Debug( LDAP_DEBUG_ANY, "%s: line %d: "376 snprintf( c->cr_msg, sizeof( c->cr_msg ),
374 "missing \"=\" in \"%s\" in to clause\n",377 "missing \"=\" in \"%s\" in to clause", left );
375 fname, lineno, left );378 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
376 goto fail;379 goto fail;
377 }380 }
378381
@@ -380,10 +383,9 @@ parse_acl(
380 if ( !BER_BVISEMPTY( &a->acl_dn_pat ) ||383 if ( !BER_BVISEMPTY( &a->acl_dn_pat ) ||
381 a->acl_dn_style != ACL_STYLE_REGEX )384 a->acl_dn_style != ACL_STYLE_REGEX )
382 {385 {
383 Debug( LDAP_DEBUG_ANY,386 snprintf( c->cr_msg, sizeof( c->cr_msg),
384 "%s: line %d: dn pattern"387 "dn pattern already specified in to clause" );
385 " already specified in to clause.\n",388 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
386 fname, lineno );
387 goto fail;389 goto fail;
388 }390 }
389391
@@ -424,12 +426,12 @@ parse_acl(
424 a->acl_dn_style = ACL_STYLE_BASE;426 a->acl_dn_style = ACL_STYLE_BASE;
425 ber_str2bv( right, 0, 1, &a->acl_dn_pat );427 ber_str2bv( right, 0, 1, &a->acl_dn_pat );
426428
427 } else if ( strcmp(right, "*") == 0 429 } else if ( strcmp(right, "*") == 0
428 || strcmp(right, ".*") == 0 430 || strcmp(right, ".*") == 0
429 || strcmp(right, ".*$") == 0 431 || strcmp(right, ".*$") == 0
430 || strcmp(right, "^.*") == 0 432 || strcmp(right, "^.*") == 0
431 || strcmp(right, "^.*$") == 0433 || strcmp(right, "^.*$") == 0
432 || strcmp(right, ".*$$") == 0 434 || strcmp(right, ".*$$") == 0
433 || strcmp(right, "^.*$$") == 0 )435 || strcmp(right, "^.*$$") == 0 )
434 {436 {
435 ber_str2bv( "*", STRLENOF("*"), 1, &a->acl_dn_pat );437 ber_str2bv( "*", STRLENOF("*"), 1, &a->acl_dn_pat );
@@ -439,9 +441,9 @@ parse_acl(
439 }441 }
440442
441 } else {443 } else {
442 Debug( LDAP_DEBUG_ANY, "%s: line %d: "444 snprintf( c->cr_msg, sizeof( c->cr_msg ),
443 "unknown dn style \"%s\" in to clause\n",445 "unknown dn style \"%s\" in to clause", style );
444 fname, lineno, style );446 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
445 goto fail;447 goto fail;
446 }448 }
447449
@@ -450,9 +452,9 @@ parse_acl(
450452
451 if ( strcasecmp( left, "filter" ) == 0 ) {453 if ( strcasecmp( left, "filter" ) == 0 ) {
452 if ( (a->acl_filter = str2filter( right )) == NULL ) {454 if ( (a->acl_filter = str2filter( right )) == NULL ) {
453 Debug( LDAP_DEBUG_ANY,455 snprintf( c->cr_msg, sizeof( c->cr_msg ),
454 "%s: line %d: bad filter \"%s\" in to clause\n",456 "bad filter \"%s\" in to clause", right );
455 fname, lineno, right );457 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
456 goto fail;458 goto fail;
457 }459 }
458460
@@ -460,37 +462,36 @@ parse_acl(
460 || strcasecmp( left, "attrs" ) == 0 ) /* DOCUMENTED */462 || strcasecmp( left, "attrs" ) == 0 ) /* DOCUMENTED */
461 {463 {
462 if ( strcasecmp( left, "attr" ) == 0 ) {464 if ( strcasecmp( left, "attr" ) == 0 ) {
463 Debug( LDAP_DEBUG_ANY,465 snprintf( c->cr_msg, sizeof( c->cr_msg ),
464 "%s: line %d: \"attr\" "466 "\"attr\" is deprecated (and undocumented); "
465 "is deprecated (and undocumented); "467 "use \"attrs\" instead");
466 "use \"attrs\" instead.\n",468 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
467 fname, lineno );
468 }469 }
469470
470 a->acl_attrs = str2anlist( a->acl_attrs,471 a->acl_attrs = str2anlist( a->acl_attrs,
471 right, "," );472 right, "," );
472 if ( a->acl_attrs == NULL ) {473 if ( a->acl_attrs == NULL ) {
473 Debug( LDAP_DEBUG_ANY,474 snprintf( c->cr_msg, sizeof( c->cr_msg ),
474 "%s: line %d: unknown attr \"%s\" in to clause\n",475 "unknown attr \"%s\" in to clause", right );
475 fname, lineno, right );476 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
476 goto fail;477 goto fail;
477 }478 }
478479
479 } else if ( strncasecmp( left, "val", 3 ) == 0 ) {480 } else if ( strncasecmp( left, "val", 3 ) == 0 ) {
480 struct berval bv;481 struct berval bv;
481 char *mr;482 char *mr;
482 483
483 if ( !BER_BVISEMPTY( &a->acl_attrval ) ) {484 if ( !BER_BVISEMPTY( &a->acl_attrval ) ) {
484 Debug( LDAP_DEBUG_ANY,485 snprintf( c->cr_msg, sizeof( c->cr_msg ),
485 "%s: line %d: attr val already specified in to clause.\n",486 "attr val already specified in to clause" );
486 fname, lineno );487 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
487 goto fail;488 goto fail;
488 }489 }
489 if ( a->acl_attrs == NULL || !BER_BVISEMPTY( &a->acl_attrs[1].an_name ) )490 if ( a->acl_attrs == NULL || !BER_BVISEMPTY( &a->acl_attrs[1].an_name ) )
490 {491 {
491 Debug( LDAP_DEBUG_ANY,492 snprintf( c->cr_msg, sizeof( c->cr_msg ),
492 "%s: line %d: attr val requires a single attribute.\n",493 "attr val requires a single attribute");
493 fname, lineno );494 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
494 goto fail;495 goto fail;
495 }496 }
496497
@@ -504,23 +505,23 @@ parse_acl(
504505
505 a->acl_attrval_mr = mr_find( mr );506 a->acl_attrval_mr = mr_find( mr );
506 if ( a->acl_attrval_mr == NULL ) {507 if ( a->acl_attrval_mr == NULL ) {
507 Debug( LDAP_DEBUG_ANY, "%s: line %d: "508 snprintf( c->cr_msg, sizeof( c->cr_msg ),
508 "invalid matching rule \"%s\".\n",509 "invalid matching rule \"%s\"", mr);
509 fname, lineno, mr );510 Debug( LDAP_DEBUG_ANY, "%s: %s\n", c->log, c->cr_msg );
510 goto fail;511 goto fail;
511 }512 }
512513
513 if( !mr_usable_with_at( a->acl_attrval_mr, a->acl_attrs[ 0 ].an_desc->ad_type ) )514 if( !mr_usable_with_at( a->acl_attrval_mr, a->acl_attrs[ 0 ].an_desc->ad_type ) )
514 {515 {
515 Debug(LDAP_DEBUG_ANY,516 snprintf( c->cr_msg, sizeof( c->cr_msg ),
516 "%s: line %d: matching rule \"%s\" use " "with attr \"%s\" not appropriate.\n",517 "matching rule \"%s\" use " "with attr \"%s\" not appropriate",
517 fname, lineno,518 mr,
518 mr,519 a->acl_attrs[0].an_name.bv_val );
519 a->acl_attrs[0].an_name.bv_val );520 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c-> log, c->cr_msg );
520 goto fail;521 goto fail;
521 }522 }
522 }523 }
523 524
524 if ( style != NULL ) {525 if ( style != NULL ) {
525 if ( strcasecmp( style, "regex" ) == 0 ) {526 if ( strcasecmp( style, "regex" ) == 0 ) {
526 int e = regcomp( &a->acl_attrval_re, bv.bv_val,527 int e = regcomp( &a->acl_attrval_re, bv.bv_val,
@@ -529,9 +530,10 @@ parse_acl(
529 char err[SLAP_TEXT_BUFLEN];530 char err[SLAP_TEXT_BUFLEN];
530531
531 regerror( e, &a->acl_attrval_re, err, sizeof( err ) );532 regerror( e, &a->acl_attrval_re, err, sizeof( err ) );
532 Debug(LDAP_DEBUG_ANY,533 snprintf( c->cr_msg, sizeof( c->cr_msg ),
533 "%s: line %d: regular expression \"%s\" bad because of %s\n",534 "regular expression \"%s\" bad because of %s",
534 fname, lineno, right, err );535 right, err );
536 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
535 goto fail;537 goto fail;
536 }538 }
537 a->acl_attrval_style = ACL_STYLE_REGEX;539 a->acl_attrval_style = ACL_STYLE_REGEX;
@@ -561,34 +563,31 @@ parse_acl(
561 } else if ( !strcasecmp( style, "children" ) ) {563 } else if ( !strcasecmp( style, "children" ) ) {
562 a->acl_attrval_style = ACL_STYLE_CHILDREN;564 a->acl_attrval_style = ACL_STYLE_CHILDREN;
563 } else {565 } else {
564 Debug(LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL,566 snprintf( c->cr_msg, sizeof( c->cr_msg ),
565 "%s: line %d: unknown val.<style> \"%s\" for attributeType \"%s\" " "with DN syntax.\n",567 "unknown val.<style> \"%s\" for attributeType \"%s\" " "with DN syntax",
566 fname,
567 lineno,
568 style,568 style,
569 a->acl_attrs[0].an_desc->ad_cname.bv_val );569 a->acl_attrs[0].an_desc->ad_cname.bv_val );
570 Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL, "%s: %s.\n", c->log, c->cr_msg );
570 goto fail;571 goto fail;
571 }572 }
572573
573 rc = dnNormalize( 0, NULL, NULL, &bv, &a->acl_attrval, NULL );574 rc = dnNormalize( 0, NULL, NULL, &bv, &a->acl_attrval, NULL );
574 if ( rc != LDAP_SUCCESS ) {575 if ( rc != LDAP_SUCCESS ) {
575 Debug(LDAP_DEBUG_ANY,576 snprintf( c->cr_msg, sizeof( c->cr_msg ),
576 "%s: line %d: unable to normalize DN \"%s\" " "for attributeType \"%s\" (%d).\n",577 "unable to normalize DN \"%s\" " "for attributeType \"%s\" (%d)",
577 fname,
578 lineno,
579 bv.bv_val,578 bv.bv_val,
580 a->acl_attrs[0].an_desc->ad_cname.bv_val,579 a->acl_attrs[0].an_desc->ad_cname.bv_val,
581 rc );580 rc );
581 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
582 goto fail;582 goto fail;
583 }583 }
584584
585 } else {585 } else {
586 Debug(LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL,586 snprintf( c->cr_msg, sizeof( c->cr_msg ),
587 "%s: line %d: unknown val.<style> \"%s\" for attributeType \"%s\".\n",587 "unknown val.<style> \"%s\" for attributeType \"%s\"",
588 fname,588 fname,
589 lineno,
590 style,
591 a->acl_attrs[0].an_desc->ad_cname.bv_val );589 a->acl_attrs[0].an_desc->ad_cname.bv_val );
590 Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL, "%s: %s.\n", c->log, c->cr_msg );
592 goto fail;591 goto fail;
593 }592 }
594 }593 }
@@ -607,9 +606,10 @@ parse_acl(
607 }606 }
608607
609 if ( a->acl_attrval_mr == NULL ) {608 if ( a->acl_attrval_mr == NULL ) {
610 Debug( LDAP_DEBUG_ANY, "%s: line %d: "609 snprintf( c->cr_msg, sizeof( c->cr_msg ),
611 "attr \"%s\" does not have an EQUALITY matching rule.\n",610 "attr \"%s\" does not have an EQUALITY matching rule",
612 fname, lineno, a->acl_attrs[ 0 ].an_name.bv_val );611 a->acl_attrs[ 0 ].an_name.bv_val );
612 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
613 goto fail;613 goto fail;
614 }614 }
615615
@@ -622,42 +622,43 @@ parse_acl(
622 &text,622 &text,
623 NULL );623 NULL );
624 if ( rc != LDAP_SUCCESS ) {624 if ( rc != LDAP_SUCCESS ) {
625 Debug(LDAP_DEBUG_ANY,625 snprintf( c->cr_msg, sizeof( c->cr_msg ),
626 "%s: line %d: %s: line %d: " " attr \"%s\" normalization failed (%d: %s).\n",626 "attr \"%s\" normalization failed (%d: %s).\n",
627 fname, lineno,
628 fname, lineno,
629 a->acl_attrs[0].an_name.bv_val,627 a->acl_attrs[0].an_name.bv_val,
630 rc, text );628 rc, text );
629 Debug(LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
631 goto fail;630 goto fail;
632 }631 }
633 }632 }
634633
635 } else {634 } else {
636 Debug( LDAP_DEBUG_ANY,635 snprintf( c->cr_msg, sizeof( c->cr_msg ),
637 "%s: line %d: expecting <what> got \"%s\"\n",636 "expecting <what> got \"%s\"",
638 fname, lineno, left );637 left );
638 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
639 goto fail;639 goto fail;
640 }640 }
641 }641 }
642642
643 if ( !BER_BVISNULL( &a->acl_dn_pat ) && 643 if ( !BER_BVISNULL( &a->acl_dn_pat ) &&
644 ber_bvccmp( &a->acl_dn_pat, '*' ) )644 ber_bvccmp( &a->acl_dn_pat, '*' ) )
645 {645 {
646 free( a->acl_dn_pat.bv_val );646 free( a->acl_dn_pat.bv_val );
647 BER_BVZERO( &a->acl_dn_pat );647 BER_BVZERO( &a->acl_dn_pat );
648 a->acl_dn_style = ACL_STYLE_REGEX;648 a->acl_dn_style = ACL_STYLE_REGEX;
649 }649 }
650 650
651 if ( !BER_BVISEMPTY( &a->acl_dn_pat ) ||651 if ( !BER_BVISEMPTY( &a->acl_dn_pat ) ||
652 a->acl_dn_style != ACL_STYLE_REGEX ) 652 a->acl_dn_style != ACL_STYLE_REGEX )
653 {653 {
654 if ( a->acl_dn_style != ACL_STYLE_REGEX ) {654 if ( a->acl_dn_style != ACL_STYLE_REGEX ) {
655 struct berval bv;655 struct berval bv;
656 rc = dnNormalize( 0, NULL, NULL, &a->acl_dn_pat, &bv, NULL);656 rc = dnNormalize( 0, NULL, NULL, &a->acl_dn_pat, &bv, NULL);
657 if ( rc != LDAP_SUCCESS ) {657 if ( rc != LDAP_SUCCESS ) {
658 Debug( LDAP_DEBUG_ANY,658 snprintf( c->cr_msg, sizeof(c->cr_msg ),
659 "%s: line %d: bad DN \"%s\" in to DN clause\n",659 "bad DN \"%s\" in to DN clause",
660 fname, lineno, a->acl_dn_pat.bv_val );660 a->acl_dn_pat.bv_val );
661 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
661 goto fail;662 goto fail;
662 }663 }
663 free( a->acl_dn_pat.bv_val );664 free( a->acl_dn_pat.bv_val );
@@ -670,9 +671,10 @@ parse_acl(
670 char err[ SLAP_TEXT_BUFLEN ];671 char err[ SLAP_TEXT_BUFLEN ];
671672
672 regerror( e, &a->acl_dn_re, err, sizeof( err ) );673 regerror( e, &a->acl_dn_re, err, sizeof( err ) );
673 Debug(LDAP_DEBUG_ANY,674 snprintf( c->cr_msg, sizeof( c->cr_msg ),
674 "%s: line %d: regular expression \"%s\" bad because of %s\n",675 "regular expression \"%s\" bad because of %s",
675 fname, lineno, right, err );676 right, err );
677 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
676 goto fail;678 goto fail;
677 }679 }
678 }680 }
@@ -681,9 +683,9 @@ parse_acl(
681 /* by clause - select who has what access to entries */683 /* by clause - select who has what access to entries */
682 } else if ( strcasecmp( argv[i], "by" ) == 0 ) {684 } else if ( strcasecmp( argv[i], "by" ) == 0 ) {
683 if ( a == NULL ) {685 if ( a == NULL ) {
684 Debug( LDAP_DEBUG_ANY, "%s: line %d: "686 snprintf( c->cr_msg, sizeof( c->cr_msg ),
685 "to clause required before by clause in access line\n",687 "to clause required before by clause in access line");
686 fname, lineno );688 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
687 goto fail;689 goto fail;
688 }690 }
689691
@@ -692,9 +694,9 @@ parse_acl(
692 */694 */
693695
694 if ( ++i == argc ) {696 if ( ++i == argc ) {
695 Debug( LDAP_DEBUG_ANY,697 snprintf( c->cr_msg, sizeof( c->cr_msg ),
696 "%s: line %d: premature EOL: expecting <who>\n",698 "premature EOL: expecting <who>");
697 fname, lineno );699 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
698 goto fail;700 goto fail;
699 }701 }
700702
@@ -722,16 +724,14 @@ parse_acl(
722 if ( style_level != NULL ) {724 if ( style_level != NULL ) {
723 char *p = strchr( style_level, '}' );725 char *p = strchr( style_level, '}' );
724 if ( p == NULL ) {726 if ( p == NULL ) {
725 Debug( LDAP_DEBUG_ANY,727 snprintf( c->cr_msg, sizeof( c->cr_msg ),
726 "%s: line %d: premature eol: "728 "premature eol: expecting closing '}' in \"level{n}\"");
727 "expecting closing '}' in \"level{n}\"\n",729 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
728 fname, lineno );
729 goto fail;730 goto fail;
730 } else if ( p == style_level ) {731 } else if ( p == style_level ) {
731 Debug( LDAP_DEBUG_ANY,732 snprintf( c->cr_msg, sizeof( c->cr_msg ),
732 "%s: line %d: empty level "733 "empty level in \"level{n}\"");
733 "in \"level{n}\"\n",734 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
734 fname, lineno );
735 goto fail;735 goto fail;
736 }736 }
737 p[0] = '\0';737 p[0] = '\0';
@@ -762,10 +762,9 @@ parse_acl(
762 } else if ( strcasecmp( style, "level" ) == 0 )762 } else if ( strcasecmp( style, "level" ) == 0 )
763 {763 {
764 if ( lutil_atoi( &level, style_level ) != 0 ) {764 if ( lutil_atoi( &level, style_level ) != 0 ) {
765 Debug( LDAP_DEBUG_ANY,765 snprintf( c->cr_msg, sizeof( c->cr_msg ),
766 "%s: line %d: unable to parse level "766 "unable to parse level in \"level{n}\"");
767 "in \"level{n}\"\n",767 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
768 fname, lineno );
769 goto fail;768 goto fail;
770 }769 }
771770
@@ -782,26 +781,25 @@ parse_acl(
782781
783 } else if ( strcasecmp( style, "ipv6" ) == 0 ) {782 } else if ( strcasecmp( style, "ipv6" ) == 0 ) {
784#ifndef LDAP_PF_INET6783#ifndef LDAP_PF_INET6
785 Debug( LDAP_DEBUG_ANY,784 snprintf( c->cr_msg, sizeof( c->cr_msg ),
786 "%s: line %d: IPv6 not supported\n",785 "IPv6 not supported");
787 fname, lineno );786 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
788#endif /* ! LDAP_PF_INET6 */787#endif /* ! LDAP_PF_INET6 */
789 sty = ACL_STYLE_IPV6;788 sty = ACL_STYLE_IPV6;
790789
791 } else if ( strcasecmp( style, "path" ) == 0 ) {790 } else if ( strcasecmp( style, "path" ) == 0 ) {
792 sty = ACL_STYLE_PATH;791 sty = ACL_STYLE_PATH;
793#ifndef LDAP_PF_LOCAL792#ifndef LDAP_PF_LOCAL
794 Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL,793 snprintf( c->cr_msg, sizeof( c->cr_msg),
795 "%s: line %d: "794 "\"path\" style modifier is useless without local");
796 "\"path\" style modifier is useless without local.\n",795 Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL, "%s: %s.\n", c->log, c->cr_msg );
797 fname, lineno );
798 goto fail;796 goto fail;
799#endif /* LDAP_PF_LOCAL */797#endif /* LDAP_PF_LOCAL */
800798
801 } else {799 } else {
802 Debug( LDAP_DEBUG_ANY,800 snprintf( c->cr_msg, sizeof ( c->cr_msg ),
803 "%s: line %d: unknown style \"%s\" in by clause\n",801 "unknown style \"%s\" in by clause", style );
804 fname, lineno, style );802 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
805 goto fail;803 goto fail;
806 }804 }
807805
@@ -810,9 +808,9 @@ parse_acl(
810 {808 {
811 switch ( sty ) {809 switch ( sty ) {
812 case ACL_STYLE_REGEX:810 case ACL_STYLE_REGEX:
813 Debug( LDAP_DEBUG_ANY, "%s: line %d: "811 snprintf( c->cr_msg, sizeof( c->cr_msg ),
814 "\"regex\" style implies \"expand\" modifier.\n",812 "\"regex\" style implies \"expand\" modifier" );
815 fname, lineno );813 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
816 goto fail;814 goto fail;
817 break;815 break;
818816
@@ -903,15 +901,15 @@ parse_acl(
903 } else {901 } else {
904 acl_regex_normalized_dn( right, &bv );902 acl_regex_normalized_dn( right, &bv );
905 if ( !ber_bvccmp( &bv, '*' ) ) {903 if ( !ber_bvccmp( &bv, '*' ) ) {
906 regtest( fname, lineno, bv.bv_val );904 if ( regtest( c, bv.bv_val ) != 0)
905 goto fail;
907 }906 }
908 }907 }
909908
910 } else if ( right == NULL || *right == '\0' ) {909 } else if ( right == NULL || *right == '\0' ) {
911 Debug( LDAP_DEBUG_ANY, "%s: line %d: "910 snprintf( c->cr_msg, sizeof( c->cr_msg ),
912 "missing \"=\" in (or value after) \"%s\" "911 "missing \"=\" in (or value after) \"%s\" in by clause", left );
913 "in by clause\n",912 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
914 fname, lineno, left );
915 goto fail;913 goto fail;
916914
917 } else {915 } else {
@@ -924,9 +922,9 @@ parse_acl(
924922
925 if ( !BER_BVISNULL( &bv ) ) {923 if ( !BER_BVISNULL( &bv ) ) {
926 if ( !BER_BVISEMPTY( &bdn->a_pat ) ) {924 if ( !BER_BVISEMPTY( &bdn->a_pat ) ) {
927 Debug( LDAP_DEBUG_ANY,925 snprintf( c->cr_msg, sizeof( c->cr_msg ),
928 "%s: line %d: dn pattern already specified.\n",926 "dn pattern already specified" );
929 fname, lineno );927 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
930 goto fail;928 goto fail;
931 }929 }
932930
@@ -939,9 +937,9 @@ parse_acl(
939 rc = dnNormalize(0, NULL, NULL,937 rc = dnNormalize(0, NULL, NULL,
940 &bv, &bdn->a_pat, NULL);938 &bv, &bdn->a_pat, NULL);
941 if ( rc != LDAP_SUCCESS ) {939 if ( rc != LDAP_SUCCESS ) {
942 Debug( LDAP_DEBUG_ANY,940 snprintf( c->cr_msg, sizeof( c->cr_msg ),
943 "%s: line %d: bad DN \"%s\" in by DN clause\n",941 "bad DN \"%s\" in by DN clause", bv.bv_val );
944 fname, lineno, bv.bv_val );942 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
945 goto fail;943 goto fail;
946 }944 }
947 free( bv.bv_val );945 free( bv.bv_val );
@@ -950,10 +948,9 @@ parse_acl(
950 && !BER_BVISNULL( &be->be_rootndn )948 && !BER_BVISNULL( &be->be_rootndn )
951 && dn_match( &bdn->a_pat, &be->be_rootndn ) )949 && dn_match( &bdn->a_pat, &be->be_rootndn ) )
952 {950 {
953 Debug( LDAP_DEBUG_ANY,951 snprintf( c->cr_msg, sizeof( c->cr_msg ),
954 "%s: line %d: rootdn is always granted "952 "rootdn is always granted unlimited privileges" );
955 "unlimited privileges.\n",953 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
956 fname, lineno );
957 }954 }
958955
959 } else {956 } else {
@@ -980,32 +977,29 @@ parse_acl(
980 bdn->a_expand = expand;977 bdn->a_expand = expand;
981978
982 } else {979 } else {
983 Debug( LDAP_DEBUG_ANY, "%s: line %d: "980 snprintf( c->cr_msg, sizeof( c->cr_msg ),
984 "\"expand\" used with no expansions in \"pattern\".\n",981 "\"expand\" used with no expansions in \"pattern\"");
985 fname, lineno );982 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
986 goto fail;983 goto fail;
987 } 984 }
988 }985 }
989 if ( sty == ACL_STYLE_SELF ) {986 if ( sty == ACL_STYLE_SELF ) {
990 bdn->a_self_level = level;987 bdn->a_self_level = level;
991988
992 } else {989 } else {
993 if ( level < 0 ) {990 if ( level < 0 ) {
994 Debug( LDAP_DEBUG_ANY,991 snprintf( c->cr_msg, sizeof( c ->cr_msg ),
995 "%s: line %d: bad negative level \"%d\" "992 "bad negative level \"%d\" in by DN clause", level );
996 "in by DN clause\n",993 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
997 fname, lineno, level );
998 goto fail;994 goto fail;
999 } else if ( level == 1 ) {995 } else if ( level == 1 ) {
1000 Debug( LDAP_DEBUG_ANY,996 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1001 "%s: line %d: \"onelevel\" should be used "997 "\"onelevel\" should be used instead of \"level{1}\" in by DN clause" );
1002 "instead of \"level{1}\" in by DN clause\n",998 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1003 fname, lineno );
1004 } else if ( level == 0 && sty == ACL_STYLE_LEVEL ) {999 } else if ( level == 0 && sty == ACL_STYLE_LEVEL ) {
1005 Debug( LDAP_DEBUG_ANY,1000 snprintf ( c->cr_msg, sizeof( c->cr_msg ),
1006 "%s: line %d: \"base\" should be used "1001 "\"base\" should be used instead of \"level{0}\" in by DN clause" );
1007 "instead of \"level{0}\" in by DN clause\n",1002 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1008 fname, lineno );
1009 }1003 }
10101004
1011 bdn->a_level = level;1005 bdn->a_level = level;
@@ -1015,27 +1009,25 @@ parse_acl(
10151009
1016 if ( strcasecmp( left, "dnattr" ) == 0 ) {1010 if ( strcasecmp( left, "dnattr" ) == 0 ) {
1017 if ( right == NULL || right[0] == '\0' ) {1011 if ( right == NULL || right[0] == '\0' ) {
1018 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1012 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1019 "missing \"=\" in (or value after) \"%s\" "1013 "missing \"=\" in (or value after) \"%s\" in by clause", left );
1020 "in by clause\n",1014 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1021 fname, lineno, left );
1022 goto fail;1015 goto fail;
1023 }1016 }
10241017
1025 if( bdn->a_at != NULL ) {1018 if( bdn->a_at != NULL ) {
1026 Debug( LDAP_DEBUG_ANY,1019 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1027 "%s: line %d: dnattr already specified.\n",1020 "dnattr already specified" );
1028 fname, lineno );1021 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1029 goto fail;1022 goto fail;
1030 }1023 }
10311024
1032 rc = slap_str2ad( right, &bdn->a_at, &text );1025 rc = slap_str2ad( right, &bdn->a_at, &text );
10331026
1034 if( rc != LDAP_SUCCESS ) {1027 if( rc != LDAP_SUCCESS ) {
1035 Debug(LDAP_DEBUG_ANY,1028 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1036 "%s: line %d: dnattr \"%s\": %s\n",1029 "dnattr \"%s\": %s", right, text );
1037 fname, lineno, right,1030 Debug(LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1038 text );
1039 goto fail;1031 goto fail;
1040 }1032 }
10411033
@@ -1045,18 +1037,17 @@ parse_acl(
1045 !is_at_syntax( bdn->a_at->ad_type,1037 !is_at_syntax( bdn->a_at->ad_type,
1046 SLAPD_NAMEUID_SYNTAX ))1038 SLAPD_NAMEUID_SYNTAX ))
1047 {1039 {
1048 Debug(LDAP_DEBUG_ANY,1040 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1049 "%s: line %d: dnattr \"%s\": " "inappropriate syntax: %s\n\n",1041 "dnattr \"%s\": " "inappropriate syntax: %s",
1050 fname, lineno, right,1042 right, bdn->a_at->ad_type->sat_syntax_oid );
1051 bdn->a_at->ad_type->sat_syntax_oid );1043 Debug(LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1052 goto fail;1044 goto fail;
1053 }1045 }
10541046
1055 if( bdn->a_at->ad_type->sat_equality == NULL ) {1047 if( bdn->a_at->ad_type->sat_equality == NULL ) {
1056 Debug( LDAP_DEBUG_ANY,1048 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1057 "%s: line %d: dnattr \"%s\": "1049 "dnattr \"%s\": inappropriate matching (no EQUALITY)", right );
1058 "inappropriate matching (no EQUALITY)\n",1050 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1059 fname, lineno, right );
1060 goto fail;1051 goto fail;
1061 }1052 }
10621053
@@ -1071,11 +1062,9 @@ parse_acl(
1071 switch ( sty ) {1062 switch ( sty ) {
1072 case ACL_STYLE_REGEX:1063 case ACL_STYLE_REGEX:
1073 /* legacy, tolerated */1064 /* legacy, tolerated */
1074 Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL,1065 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1075 "%s: line %d: "1066 "deprecated group style \"regex\"; use \"expand\" instead" );
1076 "deprecated group style \"regex\"; "1067 Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL, "%s: %s.\n", c->log, c->cr_msg );
1077 "use \"expand\" instead.\n",
1078 fname, lineno );
1079 sty = ACL_STYLE_EXPAND;1068 sty = ACL_STYLE_EXPAND;
1080 break;1069 break;
10811070
@@ -1087,26 +1076,23 @@ parse_acl(
10871076
1088 default:1077 default:
1089 /* unknown */1078 /* unknown */
1090 Debug( LDAP_DEBUG_ANY,1079 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1091 "%s: line %d: "1080 "inappropriate style \"%s\" in by clause", style );
1092 "inappropriate style \"%s\" in by clause.\n",1081 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1093 fname, lineno, style );
1094 goto fail;1082 goto fail;
1095 }1083 }
10961084
1097 if ( right == NULL || right[0] == '\0' ) {1085 if ( right == NULL || right[0] == '\0' ) {
1098 Debug( LDAP_DEBUG_ANY,1086 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1099 "%s: line %d: "1087 "missing \"=\" in (or value after) \"%s\" in by clause", left );
1100 "missing \"=\" in (or value after) \"%s\" "1088 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1101 "in by clause.\n",
1102 fname, lineno, left );
1103 goto fail;1089 goto fail;
1104 }1090 }
11051091
1106 if ( !BER_BVISEMPTY( &b->a_group_pat ) ) {1092 if ( !BER_BVISEMPTY( &b->a_group_pat ) ) {
1107 Debug( LDAP_DEBUG_ANY,1093 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1108 "%s: line %d: group pattern already specified.\n",1094 "group pattern already specified" );
1109 fname, lineno );1095 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1110 goto fail;1096 goto fail;
1111 }1097 }
11121098
@@ -1123,7 +1109,8 @@ parse_acl(
1123 if ( sty == ACL_STYLE_EXPAND ) {1109 if ( sty == ACL_STYLE_EXPAND ) {
1124 acl_regex_normalized_dn( right, &bv );1110 acl_regex_normalized_dn( right, &bv );
1125 if ( !ber_bvccmp( &bv, '*' ) ) {1111 if ( !ber_bvccmp( &bv, '*' ) ) {
1126 regtest( fname, lineno, bv.bv_val );1112 if ( regtest( c, bv.bv_val ) != 0)
1113 goto fail;
1127 }1114 }
1128 b->a_group_pat = bv;1115 b->a_group_pat = bv;
11291116
@@ -1132,9 +1119,9 @@ parse_acl(
1132 rc = dnNormalize( 0, NULL, NULL, &bv,1119 rc = dnNormalize( 0, NULL, NULL, &bv,
1133 &b->a_group_pat, NULL );1120 &b->a_group_pat, NULL );
1134 if ( rc != LDAP_SUCCESS ) {1121 if ( rc != LDAP_SUCCESS ) {
1135 Debug( LDAP_DEBUG_ANY,1122 snprintf( c->cr_msg, sizeof( c->cr_msg),
1136 "%s: line %d: bad DN \"%s\".\n",1123 "bad DN \"%s\"", right );
1137 fname, lineno, right );1124 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1138 goto fail;1125 goto fail;
1139 }1126 }
1140 }1127 }
@@ -1144,10 +1131,9 @@ parse_acl(
1144 *--value = '/';1131 *--value = '/';
11451132
1146 if ( b->a_group_oc == NULL ) {1133 if ( b->a_group_oc == NULL ) {
1147 Debug( LDAP_DEBUG_ANY,1134 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1148 "%s: line %d: group objectclass "1135 "group objectclass \"%s\" unknown", value );
1149 "\"%s\" unknown.\n",1136 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1150 fname, lineno, value );
1151 goto fail;1137 goto fail;
1152 }1138 }
11531139
@@ -1155,10 +1141,9 @@ parse_acl(
1155 b->a_group_oc = oc_find( SLAPD_GROUP_CLASS );1141 b->a_group_oc = oc_find( SLAPD_GROUP_CLASS );
11561142
1157 if( b->a_group_oc == NULL ) {1143 if( b->a_group_oc == NULL ) {
1158 Debug( LDAP_DEBUG_ANY,1144 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1159 "%s: line %d: group default objectclass "1145 "group default objectclass \"%s\" unknown", SLAPD_GROUP_CLASS );
1160 "\"%s\" unknown.\n",1146 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1161 fname, lineno, SLAPD_GROUP_CLASS );
1162 goto fail;1147 goto fail;
1163 }1148 }
1164 }1149 }
@@ -1166,20 +1151,18 @@ parse_acl(
1166 if ( is_object_subclass( slap_schema.si_oc_referral,1151 if ( is_object_subclass( slap_schema.si_oc_referral,
1167 b->a_group_oc ) )1152 b->a_group_oc ) )
1168 {1153 {
1169 Debug( LDAP_DEBUG_ANY,1154 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1170 "%s: line %d: group objectclass \"%s\" "1155 "group objectclass \"%s\" is subclass of referral", value );
1171 "is subclass of referral.\n",1156 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1172 fname, lineno, value );
1173 goto fail;1157 goto fail;
1174 }1158 }
11751159
1176 if ( is_object_subclass( slap_schema.si_oc_alias,1160 if ( is_object_subclass( slap_schema.si_oc_alias,
1177 b->a_group_oc ) )1161 b->a_group_oc ) )
1178 {1162 {
1179 Debug( LDAP_DEBUG_ANY,1163 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1180 "%s: line %d: group objectclass \"%s\" "1164 "group objectclass \"%s\" is subclass of alias", value );
1181 "is subclass of alias.\n",1165 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1182 fname, lineno, value );
1183 goto fail;1166 goto fail;
1184 }1167 }
11851168
@@ -1191,10 +1174,9 @@ parse_acl(
11911174
1192 rc = slap_str2ad( attr_name, &b->a_group_at, &text );1175 rc = slap_str2ad( attr_name, &b->a_group_at, &text );
1193 if ( rc != LDAP_SUCCESS ) {1176 if ( rc != LDAP_SUCCESS ) {
1194 Debug(LDAP_DEBUG_ANY,1177 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1195 "%s: line %d: group \"%s\": %s.\n",1178 "group \"%s\": %s", right, text );
1196 fname, lineno, right,1179 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1197 text );
1198 goto fail;1180 goto fail;
1199 }1181 }
12001182
@@ -1205,11 +1187,10 @@ parse_acl(
1205 && !is_at_subtype( b->a_group_at->ad_type,1187 && !is_at_subtype( b->a_group_at->ad_type,
1206 slap_schema.si_ad_labeledURI->ad_type ) /* e.g. memberURL */ )1188 slap_schema.si_ad_labeledURI->ad_type ) /* e.g. memberURL */ )
1207 {1189 {
1208 Debug(LDAP_DEBUG_ANY,1190 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1209 "%s: line %d: group \"%s\" attr \"%s\": inappropriate syntax: %s; " "must be " SLAPD_DN_SYNTAX " (DN), " SLAPD_NAMEUID_SYNTAX " (NameUID) " "or a subtype of labeledURI.\n",1191 "group \"%s\" attr \"%s\": inappropriate syntax: %s; " "must be " SLAPD_DN_SYNTAX " (DN), " SLAPD_NAMEUID_SYNTAX " (NameUID) " "or a subtype of labeledURI",
1210 fname, lineno, right,1192 right, attr_name, at_syntax(b->a_group_at->ad_type) );
1211 attr_name,1193 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1212 at_syntax(b->a_group_at->ad_type) );
1213 goto fail;1194 goto fail;
1214 }1195 }
12151196
@@ -1225,11 +1206,11 @@ parse_acl(
1225 ocs, NULL );1206 ocs, NULL );
12261207
1227 if( rc != 0 ) {1208 if( rc != 0 ) {
1228 Debug(LDAP_DEBUG_ANY,1209 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1229 "%s: line %d: group: \"%s\" not allowed by \"%s\".\n",1210 "group: \"%s\" not allowed by \"%s\".\n",
1230 fname, lineno,
1231 b->a_group_at->ad_cname.bv_val,1211 b->a_group_at->ad_cname.bv_val,
1232 b->a_group_oc->soc_oid );1212 b->a_group_oc->soc_oid );
1213 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1233 goto fail;1214 goto fail;
1234 }1215 }
1235 }1216 }
@@ -1250,24 +1231,23 @@ parse_acl(
1250 break;1231 break;
12511232
1252 default:1233 default:
1253 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1234 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1254 "inappropriate style \"%s\" in by clause.\n",1235 "inappropriate style \"%s\" in by clause", style );
1255 fname, lineno, style );1236 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1256 goto fail;1237 goto fail;
1257 }1238 }
12581239
1259 if ( right == NULL || right[0] == '\0' ) {1240 if ( right == NULL || right[0] == '\0' ) {
1260 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1241 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1261 "missing \"=\" in (or value after) \"%s\" "1242 "missing \"=\" in (or value after) \"%s\" in by clause", left);
1262 "in by clause.\n",1243 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1263 fname, lineno, left );
1264 goto fail;1244 goto fail;
1265 }1245 }
12661246
1267 if ( !BER_BVISEMPTY( &b->a_peername_pat ) ) {1247 if ( !BER_BVISEMPTY( &b->a_peername_pat ) ) {
1268 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1248 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1269 "peername pattern already specified.\n",1249 "peername pattern already specified" );
1270 fname, lineno );1250 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1271 goto fail;1251 goto fail;
1272 }1252 }
12731253
@@ -1275,7 +1255,8 @@ parse_acl(
1275 if ( sty == ACL_STYLE_REGEX ) {1255 if ( sty == ACL_STYLE_REGEX ) {
1276 acl_regex_normalized_dn( right, &bv );1256 acl_regex_normalized_dn( right, &bv );
1277 if ( !ber_bvccmp( &bv, '*' ) ) {1257 if ( !ber_bvccmp( &bv, '*' ) ) {
1278 regtest( fname, lineno, bv.bv_val );1258 if ( regtest( c, bv.bv_val ) != 0)
1259 goto fail;
1279 }1260 }
1280 b->a_peername_pat = bv;1261 b->a_peername_pat = bv;
12811262
@@ -1293,9 +1274,9 @@ parse_acl(
1293 b->a_peername_addr = inet_addr( addr );1274 b->a_peername_addr = inet_addr( addr );
1294 if ( b->a_peername_addr == (unsigned long)(-1) ) {1275 if ( b->a_peername_addr == (unsigned long)(-1) ) {
1295 /* illegal address */1276 /* illegal address */
1296 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1277 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1297 "illegal peername address \"%s\".\n",1278 "illegal peername address \"%s\"", addr );
1298 fname, lineno, addr );1279 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1299 goto fail;1280 goto fail;
1300 }1281 }
13011282
@@ -1306,13 +1287,12 @@ parse_acl(
1306 (unsigned long)(-1) )1287 (unsigned long)(-1) )
1307 {1288 {
1308 /* illegal mask */1289 /* illegal mask */
1309 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1290 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1310 "illegal peername address mask "1291 "illegal peername address mask \"%s\"", mask );
1311 "\"%s\".\n",1292 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1312 fname, lineno, mask );
1313 goto fail;1293 goto fail;
1314 }1294 }
1315 } 1295 }
13161296
1317 b->a_peername_port = -1;1297 b->a_peername_port = -1;
1318 if ( port ) {1298 if ( port ) {
@@ -1321,10 +1301,9 @@ parse_acl(
1321 b->a_peername_port = strtol( port, &end, 10 );1301 b->a_peername_port = strtol( port, &end, 10 );
1322 if ( end == port || end[0] != '}' ) {1302 if ( end == port || end[0] != '}' ) {
1323 /* illegal port */1303 /* illegal port */
1324 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1304 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1325 "illegal peername port specification "1305 "illegal peername port specification \"{%s}\"", port );
1326 "\"{%s}\".\n",1306 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1327 fname, lineno, port );
1328 goto fail;1307 goto fail;
1329 }1308 }
1330 }1309 }
@@ -1340,9 +1319,9 @@ parse_acl(
13401319
1341 if ( inet_pton( AF_INET6, addr, &b->a_peername_addr6 ) != 1 ) {1320 if ( inet_pton( AF_INET6, addr, &b->a_peername_addr6 ) != 1 ) {
1342 /* illegal address */1321 /* illegal address */
1343 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1322 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1344 "illegal peername address \"%s\".\n",1323 "illegal peername address \"%s\"", addr );
1345 fname, lineno, addr );1324 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1346 goto fail;1325 goto fail;
1347 }1326 }
13481327
@@ -1352,10 +1331,9 @@ parse_acl(
13521331
1353 if ( inet_pton( AF_INET6, mask, &b->a_peername_mask6 ) != 1 ) {1332 if ( inet_pton( AF_INET6, mask, &b->a_peername_mask6 ) != 1 ) {
1354 /* illegal mask */1333 /* illegal mask */
1355 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1334 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1356 "illegal peername address mask "1335 "illegal peername address mask \"%s\"", mask );
1357 "\"%s\".\n",1336 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1358 fname, lineno, mask );
1359 goto fail;1337 goto fail;
1360 }1338 }
13611339
@@ -1366,10 +1344,9 @@ parse_acl(
1366 b->a_peername_port = strtol( port, &end, 10 );1344 b->a_peername_port = strtol( port, &end, 10 );
1367 if ( end == port || end[0] != '}' ) {1345 if ( end == port || end[0] != '}' ) {
1368 /* illegal port */1346 /* illegal port */
1369 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1347 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1370 "illegal peername port specification "1348 "illegal peername port specification \"{%s}\"", port );
1371 "\"{%s}\".\n",1349 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1372 fname, lineno, port );
1373 goto fail;1350 goto fail;
1374 }1351 }
1375 }1352 }
@@ -1390,24 +1367,23 @@ parse_acl(
13901367
1391 default:1368 default:
1392 /* unknown */1369 /* unknown */
1393 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1370 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1394 "inappropriate style \"%s\" in by clause\n",1371 "inappropriate style \"%s\" in by clause", style );
1395 fname, lineno, style );1372 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1396 goto fail;1373 goto fail;
1397 }1374 }
13981375
1399 if ( right == NULL || right[0] == '\0' ) {1376 if ( right == NULL || right[0] == '\0' ) {
1400 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1377 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1401 "missing \"=\" in (or value after) \"%s\" "1378 "missing \"=\" in (or value after) \"%s\" in by clause", left );
1402 "in by clause\n",1379 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1403 fname, lineno, left );
1404 goto fail;1380 goto fail;
1405 }1381 }
14061382
1407 if ( !BER_BVISNULL( &b->a_sockname_pat ) ) {1383 if ( !BER_BVISNULL( &b->a_sockname_pat ) ) {
1408 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1384 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1409 "sockname pattern already specified.\n",1385 "sockname pattern already specified" );
1410 fname, lineno );1386 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1411 goto fail;1387 goto fail;
1412 }1388 }
14131389
@@ -1415,10 +1391,11 @@ parse_acl(
1415 if ( sty == ACL_STYLE_REGEX ) {1391 if ( sty == ACL_STYLE_REGEX ) {
1416 acl_regex_normalized_dn( right, &bv );1392 acl_regex_normalized_dn( right, &bv );
1417 if ( !ber_bvccmp( &bv, '*' ) ) {1393 if ( !ber_bvccmp( &bv, '*' ) ) {
1418 regtest( fname, lineno, bv.bv_val );1394 if ( regtest( c, bv.bv_val ) != 0)
1395 goto fail;
1419 }1396 }
1420 b->a_sockname_pat = bv;1397 b->a_sockname_pat = bv;
1421 1398
1422 } else {1399 } else {
1423 ber_str2bv( right, 0, 1, &b->a_sockname_pat );1400 ber_str2bv( right, 0, 1, &b->a_sockname_pat );
1424 }1401 }
@@ -1436,11 +1413,9 @@ parse_acl(
1436 case ACL_STYLE_EXPAND:1413 case ACL_STYLE_EXPAND:
1437 /* tolerated: means exact,expand */1414 /* tolerated: means exact,expand */
1438 if ( expand ) {1415 if ( expand ) {
1439 Debug( LDAP_DEBUG_ANY,1416 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1440 "%s: line %d: "1417 "\"expand\" modifier with \"expand\" style" );
1441 "\"expand\" modifier "1418 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1442 "with \"expand\" style.\n",
1443 fname, lineno );
1444 }1419 }
1445 sty = ACL_STYLE_BASE;1420 sty = ACL_STYLE_BASE;
1446 expand = 1;1421 expand = 1;
@@ -1448,24 +1423,23 @@ parse_acl(
14481423
1449 default:1424 default:
1450 /* unknown */1425 /* unknown */
1451 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1426 snprintf( c->cr_msg, sizeof( c->cr_msg),
1452 "inappropriate style \"%s\" in by clause.\n",1427 "inappropriate style \"%s\" in by clause", style );
1453 fname, lineno, style );1428 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1454 goto fail;1429 goto fail;
1455 }1430 }
14561431
1457 if ( right == NULL || right[0] == '\0' ) {1432 if ( right == NULL || right[0] == '\0' ) {
1458 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1433 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1459 "missing \"=\" in (or value after) \"%s\" "1434 "missing \"=\" in (or value after) \"%s\" in by clause", left );
1460 "in by clause.\n",1435 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1461 fname, lineno, left );
1462 goto fail;1436 goto fail;
1463 }1437 }
14641438
1465 if ( !BER_BVISEMPTY( &b->a_domain_pat ) ) {1439 if ( !BER_BVISEMPTY( &b->a_domain_pat ) ) {
1466 Debug( LDAP_DEBUG_ANY,1440 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1467 "%s: line %d: domain pattern already specified.\n",1441 "domain pattern already specified" );
1468 fname, lineno );1442 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1469 goto fail;1443 goto fail;
1470 }1444 }
14711445
@@ -1474,7 +1448,8 @@ parse_acl(
1474 if ( sty == ACL_STYLE_REGEX ) {1448 if ( sty == ACL_STYLE_REGEX ) {
1475 acl_regex_normalized_dn( right, &bv );1449 acl_regex_normalized_dn( right, &bv );
1476 if ( !ber_bvccmp( &bv, '*' ) ) {1450 if ( !ber_bvccmp( &bv, '*' ) ) {
1477 regtest( fname, lineno, bv.bv_val );1451 if ( regtest( c, bv.bv_val ) != 0)
1452 goto fail;
1478 }1453 }
1479 b->a_domain_pat = bv;1454 b->a_domain_pat = bv;
14801455
@@ -1495,24 +1470,23 @@ parse_acl(
14951470
1496 default:1471 default:
1497 /* unknown */1472 /* unknown */
1498 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1473 snprintf( c->cr_msg, sizeof( c->cr_msg),
1499 "inappropriate style \"%s\" in by clause.\n",1474 "inappropriate style \"%s\" in by clause", style );
1500 fname, lineno, style );1475 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1501 goto fail;1476 goto fail;
1502 }1477 }
15031478
1504 if ( right == NULL || right[0] == '\0' ) {1479 if ( right == NULL || right[0] == '\0' ) {
1505 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1480 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1506 "missing \"=\" in (or value after) \"%s\" "1481 "missing \"=\" in (or value after) \"%s\" in by clause", left );
1507 "in by clause.\n",1482 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1508 fname, lineno, left );
1509 goto fail;1483 goto fail;
1510 }1484 }
15111485
1512 if ( !BER_BVISEMPTY( &b->a_sockurl_pat ) ) {1486 if ( !BER_BVISEMPTY( &b->a_sockurl_pat ) ) {
1513 Debug( LDAP_DEBUG_ANY,1487 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1514 "%s: line %d: sockurl pattern already specified.\n",1488 "sockurl pattern already specified" );
1515 fname, lineno );1489 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1516 goto fail;1490 goto fail;
1517 }1491 }
15181492
@@ -1520,10 +1494,11 @@ parse_acl(
1520 if ( sty == ACL_STYLE_REGEX ) {1494 if ( sty == ACL_STYLE_REGEX ) {
1521 acl_regex_normalized_dn( right, &bv );1495 acl_regex_normalized_dn( right, &bv );
1522 if ( !ber_bvccmp( &bv, '*' ) ) {1496 if ( !ber_bvccmp( &bv, '*' ) ) {
1523 regtest( fname, lineno, bv.bv_val );1497 if ( regtest( c, bv.bv_val ) != 0)
1498 goto fail;
1524 }1499 }
1525 b->a_sockurl_pat = bv;1500 b->a_sockurl_pat = bv;
1526 1501
1527 } else {1502 } else {
1528 ber_str2bv( right, 0, 1, &b->a_sockurl_pat );1503 ber_str2bv( right, 0, 1, &b->a_sockurl_pat );
1529 }1504 }
@@ -1534,37 +1509,36 @@ parse_acl(
1534 switch ( sty ) {1509 switch ( sty ) {
1535 /* deprecated */1510 /* deprecated */
1536 case ACL_STYLE_REGEX:1511 case ACL_STYLE_REGEX:
1537 Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL,1512 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1538 "%s: line %d: "
1539 "deprecated set style "1513 "deprecated set style "
1540 "\"regex\" in <by> clause; "1514 "\"regex\" in <by> clause; "
1541 "use \"expand\" instead.\n",1515 "use \"expand\" instead" );
1542 fname, lineno );1516 Debug( LDAP_DEBUG_CONFIG | LDAP_DEBUG_ACL, "%s: %s.\n", c->log, c->cr_msg );
1543 sty = ACL_STYLE_EXPAND;1517 sty = ACL_STYLE_EXPAND;
1544 /* FALLTHRU */1518 /* FALLTHRU */
1545 1519
1546 case ACL_STYLE_BASE:1520 case ACL_STYLE_BASE:
1547 case ACL_STYLE_EXPAND:1521 case ACL_STYLE_EXPAND:
1548 break;1522 break;
15491523
1550 default:1524 default:
1551 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1525 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1552 "inappropriate style \"%s\" in by clause.\n",1526 "inappropriate style \"%s\" in by clause", style );
1553 fname, lineno, style );1527 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1554 goto fail;1528 goto fail;
1555 }1529 }
15561530
1557 if ( !BER_BVISEMPTY( &b->a_set_pat ) ) {1531 if ( !BER_BVISEMPTY( &b->a_set_pat ) ) {
1558 Debug( LDAP_DEBUG_ANY,1532 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1559 "%s: line %d: set attribute already specified.\n",1533 "set attribute already specified" );
1560 fname, lineno );1534 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1561 goto fail;1535 goto fail;
1562 }1536 }
15631537
1564 if ( right == NULL || *right == '\0' ) {1538 if ( right == NULL || *right == '\0' ) {
1565 Debug( LDAP_DEBUG_ANY,1539 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1566 "%s: line %d: no set is defined.\n",1540 "no set is defined" );
1567 fname, lineno );1541 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1568 goto fail;1542 goto fail;
1569 }1543 }
15701544
@@ -1581,12 +1555,12 @@ parse_acl(
15811555
1582#if 1 /* tolerate legacy "aci" <who> */1556#if 1 /* tolerate legacy "aci" <who> */
1583 if ( strcasecmp( left, "aci" ) == 0 ) {1557 if ( strcasecmp( left, "aci" ) == 0 ) {
1584 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1558 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1585 "undocumented deprecated \"aci\" directive "1559 "undocumented deprecated \"aci\" directive "
1586 "is superseded by \"dynacl/aci\".\n",1560 "is superseded by \"dynacl/aci\"" );
1587 fname, lineno );1561 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1588 name = "aci";1562 name = "aci";
1589 1563
1590 } else1564 } else
1591#endif /* tolerate legacy "aci" <who> */1565#endif /* tolerate legacy "aci" <who> */
1592 if ( strncasecmp( left, "dynacl/", STRLENOF( "dynacl/" ) ) == 0 ) {1566 if ( strncasecmp( left, "dynacl/", STRLENOF( "dynacl/" ) ) == 0 ) {
@@ -1599,10 +1573,10 @@ parse_acl(
1599 }1573 }
16001574
1601 if ( name ) {1575 if ( name ) {
1602 if ( slap_dynacl_config( fname, lineno, b, name, opts, sty, right ) ) {1576 if ( slap_dynacl_config( c, b, name, opts, sty, right ) ) {
1603 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1577 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1604 "unable to configure dynacl \"%s\".\n",1578 "unable to configure dynacl \"%s\"", name );
1605 fname, lineno, name );1579 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1606 goto fail;1580 goto fail;
1607 }1581 }
16081582
@@ -1613,37 +1587,37 @@ parse_acl(
16131587
1614 if ( strcasecmp( left, "ssf" ) == 0 ) {1588 if ( strcasecmp( left, "ssf" ) == 0 ) {
1615 if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {1589 if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {
1616 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1590 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1617 "inappropriate style \"%s\" in by clause.\n",1591 "inappropriate style \"%s\" in by clause", style );
1618 fname, lineno, style );1592 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1619 goto fail;1593 goto fail;
1620 }1594 }
16211595
1622 if ( b->a_authz.sai_ssf ) {1596 if ( b->a_authz.sai_ssf ) {
1623 Debug( LDAP_DEBUG_ANY,1597 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1624 "%s: line %d: ssf attribute already specified.\n",1598 "ssf attribute already specified" );
1625 fname, lineno );1599 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1626 goto fail;1600 goto fail;
1627 }1601 }
16281602
1629 if ( right == NULL || *right == '\0' ) {1603 if ( right == NULL || *right == '\0' ) {
1630 Debug( LDAP_DEBUG_ANY,1604 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1631 "%s: line %d: no ssf is defined.\n",1605 "no ssf is defined" );
1632 fname, lineno );1606 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1633 goto fail;1607 goto fail;
1634 }1608 }
16351609
1636 if ( lutil_atou( &b->a_authz.sai_ssf, right ) != 0 ) {1610 if ( lutil_atou( &b->a_authz.sai_ssf, right ) != 0 ) {
1637 Debug( LDAP_DEBUG_ANY,1611 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1638 "%s: line %d: unable to parse ssf value (%s).\n",1612 "unable to parse ssf value (%s)", right );
1639 fname, lineno, right );1613 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1640 goto fail;1614 goto fail;
1641 }1615 }
16421616
1643 if ( !b->a_authz.sai_ssf ) {1617 if ( !b->a_authz.sai_ssf ) {
1644 Debug( LDAP_DEBUG_ANY,1618 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1645 "%s: line %d: invalid ssf value (%s).\n",1619 "invalid ssf value (%s)", right );
1646 fname, lineno, right );1620 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1647 goto fail;1621 goto fail;
1648 }1622 }
1649 continue;1623 continue;
@@ -1651,37 +1625,37 @@ parse_acl(
16511625
1652 if ( strcasecmp( left, "transport_ssf" ) == 0 ) {1626 if ( strcasecmp( left, "transport_ssf" ) == 0 ) {
1653 if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {1627 if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {
1654 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1628 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1655 "inappropriate style \"%s\" in by clause.\n",1629 "inappropriate style \"%s\" in by clause", style );
1656 fname, lineno, style );1630 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1657 goto fail;1631 goto fail;
1658 }1632 }
16591633
1660 if ( b->a_authz.sai_transport_ssf ) {1634 if ( b->a_authz.sai_transport_ssf ) {
1661 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1635 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1662 "transport_ssf attribute already specified.\n",1636 "transport_ssf attribute already specified" );
1663 fname, lineno );1637 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1664 goto fail;1638 goto fail;
1665 }1639 }
16661640
1667 if ( right == NULL || *right == '\0' ) {1641 if ( right == NULL || *right == '\0' ) {
1668 Debug( LDAP_DEBUG_ANY,1642 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1669 "%s: line %d: no transport_ssf is defined.\n",1643 "no transport_ssf is defined" );
1670 fname, lineno );1644 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1671 goto fail;1645 goto fail;
1672 }1646 }
16731647
1674 if ( lutil_atou( &b->a_authz.sai_transport_ssf, right ) != 0 ) {1648 if ( lutil_atou( &b->a_authz.sai_transport_ssf, right ) != 0 ) {
1675 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1649 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1676 "unable to parse transport_ssf value (%s).\n",1650 "unable to parse transport_ssf value (%s)", right );
1677 fname, lineno, right );1651 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1678 goto fail;1652 goto fail;
1679 }1653 }
16801654
1681 if ( !b->a_authz.sai_transport_ssf ) {1655 if ( !b->a_authz.sai_transport_ssf ) {
1682 Debug( LDAP_DEBUG_ANY,1656 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1683 "%s: line %d: invalid transport_ssf value (%s).\n",1657 "invalid transport_ssf value (%s)", right );
1684 fname, lineno, right );1658 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1685 goto fail;1659 goto fail;
1686 }1660 }
1687 continue;1661 continue;
@@ -1689,37 +1663,36 @@ parse_acl(
16891663
1690 if ( strcasecmp( left, "tls_ssf" ) == 0 ) {1664 if ( strcasecmp( left, "tls_ssf" ) == 0 ) {
1691 if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {1665 if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {
1692 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1666 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1693 "inappropriate style \"%s\" in by clause.\n",1667 "inappropriate style \"%s\" in by clause", style );
1694 fname, lineno, style );1668 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1695 goto fail;1669 goto fail;
1696 }1670 }
16971671
1698 if ( b->a_authz.sai_tls_ssf ) {1672 if ( b->a_authz.sai_tls_ssf ) {
1699 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1673 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1700 "tls_ssf attribute already specified.\n",1674 "tls_ssf attribute already specified" );
1701 fname, lineno );
1702 goto fail;1675 goto fail;
1703 }1676 }
17041677
1705 if ( right == NULL || *right == '\0' ) {1678 if ( right == NULL || *right == '\0' ) {
1706 Debug( LDAP_DEBUG_ANY,1679 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1707 "%s: line %d: no tls_ssf is defined\n",1680 "no tls_ssf is defined" );
1708 fname, lineno );1681 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1709 goto fail;1682 goto fail;
1710 }1683 }
17111684
1712 if ( lutil_atou( &b->a_authz.sai_tls_ssf, right ) != 0 ) {1685 if ( lutil_atou( &b->a_authz.sai_tls_ssf, right ) != 0 ) {
1713 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1686 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1714 "unable to parse tls_ssf value (%s).\n",1687 "unable to parse tls_ssf value (%s)", right );
1715 fname, lineno, right );1688 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1716 goto fail;1689 goto fail;
1717 }1690 }
17181691
1719 if ( !b->a_authz.sai_tls_ssf ) {1692 if ( !b->a_authz.sai_tls_ssf ) {
1720 Debug( LDAP_DEBUG_ANY,1693 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1721 "%s: line %d: invalid tls_ssf value (%s).\n",1694 "invalid tls_ssf value (%s)", right );
1722 fname, lineno, right );1695 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1723 goto fail;1696 goto fail;
1724 }1697 }
1725 continue;1698 continue;
@@ -1727,37 +1700,37 @@ parse_acl(
17271700
1728 if ( strcasecmp( left, "sasl_ssf" ) == 0 ) {1701 if ( strcasecmp( left, "sasl_ssf" ) == 0 ) {
1729 if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {1702 if ( sty != ACL_STYLE_REGEX && sty != ACL_STYLE_BASE ) {
1730 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1703 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1731 "inappropriate style \"%s\" in by clause.\n",1704 "inappropriate style \"%s\" in by clause", style );
1732 fname, lineno, style );1705 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1733 goto fail;1706 goto fail;
1734 }1707 }
17351708
1736 if ( b->a_authz.sai_sasl_ssf ) {1709 if ( b->a_authz.sai_sasl_ssf ) {
1737 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1710 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1738 "sasl_ssf attribute already specified.\n",1711 "sasl_ssf attribute already specified" );
1739 fname, lineno );1712 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1740 goto fail;1713 goto fail;
1741 }1714 }
17421715
1743 if ( right == NULL || *right == '\0' ) {1716 if ( right == NULL || *right == '\0' ) {
1744 Debug( LDAP_DEBUG_ANY,1717 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1745 "%s: line %d: no sasl_ssf is defined.\n",1718 "no sasl_ssf is defined" );
1746 fname, lineno );1719 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1747 goto fail;1720 goto fail;
1748 }1721 }
17491722
1750 if ( lutil_atou( &b->a_authz.sai_sasl_ssf, right ) != 0 ) {1723 if ( lutil_atou( &b->a_authz.sai_sasl_ssf, right ) != 0 ) {
1751 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1724 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1752 "unable to parse sasl_ssf value (%s).\n",1725 "unable to parse sasl_ssf value (%s)", right );
1753 fname, lineno, right );1726 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1754 goto fail;1727 goto fail;
1755 }1728 }
17561729
1757 if ( !b->a_authz.sai_sasl_ssf ) {1730 if ( !b->a_authz.sai_sasl_ssf ) {
1758 Debug( LDAP_DEBUG_ANY,1731 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1759 "%s: line %d: invalid sasl_ssf value (%s).\n",1732 "invalid sasl_ssf value (%s)", right );
1760 fname, lineno, right );1733 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1761 goto fail;1734 goto fail;
1762 }1735 }
1763 continue;1736 continue;
@@ -1770,7 +1743,7 @@ parse_acl(
1770 break;1743 break;
1771 }1744 }
17721745
1773 if ( i == argc || ( strcasecmp( left, "stop" ) == 0 ) ) { 1746 if ( i == argc || ( strcasecmp( left, "stop" ) == 0 ) ) {
1774 /* out of arguments or plain stop */1747 /* out of arguments or plain stop */
17751748
1776 ACL_PRIV_ASSIGN( b->a_access_mask, ACL_PRIV_ADDITIVE );1749 ACL_PRIV_ASSIGN( b->a_access_mask, ACL_PRIV_ADDITIVE );
@@ -1831,9 +1804,9 @@ parse_acl(
1831 }1804 }
18321805
1833 if ( ACL_IS_INVALID( b->a_access_mask ) ) {1806 if ( ACL_IS_INVALID( b->a_access_mask ) ) {
1834 Debug( LDAP_DEBUG_ANY,1807 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1835 "%s: line %d: expecting <access> got \"%s\".\n",1808 "expecting <access> got \"%s\"", left );
1836 fname, lineno, left );1809 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1837 goto fail;1810 goto fail;
1838 }1811 }
18391812
@@ -1862,19 +1835,18 @@ parse_acl(
1862 b = NULL;1835 b = NULL;
18631836
1864 } else {1837 } else {
1865 Debug( LDAP_DEBUG_ANY,1838 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1866 "%s: line %d: expecting \"to\" "1839 "expecting \"to\" or \"by\" got \"%s\"", argv[i] );
1867 "or \"by\" got \"%s\"\n",1840 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1868 fname, lineno, argv[i] );
1869 goto fail;1841 goto fail;
1870 }1842 }
1871 }1843 }
18721844
1873 /* if we have no real access clause, complain and do nothing */1845 /* if we have no real access clause, complain and do nothing */
1874 if ( a == NULL ) {1846 if ( a == NULL ) {
1875 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1847 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1876 "warning: no access clause(s) specified in access line.\n",1848 "warning: no access clause(s) specified in access line");
1877 fname, lineno );1849 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1878 goto fail;1850 goto fail;
18791851
1880 } else {1852 } else {
@@ -1883,53 +1855,49 @@ parse_acl(
1883 print_acl( be, a );1855 print_acl( be, a );
1884 }1856 }
1885#endif1857#endif
1886 1858
1887 if ( a->acl_access == NULL ) {1859 if ( a->acl_access == NULL ) {
1888 Debug( LDAP_DEBUG_ANY, "%s: line %d: "1860 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1889 "warning: no by clause(s) specified in access line.\n",1861 "warning: no by clause(s) specified in access line" );
1890 fname, lineno );1862 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
1891 goto fail;1863 goto fail;
1892 }1864 }
18931865
1894 if ( be != NULL ) {1866 if ( be != NULL ) {
1895 if ( be->be_nsuffix == NULL ) {1867 if ( be->be_nsuffix == NULL ) {
1896 Debug( LDAP_DEBUG_ACL, "%s: line %d: warning: "1868 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1897 "scope checking needs suffix before ACLs.\n",1869 "warning: scope checking needs suffix before ACLs" );
1898 fname, lineno );1870 Debug( LDAP_DEBUG_ACL, "%s: %s.\n", c->log, c->cr_msg );
1899 /* go ahead, since checking is not authoritative */1871 /* go ahead, since checking is not authoritative */
1900 } else if ( !BER_BVISNULL( &be->be_nsuffix[ 1 ] ) ) {1872 } else if ( !BER_BVISNULL( &be->be_nsuffix[ 1 ] ) ) {
1901 Debug( LDAP_DEBUG_ACL, "%s: line %d: warning: "1873 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1902 "scope checking only applies to single-valued "1874 "warning: scope checking only applies to single-valued suffix databases" );
1903 "suffix databases\n",1875 Debug( LDAP_DEBUG_ACL, "%s: %s.\n", c->log, c->cr_msg );
1904 fname, lineno );
1905 /* go ahead, since checking is not authoritative */1876 /* go ahead, since checking is not authoritative */
1906 } else {1877 } else {
1907 switch ( check_scope( be, a ) ) {1878 switch ( check_scope( be, a ) ) {
1908 case ACL_SCOPE_UNKNOWN:1879 case ACL_SCOPE_UNKNOWN:
1909 Debug( LDAP_DEBUG_ACL, "%s: line %d: warning: "1880 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1910 "cannot assess the validity of the ACL scope within "1881 "warning: cannot assess the validity of the ACL scope within backend naming context" );
1911 "backend naming context\n",1882 Debug( LDAP_DEBUG_ACL, "%s: %s.\n", c->log, c->cr_msg );
1912 fname, lineno );
1913 break;1883 break;
19141884
1915 case ACL_SCOPE_WARN:1885 case ACL_SCOPE_WARN:
1916 Debug( LDAP_DEBUG_ACL, "%s: line %d: warning: "1886 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1917 "ACL could be out of scope within backend naming context\n",1887 "warning: ACL could be out of scope within backend naming context" );
1918 fname, lineno );1888 Debug( LDAP_DEBUG_ACL, "%s: %s.\n", c->log, c->cr_msg );
1919 break;1889 break;
19201890
1921 case ACL_SCOPE_PARTIAL:1891 case ACL_SCOPE_PARTIAL:
1922 Debug( LDAP_DEBUG_ACL, "%s: line %d: warning: "1892 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1923 "ACL appears to be partially out of scope within "1893 "warning: ACL appears to be partially out of scope within backend naming context" );
1924 "backend naming context\n",1894 Debug( LDAP_DEBUG_ACL, "%s: %s.\n", c->log, c->cr_msg );
1925 fname, lineno );
1926 break;1895 break;
1927 1896
1928 case ACL_SCOPE_ERR:1897 case ACL_SCOPE_ERR:
1929 Debug( LDAP_DEBUG_ACL, "%s: line %d: warning: "1898 snprintf( c->cr_msg, sizeof( c->cr_msg ),
1930 "ACL appears to be out of scope within "1899 "warning: ACL appears to be out of scope within backend naming context" );
1931 "backend naming context\n",1900 Debug( LDAP_DEBUG_ACL, "%s: %s.\n", c->log, c->cr_msg );
1932 fname, lineno );
1933 break;1901 break;
19341902
1935 default:1903 default:
@@ -1999,7 +1967,7 @@ accessmask2str( slap_mask_t mask, char *buf, int debug )
1999 } else {1967 } else {
2000 ptr = lutil_strcopy( ptr, "unknown" );1968 ptr = lutil_strcopy( ptr, "unknown" );
2001 }1969 }
2002 1970
2003 if ( !debug ) {1971 if ( !debug ) {
2004 *ptr = '\0';1972 *ptr = '\0';
2005 return buf;1973 return buf;
@@ -2020,7 +1988,7 @@ accessmask2str( slap_mask_t mask, char *buf, int debug )
2020 if ( ACL_PRIV_ISSET(mask, ACL_PRIV_MANAGE) ) {1988 if ( ACL_PRIV_ISSET(mask, ACL_PRIV_MANAGE) ) {
2021 none = 0;1989 none = 0;
2022 *ptr++ = 'm';1990 *ptr++ = 'm';
2023 } 1991 }
20241992
2025 if ( ACL_PRIV_ISSET(mask, ACL_PRIV_WRITE) ) {1993 if ( ACL_PRIV_ISSET(mask, ACL_PRIV_WRITE) ) {
2026 none = 0;1994 none = 0;
@@ -2033,37 +2001,37 @@ accessmask2str( slap_mask_t mask, char *buf, int debug )
2033 } else if ( ACL_PRIV_ISSET(mask, ACL_PRIV_WDEL) ) {2001 } else if ( ACL_PRIV_ISSET(mask, ACL_PRIV_WDEL) ) {
2034 none = 0;2002 none = 0;
2035 *ptr++ = 'z';2003 *ptr++ = 'z';
2036 } 2004 }
20372005
2038 if ( ACL_PRIV_ISSET(mask, ACL_PRIV_READ) ) {2006 if ( ACL_PRIV_ISSET(mask, ACL_PRIV_READ) ) {
2039 none = 0;2007 none = 0;
2040 *ptr++ = 'r';2008 *ptr++ = 'r';
2041 } 2009 }
20422010
2043 if ( ACL_PRIV_ISSET(mask, ACL_PRIV_SEARCH) ) {2011 if ( ACL_PRIV_ISSET(mask, ACL_PRIV_SEARCH) ) {
2044 none = 0;2012 none = 0;
2045 *ptr++ = 's';2013 *ptr++ = 's';
2046 } 2014 }
20472015
2048 if ( ACL_PRIV_ISSET(mask, ACL_PRIV_COMPARE) ) {2016 if ( ACL_PRIV_ISSET(mask, ACL_PRIV_COMPARE) ) {
2049 none = 0;2017 none = 0;
2050 *ptr++ = 'c';2018 *ptr++ = 'c';
2051 } 2019 }
20522020
2053 if ( ACL_PRIV_ISSET(mask, ACL_PRIV_AUTH) ) {2021 if ( ACL_PRIV_ISSET(mask, ACL_PRIV_AUTH) ) {
2054 none = 0;2022 none = 0;
2055 *ptr++ = 'x';2023 *ptr++ = 'x';
2056 } 2024 }
20572025
2058 if ( ACL_PRIV_ISSET(mask, ACL_PRIV_DISCLOSE) ) {2026 if ( ACL_PRIV_ISSET(mask, ACL_PRIV_DISCLOSE) ) {
2059 none = 0;2027 none = 0;
2060 *ptr++ = 'd';2028 *ptr++ = 'd';
2061 } 2029 }
20622030
2063 if ( none && ACL_PRIV_ISSET(mask, ACL_PRIV_NONE) ) {2031 if ( none && ACL_PRIV_ISSET(mask, ACL_PRIV_NONE) ) {
2064 none = 0;2032 none = 0;
2065 *ptr++ = '0';2033 *ptr++ = '0';
2066 } 2034 }
20672035
2068 if ( none ) {2036 if ( none ) {
2069 ptr = buf;2037 ptr = buf;
@@ -2178,7 +2146,7 @@ str2accessmask( const char *str )
2178}2146}
21792147
2180static int2148static int
2181acl_usage( void )2149acl_usage(void)
2182{2150{
2183 char *access =2151 char *access =
2184 "<access clause> ::= access to <what> "2152 "<access clause> ::= access to <what> "
@@ -2227,7 +2195,7 @@ acl_usage( void )
22272195
2228/*2196/*
2229 * Set pattern to a "normalized" DN from src.2197 * Set pattern to a "normalized" DN from src.
2230 * At present it simply eats the (optional) space after 2198 * At present, it simply eats the (optional) space after
2231 * a RDN separator (,)2199 * a RDN separator (,)
2232 * Eventually will evolve in a more complete normalization2200 * Eventually will evolve in a more complete normalization
2233 */2201 */
@@ -2245,10 +2213,10 @@ acl_regex_normalized_dn(
2245 for ( p = str; p && p[0]; p++ ) {2213 for ( p = str; p && p[0]; p++ ) {
2246 /* escape */2214 /* escape */
2247 if ( p[0] == '\\' && p[1] ) {2215 if ( p[0] == '\\' && p[1] ) {
2248 /* 2216 /*
2249 * if escaping a hex pair we should2217 * if escaping a hex pair we should
2250 * increment p twice; however, in that 2218 * increment p twice; however, in that
2251 * case the second hex number does 2219 * case the second hex number does
2252 * no harm2220 * no harm
2253 */2221 */
2254 p++;2222 p++;
@@ -2256,7 +2224,7 @@ acl_regex_normalized_dn(
22562224
2257 if ( p[0] == ',' && p[1] == ' ' ) {2225 if ( p[0] == ',' && p[1] == ' ' ) {
2258 char *q;2226 char *q;
2259 2227
2260 /*2228 /*
2261 * too much space should be an error if we are pedantic2229 * too much space should be an error if we are pedantic
2262 */2230 */
@@ -2532,7 +2500,7 @@ dnaccess2text( slap_dn_access *bdn, char *ptr, int is_realdn )
2532 if ( is_realdn ) {2500 if ( is_realdn ) {
2533 assert( ! ber_bvccmp( &bdn->a_pat, '*' ) );2501 assert( ! ber_bvccmp( &bdn->a_pat, '*' ) );
2534 }2502 }
2535 2503
2536 ptr = acl_safe_strbvcopy( ptr, &bdn->a_pat );2504 ptr = acl_safe_strbvcopy( ptr, &bdn->a_pat );
2537 if ( bdn->a_style == ACL_STYLE_SELF && bdn->a_self_level != 0 ) {2505 if ( bdn->a_style == ACL_STYLE_SELF && bdn->a_self_level != 0 ) {
2538 char buf[SLAP_TEXT_BUFLEN];2506 char buf[SLAP_TEXT_BUFLEN];
@@ -2546,7 +2514,7 @@ dnaccess2text( slap_dn_access *bdn, char *ptr, int is_realdn )
2546 ptr = acl_safe_strcopy( ptr, "dn." );2514 ptr = acl_safe_strcopy( ptr, "dn." );
2547 if ( bdn->a_style == ACL_STYLE_BASE )2515 if ( bdn->a_style == ACL_STYLE_BASE )
2548 ptr = acl_safe_strcopy( ptr, style_base );2516 ptr = acl_safe_strcopy( ptr, style_base );
2549 else 2517 else
2550 ptr = acl_safe_strcopy( ptr, style_strings[bdn->a_style] );2518 ptr = acl_safe_strcopy( ptr, style_strings[bdn->a_style] );
2551 if ( bdn->a_style == ACL_STYLE_LEVEL ) {2519 if ( bdn->a_style == ACL_STYLE_LEVEL ) {
2552 char buf[SLAP_TEXT_BUFLEN];2520 char buf[SLAP_TEXT_BUFLEN];
@@ -2668,7 +2636,7 @@ access2text( Access *b, char *ptr )
2668 /* Security Strength Factors */2636 /* Security Strength Factors */
2669 if ( b->a_authz.sai_ssf ) {2637 if ( b->a_authz.sai_ssf ) {
2670 char buf[SLAP_TEXT_BUFLEN];2638 char buf[SLAP_TEXT_BUFLEN];
2671 int n = snprintf( buf, sizeof(buf), " ssf=%u", 2639 int n = snprintf( buf, sizeof(buf), " ssf=%u",
2672 b->a_authz.sai_ssf );2640 b->a_authz.sai_ssf );
2673 ptr = acl_safe_strncopy( ptr, buf, n );2641 ptr = acl_safe_strncopy( ptr, buf, n );
2674 }2642 }
diff --git a/servers/slapd/back-asyncmeta/map.c b/servers/slapd/back-asyncmeta/map.c
index b811708..66bb8b0 100644
--- a/servers/slapd/back-asyncmeta/map.c
+++ b/servers/slapd/back-asyncmeta/map.c
@@ -197,16 +197,26 @@ ignore:
197 }197 }
198198
199 /* DN longer than our suffix and doesn't match */199 /* DN longer than our suffix and doesn't match */
200 if ( diff > 0 && !DN_SEPARATOR(dn->bv_val[diff-1]))200 if ( osuff->bv_len != 0 && diff > 0 && !DN_SEPARATOR(dn->bv_val[diff-1]) )
201 goto ignore;201 goto ignore;
202202
203 /* suffix is same length as ours, but doesn't match */203 /* suffix is same length as ours, but doesn't match */
204 if ( strcasecmp( osuff->bv_val, &dn->bv_val[diff] ))204 if ( strcasecmp( osuff->bv_val, &dn->bv_val[diff] ))
205 goto ignore;205 goto ignore;
206206
207 /* if remote suffix is empty, remove or add the dn separator*/
208 if ( nsuff->bv_len == 0 ) {
209 diff--;
210 } else if ( osuff->bv_len == 0 ) {
211 diff++;
212 }
213
214
207 res->bv_len = diff + nsuff->bv_len;215 res->bv_len = diff + nsuff->bv_len;
208 res->bv_val = dc->op->o_tmpalloc( res->bv_len + 1, dc->memctx );216 res->bv_val = dc->op->o_tmpalloc( res->bv_len + 1, dc->memctx );
209 strncpy( res->bv_val, dn->bv_val, diff );217 strncpy( res->bv_val, dn->bv_val, diff );
218 if ( osuff->bv_len == 0 )
219 res->bv_val[diff-1] = ',';
210 strcpy( &res->bv_val[diff], nsuff->bv_val );220 strcpy( &res->bv_val[diff], nsuff->bv_val );
211221
212 if (pretty.bv_val)222 if (pretty.bv_val)
diff --git a/servers/slapd/back-ldap/chain.c b/servers/slapd/back-ldap/chain.c
index d6ffd1a..fece74d 100644
--- a/servers/slapd/back-ldap/chain.c
+++ b/servers/slapd/back-ldap/chain.c
@@ -1040,7 +1040,7 @@ ldap_chain_response( Operation *op, SlapReply *rs )
10401040
1041 /* we need this to know if back-ldap returned any result */1041 /* we need this to know if back-ldap returned any result */
1042 lb.lb_lc = lc;1042 lb.lb_lc = lc;
1043 sc2.sc_next = sc->sc_next;1043 sc2.sc_next = sc;
1044 sc2.sc_private = &lb;1044 sc2.sc_private = &lb;
1045 sc2.sc_response = ldap_chain_cb_response;1045 sc2.sc_response = ldap_chain_cb_response;
1046 op->o_callback = &sc2;1046 op->o_callback = &sc2;
diff --git a/servers/slapd/back-null/null.c b/servers/slapd/back-null/null.c
index 50b6fbc..c8d3292 100644
--- a/servers/slapd/back-null/null.c
+++ b/servers/slapd/back-null/null.c
@@ -72,8 +72,8 @@ null_back_db_open( BackendDB *be, ConfigReply *cr )
7272
73 if ( ni->ni_dosearch ) {73 if ( ni->ni_dosearch ) {
74 e = entry_alloc();74 e = entry_alloc();
75 e->e_name = be->be_suffix[0];75 ber_dupbv( &e->e_name, &be->be_suffix[0] );
76 e->e_nname = be->be_nsuffix[0];76 ber_dupbv( &e->e_nname, &be->be_nsuffix[0] );
7777
78 dnRdn( &e->e_nname, &bv[0] );78 dnRdn( &e->e_nname, &bv[0] );
79 bv[1].bv_val = strchr(bv[0].bv_val, '=') + 1;79 bv[1].bv_val = strchr(bv[0].bv_val, '=') + 1;
diff --git a/servers/slapd/bconfig.c b/servers/slapd/bconfig.c
index 4c4b925..59236c4 100644
--- a/servers/slapd/bconfig.c
+++ b/servers/slapd/bconfig.c
@@ -2247,7 +2247,7 @@ sortval_reject:
2247 for ( a=c->be->be_acl; a; a = a->acl_next )2247 for ( a=c->be->be_acl; a; a = a->acl_next )
2248 i++;2248 i++;
2249 }2249 }
2250 if ( parse_acl(c->be, c->fname, c->lineno, c->argc, c->argv, i ) ) {2250 if ( parse_acl( c, i ) ) {
2251 if ( SLAP_CONFIG( c->be ) && !c->be->be_acl) {2251 if ( SLAP_CONFIG( c->be ) && !c->be->be_acl) {
2252 c->be->be_acl = defacl_parsed;2252 c->be->be_acl = defacl_parsed;
2253 }2253 }
@@ -2533,7 +2533,7 @@ sortval_reject:
25332533
2534#ifdef LDAP_SLAPI2534#ifdef LDAP_SLAPI
2535 case CFG_PLUGIN:2535 case CFG_PLUGIN:
2536 if(slapi_int_read_config(c->be, c->fname, c->lineno, c->argc, c->argv, c->valx) != LDAP_SUCCESS)2536 if(slapi_int_read_config(c) != LDAP_SUCCESS)
2537 return(1);2537 return(1);
2538 slapi_plugins_used++;2538 slapi_plugins_used++;
2539 break;2539 break;
@@ -4360,7 +4360,8 @@ config_tls_config(ConfigArgs *c) {
4360#endif4360#endif
43614361
4362static CfEntryInfo *4362static CfEntryInfo *
4363config_find_base( CfEntryInfo *root, struct berval *dn, CfEntryInfo **last )4363config_find_base( CfEntryInfo *root, struct berval *dn, CfEntryInfo **last,
4364 Operation *op )
4364{4365{
4365 struct berval cdn;4366 struct berval cdn;
4366 char *c;4367 char *c;
@@ -4377,7 +4378,14 @@ config_find_base( CfEntryInfo *root, struct berval *dn, CfEntryInfo **last )
4377 for (;*c != ',';c--);4378 for (;*c != ',';c--);
43784379
4379 while(root) {4380 while(root) {
4380 *last = root;4381 if ( !op || access_allowed( op, root->ce_entry,
4382 slap_schema.si_ad_entry, NULL, ACL_DISCLOSE, NULL ) ) {
4383 /*
4384 * ITS#10139: Only record the lowermost entry that the user has
4385 * disclose access to
4386 */
4387 *last = root;
4388 }
4381 for (--c;c>dn->bv_val && *c != ',';c--);4389 for (--c;c>dn->bv_val && *c != ',';c--);
4382 cdn.bv_val = c;4390 cdn.bv_val = c;
4383 if ( *c == ',' )4391 if ( *c == ',' )
@@ -5495,7 +5503,7 @@ config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, SlapReply *rs,
5495 * Databases and Overlays to be inserted. Don't do any5503 * Databases and Overlays to be inserted. Don't do any
5496 * auto-renumbering if manageDSAit control is present.5504 * auto-renumbering if manageDSAit control is present.
5497 */5505 */
5498 ce = config_find_base( cfb->cb_root, &e->e_nname, &last );5506 ce = config_find_base( cfb->cb_root, &e->e_nname, &last, op );
5499 if ( ce ) {5507 if ( ce ) {
5500 if ( ( op && op->o_managedsait ) ||5508 if ( ( op && op->o_managedsait ) ||
5501 ( ce->ce_type != Cft_Database && ce->ce_type != Cft_Overlay &&5509 ( ce->ce_type != Cft_Database && ce->ce_type != Cft_Overlay &&
@@ -5516,14 +5524,14 @@ config_add_internal( CfBackInfo *cfb, Entry *e, ConfigArgs *ca, SlapReply *rs,
5516 /* If last is NULL, the new entry is the root/suffix entry, 5524 /* If last is NULL, the new entry is the root/suffix entry,
5517 * otherwise last should be the parent.5525 * otherwise last should be the parent.
5518 */5526 */
5519 if ( last && !dn_match( &last->ce_entry->e_nname, &pdn ) ) {5527 if ( cfb->cb_root && ( !last || !dn_match( &last->ce_entry->e_nname, &pdn ) ) ) {
5520 if ( rs ) {5528 if ( last && rs ) {
5521 rs->sr_matched = last->ce_entry->e_name.bv_val;5529 rs->sr_matched = last->ce_entry->e_name.bv_val;
5522 }5530 }
5523 Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "5531 Debug( LDAP_DEBUG_TRACE, "%s: config_add_internal: "
5524 "DN=\"%s\" not child of DN=\"%s\"\n",5532 "DN=\"%s\" not child of DN=\"%s\"\n",
5525 log_prefix, e->e_name.bv_val,5533 log_prefix, e->e_name.bv_val,
5526 last->ce_entry->e_name.bv_val );5534 last ? last->ce_entry->e_name.bv_val : "" );
5527 return LDAP_NO_SUCH_OBJECT;5535 return LDAP_NO_SUCH_OBJECT;
5528 }5536 }
55295537
@@ -6461,7 +6469,7 @@ config_back_modify( Operation *op, SlapReply *rs )
64616469
6462 cfb = (CfBackInfo *)op->o_bd->be_private;6470 cfb = (CfBackInfo *)op->o_bd->be_private;
64636471
6464 ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last );6472 ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last, op );
6465 if ( !ce ) {6473 if ( !ce ) {
6466 if ( last )6474 if ( last )
6467 rs->sr_matched = last->ce_entry->e_name.bv_val;6475 rs->sr_matched = last->ce_entry->e_name.bv_val;
@@ -6569,7 +6577,7 @@ config_back_modrdn( Operation *op, SlapReply *rs )
65696577
6570 cfb = (CfBackInfo *)op->o_bd->be_private;6578 cfb = (CfBackInfo *)op->o_bd->be_private;
65716579
6572 ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last );6580 ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last, op );
6573 if ( !ce ) {6581 if ( !ce ) {
6574 if ( last )6582 if ( last )
6575 rs->sr_matched = last->ce_entry->e_name.bv_val;6583 rs->sr_matched = last->ce_entry->e_name.bv_val;
@@ -6785,7 +6793,7 @@ config_back_delete( Operation *op, SlapReply *rs )
67856793
6786 cfb = (CfBackInfo *)op->o_bd->be_private;6794 cfb = (CfBackInfo *)op->o_bd->be_private;
67876795
6788 ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last );6796 ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last, op );
6789 if ( !ce ) {6797 if ( !ce ) {
6790 if ( last )6798 if ( last )
6791 rs->sr_matched = last->ce_entry->e_name.bv_val;6799 rs->sr_matched = last->ce_entry->e_name.bv_val;
@@ -6938,7 +6946,7 @@ config_back_search( Operation *op, SlapReply *rs )
6938 cfb = (CfBackInfo *)op->o_bd->be_private;6946 cfb = (CfBackInfo *)op->o_bd->be_private;
69396947
6940 ldap_pvt_thread_rdwr_rlock( &cfb->cb_rwlock );6948 ldap_pvt_thread_rdwr_rlock( &cfb->cb_rwlock );
6941 ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last );6949 ce = config_find_base( cfb->cb_root, &op->o_req_ndn, &last, op );
6942 if ( !ce ) {6950 if ( !ce ) {
6943 if ( last )6951 if ( last )
6944 rs->sr_matched = last->ce_entry->e_name.bv_val;6952 rs->sr_matched = last->ce_entry->e_name.bv_val;
@@ -7026,7 +7034,7 @@ int config_back_entry_get(
7026 if ( !paused ) {7034 if ( !paused ) {
7027 ldap_pvt_thread_rdwr_rlock( &cfb->cb_rwlock );7035 ldap_pvt_thread_rdwr_rlock( &cfb->cb_rwlock );
7028 }7036 }
7029 ce = config_find_base( cfb->cb_root, ndn, &last );7037 ce = config_find_base( cfb->cb_root, ndn, &last, op );
7030 if ( ce ) {7038 if ( ce ) {
7031 e = ce->ce_entry;7039 e = ce->ce_entry;
7032 if ( e ) {7040 if ( e ) {
@@ -7332,7 +7340,7 @@ config_check_schema(Operation *op, CfBackInfo *cfb)
7332 return 0;7340 return 0;
73337341
7334 /* Make sure the main schema entry exists */7342 /* Make sure the main schema entry exists */
7335 ce = config_find_base( cfb->cb_root, &schema_dn, &last );7343 ce = config_find_base( cfb->cb_root, &schema_dn, &last, op );
7336 if ( ce ) {7344 if ( ce ) {
7337 Attribute *a;7345 Attribute *a;
7338 struct berval *bv;7346 struct berval *bv;
@@ -7447,7 +7455,12 @@ config_back_db_open( BackendDB *be, ConfigReply *cr )
7447 */7455 */
7448 save_access = be->bd_self->be_acl;7456 save_access = be->bd_self->be_acl;
7449 be->bd_self->be_acl = NULL;7457 be->bd_self->be_acl = NULL;
7450 parse_acl(be->bd_self, "config_back_db_open", 0, 6, (char **)defacl, 0 );7458 c.be = be->bd_self;
7459 c.fname = "config_back_db_open";
7460 c.lineno = 0;
7461 c.argc = 6;
7462 c.argv = (char **)defacl;
7463 parse_acl( &c, 0 );
7451 defacl_parsed = be->bd_self->be_acl;7464 defacl_parsed = be->bd_self->be_acl;
7452 if ( save_access ) {7465 if ( save_access ) {
7453 be->bd_self->be_acl = save_access;7466 be->bd_self->be_acl = save_access;
@@ -8029,7 +8042,7 @@ config_tool_entry_modify( BackendDB *be, Entry *e, struct berval *text )
8029 BackendInfo *bi = cfb->cb_db.bd_info;8042 BackendInfo *bi = cfb->cb_db.bd_info;
8030 CfEntryInfo *ce, *last;8043 CfEntryInfo *ce, *last;
80318044
8032 ce = config_find_base( cfb->cb_root, &e->e_nname, &last );8045 ce = config_find_base( cfb->cb_root, &e->e_nname, &last, NULL );
80338046
8034 if ( ce && bi && bi->bi_tool_entry_modify )8047 if ( ce && bi && bi->bi_tool_entry_modify )
8035 return bi->bi_tool_entry_modify( &cfb->cb_db, e, text );8048 return bi->bi_tool_entry_modify( &cfb->cb_db, e, text );
@@ -8044,7 +8057,7 @@ config_tool_entry_delete( BackendDB *be, struct berval *ndn, struct berval *text
8044 BackendInfo *bi = cfb->cb_db.bd_info;8057 BackendInfo *bi = cfb->cb_db.bd_info;
8045 CfEntryInfo *ce, *last;8058 CfEntryInfo *ce, *last;
80468059
8047 ce = config_find_base( cfb->cb_root, ndn, &last );8060 ce = config_find_base( cfb->cb_root, ndn, &last, NULL );
80488061
8049 if ( ce && bi && bi->bi_tool_entry_delete )8062 if ( ce && bi && bi->bi_tool_entry_delete )
8050 return bi->bi_tool_entry_delete( &cfb->cb_db, ndn, text );8063 return bi->bi_tool_entry_delete( &cfb->cb_db, ndn, text );
diff --git a/servers/slapd/controls.c b/servers/slapd/controls.c
index 940ca3d..beabe44 100644
--- a/servers/slapd/controls.c
+++ b/servers/slapd/controls.c
@@ -17,6 +17,7 @@
1717
18#include <stdio.h>18#include <stdio.h>
1919
20#include <ac/ctype.h>
20#include <ac/string.h>21#include <ac/string.h>
21#include <ac/socket.h>22#include <ac/socket.h>
2223
diff --git a/servers/slapd/overlays/dynlist.c b/servers/slapd/overlays/dynlist.c
index 10cacf9..5c38b64 100644
--- a/servers/slapd/overlays/dynlist.c
+++ b/servers/slapd/overlays/dynlist.c
@@ -65,6 +65,7 @@ typedef struct dynlist_info_t {
65typedef struct dynlist_gen_t {65typedef struct dynlist_gen_t {
66 dynlist_info_t *dlg_dli;66 dynlist_info_t *dlg_dli;
67 int dlg_memberOf;67 int dlg_memberOf;
68 int dlg_simple;
68} dynlist_gen_t;69} dynlist_gen_t;
6970
70#define DYNLIST_USAGE \71#define DYNLIST_USAGE \
@@ -556,9 +557,8 @@ dynlist_nested_member_dg( Operation *op, SlapReply *rs )
556}557}
557558
558static void559static void
559dynlist_nested_member( Operation *op, dynlist_member_t *dm, TAvlnode *subs )560dynlist_nested_member( Operation *op, slap_overinst *on, dynlist_member_t *dm, TAvlnode *subs )
560{561{
561 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
562 TAvlnode *ptr;562 TAvlnode *ptr;
563 dynlist_name_t *dyn;563 dynlist_name_t *dyn;
564 Entry *ne;564 Entry *ne;
@@ -596,12 +596,12 @@ dynlist_nested_member( Operation *op, dynlist_member_t *dm, TAvlnode *subs )
596 dynlist_urlmembers( op, dyn, &cb );596 dynlist_urlmembers( op, dyn, &cb );
597 }597 }
598 if ( dyn->dy_subs )598 if ( dyn->dy_subs )
599 dynlist_nested_member( op, dm, dyn->dy_subs );599 dynlist_nested_member( op, on, dm, dyn->dy_subs );
600 }600 }
601}601}
602602
603static int603static int
604dynlist_prepare_entry( Operation *op, SlapReply *rs, dynlist_info_t *dli, dynlist_name_t *dyn )604dynlist_prepare_entry( Operation *op, SlapReply *rs, slap_overinst *on, dynlist_info_t *dli, dynlist_name_t *dyn )
605{605{
606 Attribute *a, *id = NULL;606 Attribute *a, *id = NULL;
607 slap_callback cb = { 0 };607 slap_callback cb = { 0 };
@@ -875,7 +875,7 @@ checkdyn:
875 /* ensure e is modifiable */875 /* ensure e is modifiable */
876 if ( e == rs->sr_entry && !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) {876 if ( e == rs->sr_entry && !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) ) {
877 e = entry_dup( rs->sr_entry );877 e = entry_dup( rs->sr_entry );
878 rs_replace_entry( op, rs, (slap_overinst *)op->o_bd->bd_info, e );878 rs_replace_entry( op, rs, on, e );
879 rs->sr_flags |= REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED;879 rs->sr_flags |= REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED;
880 }880 }
881 if ( dyn->dy_subs ) {881 if ( dyn->dy_subs ) {
@@ -888,7 +888,7 @@ checkdyn:
888 dm.dm_mod.sm_type = dlm->dlm_member_ad->ad_cname;888 dm.dm_mod.sm_type = dlm->dlm_member_ad->ad_cname;
889 dm.dm_e = e;889 dm.dm_e = e;
890 dm.dm_ad = dlm->dlm_member_ad;890 dm.dm_ad = dlm->dlm_member_ad;
891 dynlist_nested_member( op, &dm, dyn->dy_subs );891 dynlist_nested_member( op, on, &dm, dyn->dy_subs );
892 if ( dm.dm_groups )892 if ( dm.dm_groups )
893 ldap_tavl_free( dm.dm_groups, NULL );893 ldap_tavl_free( dm.dm_groups, NULL );
894 }894 }
@@ -904,7 +904,7 @@ checkdyn:
904 }904 }
905905
906 if ( e != rs->sr_entry ) {906 if ( e != rs->sr_entry ) {
907 rs_replace_entry( op, rs, (slap_overinst *)op->o_bd->bd_info, e );907 rs_replace_entry( op, rs, on, e );
908 rs->sr_flags |= REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED;908 rs->sr_flags |= REP_ENTRY_MODIFIABLE | REP_ENTRY_MUSTBEFREED;
909 }909 }
910910
@@ -1098,7 +1098,7 @@ done:;
1098 r.sr_attrs = an;1098 r.sr_attrs = an;
10991099
1100 o.o_acl_priv = ACL_COMPARE;1100 o.o_acl_priv = ACL_COMPARE;
1101 dynlist_prepare_entry( &o, &r, dli, NULL );1101 dynlist_prepare_entry( &o, &r, on, dli, NULL );
1102 a = attrs_find( r.sr_entry->e_attrs, op->orc_ava->aa_desc );1102 a = attrs_find( r.sr_entry->e_attrs, op->orc_ava->aa_desc );
11031103
1104 ret = LDAP_NO_SUCH_ATTRIBUTE;1104 ret = LDAP_NO_SUCH_ATTRIBUTE;
@@ -1131,6 +1131,7 @@ release:;
1131#define WANT_MEMBER 21131#define WANT_MEMBER 2
11321132
1133typedef struct dynlist_search_t {1133typedef struct dynlist_search_t {
1134 slap_overinst *ds_on;
1134 TAvlnode *ds_names;1135 TAvlnode *ds_names;
1135 TAvlnode *ds_fnodes;1136 TAvlnode *ds_fnodes;
1136 dynlist_info_t *ds_dli;1137 dynlist_info_t *ds_dli;
@@ -1555,11 +1556,11 @@ dynlist_test_dynmember(Operation *op, dynlist_name_t *dyn, Entry *e)
1555}1556}
15561557
1557static int1558static int
1558dynlist_test_membership(Operation *op, dynlist_name_t *dyn, Entry *e)1559dynlist_test_membership(Operation *op, slap_overinst *on, dynlist_name_t *dyn, Entry *e)
1559{1560{
1560 if ( dyn->dy_staticmember ) {1561 if ( dyn->dy_staticmember ) {
1561 Entry *grp;1562 Entry *grp;
1562 if ( overlay_entry_get_ov( op, &dyn->dy_nname, NULL, NULL, 0, &grp, (slap_overinst *)op->o_bd->bd_info ) == LDAP_SUCCESS && grp ) {1563 if ( overlay_entry_get_ov( op, &dyn->dy_nname, NULL, NULL, 0, &grp, on ) == LDAP_SUCCESS && grp ) {
1563 Attribute *a = attr_find( grp->e_attrs, dyn->dy_staticmember );1564 Attribute *a = attr_find( grp->e_attrs, dyn->dy_staticmember );
1564 int rc;1565 int rc;
1565 if ( a ) {1566 if ( a ) {
@@ -1569,7 +1570,7 @@ dynlist_test_membership(Operation *op, dynlist_name_t *dyn, Entry *e)
1569 } else {1570 } else {
1570 rc = LDAP_COMPARE_FALSE;1571 rc = LDAP_COMPARE_FALSE;
1571 }1572 }
1572 overlay_entry_release_ov( op, grp, 0, (slap_overinst *)op->o_bd->bd_info );1573 overlay_entry_release_ov( op, grp, 0, on );
1573 return rc;1574 return rc;
1574 }1575 }
1575 }1576 }
@@ -1591,7 +1592,7 @@ dynlist_add_memberOf(Operation *op, SlapReply *rs, dynlist_search_t *ds)
1591 dyn = ptr->avl_data;1592 dyn = ptr->avl_data;
1592 for ( dlm = dyn->dy_dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {1593 for ( dlm = dyn->dy_dli->dli_dlm; dlm; dlm = dlm->dlm_next ) {
1593 if ( dlm->dlm_memberOf_ad ) {1594 if ( dlm->dlm_memberOf_ad ) {
1594 if ( dynlist_test_membership( op, dyn, e ) == LDAP_COMPARE_TRUE ) {1595 if ( dynlist_test_membership( op, ds->ds_on, dyn, e ) == LDAP_COMPARE_TRUE ) {
1595 /* ensure e is modifiable, but do not replace1596 /* ensure e is modifiable, but do not replace
1596 * sr_entry yet since we have pointers into it */1597 * sr_entry yet since we have pointers into it */
1597 if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) && e == rs->sr_entry ) {1598 if ( !( rs->sr_flags & REP_ENTRY_MODIFIABLE ) && e == rs->sr_entry ) {
@@ -1655,7 +1656,7 @@ dynlist_search2resp( Operation *op, SlapReply *rs )
1655 dyn = ldap_tavl_find( ds->ds_names, &rs->sr_entry->e_nname, dynlist_avl_cmp );1656 dyn = ldap_tavl_find( ds->ds_names, &rs->sr_entry->e_nname, dynlist_avl_cmp );
1656 if ( dyn ) {1657 if ( dyn ) {
1657 dyn->dy_seen = 1;1658 dyn->dy_seen = 1;
1658 rc = dynlist_prepare_entry( op, rs, dyn->dy_dli, dyn );1659 rc = dynlist_prepare_entry( op, rs, ds->ds_on, dyn->dy_dli, dyn );
1659 } else if ( ds->ds_want )1660 } else if ( ds->ds_want )
1660 dynlist_add_memberOf( op, rs, ds );1661 dynlist_add_memberOf( op, rs, ds );
1661 }1662 }
@@ -1667,7 +1668,7 @@ dynlist_search2resp( Operation *op, SlapReply *rs )
1667 for ( dli = ds->ds_dli; dli; dli = dli->dli_next ) {1668 for ( dli = ds->ds_dli; dli; dli = dli->dli_next ) {
1668 if ( is_entry_objectclass_or_sub( rs->sr_entry, dli->dli_oc ) &&1669 if ( is_entry_objectclass_or_sub( rs->sr_entry, dli->dli_oc ) &&
1669 dynlist_check_scope( op, rs->sr_entry, dli ))1670 dynlist_check_scope( op, rs->sr_entry, dli ))
1670 rc = dynlist_prepare_entry( op, rs, dli, NULL );1671 rc = dynlist_prepare_entry( op, rs, ds->ds_on, dli, NULL );
1671 }1672 }
1672 }1673 }
1673 }1674 }
@@ -1677,7 +1678,7 @@ dynlist_search2resp( Operation *op, SlapReply *rs )
1677 }1678 }
1678 return rc;1679 return rc;
1679 } else if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS ) {1680 } else if ( rs->sr_type == REP_RESULT && rs->sr_err == LDAP_SUCCESS ) {
1680 slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;1681 slap_overinst *on = ds->ds_on;
1681 TAvlnode *ptr, *skip = NULL;1682 TAvlnode *ptr, *skip = NULL;
1682 SlapReply r = *rs;1683 SlapReply r = *rs;
1683 dynlist_map_t *dlm = NULL;1684 dynlist_map_t *dlm = NULL;
@@ -1729,7 +1730,7 @@ dynlist_search2resp( Operation *op, SlapReply *rs )
1729 r.sr_entry == NULL )1730 r.sr_entry == NULL )
1730 goto next;1731 goto next;
1731 r.sr_flags = REP_ENTRY_MUSTRELEASE;1732 r.sr_flags = REP_ENTRY_MUSTRELEASE;
1732 dynlist_prepare_entry( op, &r, dyn->dy_dli, dyn );1733 dynlist_prepare_entry( op, &r, on, dyn->dy_dli, dyn );
1733 if ( test_filter( op, r.sr_entry, f ) == LDAP_COMPARE_TRUE ) {1734 if ( test_filter( op, r.sr_entry, f ) == LDAP_COMPARE_TRUE ) {
1734 r.sr_attrs = op->ors_attrs;1735 r.sr_attrs = op->ors_attrs;
1735 rs->sr_err = send_search_entry( op, &r );1736 rs->sr_err = send_search_entry( op, &r );
@@ -1895,6 +1896,8 @@ dynlist_search( Operation *op, SlapReply *rs )
1895 userattrs = SLAP_USERATTRS( attrflags );1896 userattrs = SLAP_USERATTRS( attrflags );
1896 }1897 }
18971898
1899 if (dlg->dlg_simple)
1900 goto simple;
1898 /* Find all groups in scope. For group expansion1901 /* Find all groups in scope. For group expansion
1899 * we only need the groups within the search scope, but1902 * we only need the groups within the search scope, but
1900 * for memberOf populating, we need all dyngroups.1903 * for memberOf populating, we need all dyngroups.
@@ -2063,12 +2066,14 @@ dynlist_search( Operation *op, SlapReply *rs )
2063 dynlist_nestlink( op, ds );2066 dynlist_nestlink( op, ds );
2064 }2067 }
2065 }2068 }
2069simple:
20662070
2067 if ( dlg->dlg_dli || ds->ds_names != NULL ) {2071 if ( dlg->dlg_dli || ds->ds_names != NULL ) {
2068 sc->sc_response = dynlist_search2resp;2072 sc->sc_response = dynlist_search2resp;
2069 sc->sc_cleanup = dynlist_search_cleanup;2073 sc->sc_cleanup = dynlist_search_cleanup;
2070 sc->sc_next = op->o_callback;2074 sc->sc_next = op->o_callback;
2071 op->o_callback = sc;2075 op->o_callback = sc;
2076 ds->ds_on = on;
20722077
2073 /* dynamic lists need this */2078 /* dynamic lists need this */
2074 ds->ds_dli = dlg->dlg_dli;2079 ds->ds_dli = dlg->dlg_dli;
@@ -2145,6 +2150,13 @@ static ConfigTable dlcfg[] = {
2145 3, 3, 0, ARG_MAGIC|DL_ATTRPAIR_COMPAT, dl_cfgen,2150 3, 3, 0, ARG_MAGIC|DL_ATTRPAIR_COMPAT, dl_cfgen,
2146 NULL, NULL, NULL },2151 NULL, NULL, NULL },
2147#endif2152#endif
2153 { "dynlist-simple", NULL, 0, 0, 0, ARG_OFFSET|ARG_ON_OFF,
2154 (void *)offsetof(dynlist_gen_t, dlg_simple),
2155 "( OLcfgOvAt:8.2 NAME 'olcDynListSimple' "
2156 "DESC 'Simple mode - disable features added since 2.4.' "
2157 "EQUALITY booleanMatch "
2158 "SYNTAX OMsBoolean SINGLE-VALUE )",
2159 NULL, NULL },
2148 { NULL, NULL, 0, 0, 0, ARG_IGNORED }2160 { NULL, NULL, 0, 0, 0, ARG_IGNORED }
2149};2161};
21502162
@@ -2153,7 +2165,7 @@ static ConfigOCs dlocs[] = {
2153 "NAME ( 'olcDynListConfig' 'olcDynamicList' ) "2165 "NAME ( 'olcDynListConfig' 'olcDynamicList' ) "
2154 "DESC 'Dynamic list configuration' "2166 "DESC 'Dynamic list configuration' "
2155 "SUP olcOverlayConfig "2167 "SUP olcOverlayConfig "
2156 "MAY olcDynListAttrSet )",2168 "MAY ( olcDynListAttrSet $ olcDynListSimple ) )",
2157 Cft_Overlay, dlcfg, NULL, NULL },2169 Cft_Overlay, dlcfg, NULL, NULL },
2158 { NULL, 0, NULL }2170 { NULL, 0, NULL }
2159};2171};
@@ -2740,10 +2752,13 @@ dynlist_db_init(
2740 slap_overinst *on = (slap_overinst *)be->bd_info;2752 slap_overinst *on = (slap_overinst *)be->bd_info;
2741 dynlist_gen_t *dlg;2753 dynlist_gen_t *dlg;
27422754
2743 dlg = (dynlist_gen_t *)ch_malloc( sizeof( *dlg ));2755 if ( SLAP_ISGLOBALOVERLAY( be ) ) {
2756 Debug( LDAP_DEBUG_ANY, "dynlist cannot be used as global overlay.\n" );
2757 return 1;
2758 }
2759
2760 dlg = (dynlist_gen_t *)ch_calloc( 1, sizeof( *dlg ));
2744 on->on_bi.bi_private = dlg;2761 on->on_bi.bi_private = dlg;
2745 dlg->dlg_dli = NULL;
2746 dlg->dlg_memberOf = 0;
27472762
2748 return 0;2763 return 0;
2749}2764}
diff --git a/servers/slapd/proto-slap.h b/servers/slapd/proto-slap.h
index 106a371..c1364a9 100644
--- a/servers/slapd/proto-slap.h
+++ b/servers/slapd/proto-slap.h
@@ -100,9 +100,7 @@ LDAP_SLAPD_F (int) acl_string_expand LDAP_P((
100 */100 */
101LDAP_SLAPD_V (LDAP_CONST char *) style_strings[];101LDAP_SLAPD_V (LDAP_CONST char *) style_strings[];
102102
103LDAP_SLAPD_F (int) parse_acl LDAP_P(( Backend *be,103LDAP_SLAPD_F (int) parse_acl LDAP_P(( struct config_args_s *ca, int pos ));
104 const char *fname, int lineno,
105 int argc, char **argv, int pos ));
106104
107LDAP_SLAPD_F (char *) access2str LDAP_P(( slap_access_t access ));105LDAP_SLAPD_F (char *) access2str LDAP_P(( slap_access_t access ));
108LDAP_SLAPD_F (slap_access_t) str2access LDAP_P(( const char *str ));106LDAP_SLAPD_F (slap_access_t) str2access LDAP_P(( const char *str ));
diff --git a/servers/slapd/slap-config.h b/servers/slapd/slap-config.h
index 3252fd7..5682204 100644
--- a/servers/slapd/slap-config.h
+++ b/servers/slapd/slap-config.h
@@ -196,31 +196,31 @@ typedef struct config_args_s {
196#define value_ndn values.v_dn.vdn_ndn196#define value_ndn values.v_dn.vdn_ndn
197#define value_ad values.v_ad197#define value_ad values.v_ad
198198
199int config_fp_parse_line(ConfigArgs *c);199LDAP_SLAPD_F (int) config_fp_parse_line(ConfigArgs *c);
200200
201int config_register_schema(ConfigTable *ct, ConfigOCs *co);201LDAP_SLAPD_F (int) config_register_schema(ConfigTable *ct, ConfigOCs *co);
202int config_del_vals(ConfigTable *cf, ConfigArgs *c);202LDAP_SLAPD_F (int) config_del_vals(ConfigTable *cf, ConfigArgs *c);
203int config_get_vals(ConfigTable *ct, ConfigArgs *c);203LDAP_SLAPD_F (int) config_get_vals(ConfigTable *ct, ConfigArgs *c);
204int config_add_vals(ConfigTable *ct, ConfigArgs *c);204LDAP_SLAPD_F (int) config_add_vals(ConfigTable *ct, ConfigArgs *c);
205205
206int config_push_cleanup(ConfigArgs *c, ConfigDriver *cleanup);206LDAP_SLAPD_F (int) config_push_cleanup(ConfigArgs *c, ConfigDriver *cleanup);
207int config_run_cleanup(ConfigArgs *c);207LDAP_SLAPD_F (int) config_run_cleanup(ConfigArgs *c);
208208
209void init_config_argv( ConfigArgs *c );209LDAP_SLAPD_F (void) init_config_argv( ConfigArgs *c );
210int init_config_attrs(ConfigTable *ct);210LDAP_SLAPD_F (int) init_config_attrs(ConfigTable *ct);
211int init_config_ocs( ConfigOCs *ocs );211LDAP_SLAPD_F (int) init_config_ocs( ConfigOCs *ocs );
212void config_parse_ldif( ConfigArgs *c );212LDAP_SLAPD_F (void) config_parse_ldif( ConfigArgs *c );
213int config_parse_vals(ConfigTable *ct, ConfigArgs *c, int valx);213LDAP_SLAPD_F (int) config_parse_vals(ConfigTable *ct, ConfigArgs *c, int valx);
214int config_parse_add(ConfigTable *ct, ConfigArgs *c, int valx);214LDAP_SLAPD_F (int) config_parse_add(ConfigTable *ct, ConfigArgs *c, int valx);
215int read_config_file(const char *fname, int depth, ConfigArgs *cf,215LDAP_SLAPD_F (int) read_config_file(const char *fname, int depth, ConfigArgs *cf,
216 ConfigTable *cft );216 ConfigTable *cft );
217217
218ConfigTable * config_find_keyword(ConfigTable *ct, ConfigArgs *c);218LDAP_SLAPD_F (ConfigTable *) config_find_keyword(ConfigTable *ct, ConfigArgs *c);
219Entry * config_build_entry( Operation *op, SlapReply *rs, CfEntryInfo *parent,219LDAP_SLAPD_F (Entry *) config_build_entry( Operation *op, SlapReply *rs, CfEntryInfo *parent,
220 ConfigArgs *c, struct berval *rdn, ConfigOCs *main, ConfigOCs *extra );220 ConfigArgs *c, struct berval *rdn, ConfigOCs *main, ConfigOCs *extra );
221221
222Listener *config_check_my_url(const char *url, LDAPURLDesc *lud);222LDAP_SLAPD_F (Listener *) config_check_my_url(const char *url, LDAPURLDesc *lud);
223int config_shadow( ConfigArgs *c, slap_mask_t flag );223LDAP_SLAPD_F (int) config_shadow( ConfigArgs *c, slap_mask_t flag );
224#define config_slurp_shadow(c) config_shadow((c), SLAP_DBFLAG_SLURP_SHADOW)224#define config_slurp_shadow(c) config_shadow((c), SLAP_DBFLAG_SLURP_SHADOW)
225#define config_sync_shadow(c) config_shadow((c), SLAP_DBFLAG_SYNC_SHADOW)225#define config_sync_shadow(c) config_shadow((c), SLAP_DBFLAG_SYNC_SHADOW)
226226
@@ -231,7 +231,7 @@ int config_shadow( ConfigArgs *c, slap_mask_t flag );
231#define SLAP_X_ORDERED_FMT "{%d}"231#define SLAP_X_ORDERED_FMT "{%d}"
232232
233LDAP_SLAPD_V (slap_verbmasks *) slap_ldap_response_code;233LDAP_SLAPD_V (slap_verbmasks *) slap_ldap_response_code;
234extern int slap_ldap_response_code_register( struct berval *bv, int err );234LDAP_SLAPD_F (int) slap_ldap_response_code_register( struct berval *bv, int err );
235235
236LDAP_SLAPD_V (ConfigTable) olcDatabaseDummy[];236LDAP_SLAPD_V (ConfigTable) olcDatabaseDummy[];
237237
diff --git a/servers/slapd/slap.h b/servers/slapd/slap.h
index 5cf2f46..605a80f 100644
--- a/servers/slapd/slap.h
+++ b/servers/slapd/slap.h
@@ -1319,12 +1319,15 @@ typedef struct AuthorizationInformation {
1319 slap_ssf_t sai_sasl_ssf; /* SASL SSF */1319 slap_ssf_t sai_sasl_ssf; /* SASL SSF */
1320} AuthorizationInformation;1320} AuthorizationInformation;
13211321
1322typedef struct config_args_s ConfigArgs; /* slap-config.h */
1323typedef struct config_reply_s ConfigReply; /* slap-config.h */
1324
1322#ifdef SLAP_DYNACL1325#ifdef SLAP_DYNACL
13231326
1324/*1327/*
1325 * "dynamic" ACL infrastructure (for ACIs and more)1328 * "dynamic" ACL infrastructure (for ACIs and more)
1326 */1329 */
1327typedef int (slap_dynacl_parse) LDAP_P(( const char *fname, int lineno,1330typedef int (slap_dynacl_parse) LDAP_P(( ConfigArgs *ca,
1328 const char *opts, slap_style_t, const char *, void **privp ));1331 const char *opts, slap_style_t, const char *, void **privp ));
1329typedef int (slap_dynacl_unparse) LDAP_P(( void *priv, struct berval *bv ));1332typedef int (slap_dynacl_unparse) LDAP_P(( void *priv, struct berval *bv ));
1330typedef int (slap_dynacl_mask) LDAP_P((1333typedef int (slap_dynacl_mask) LDAP_P((
@@ -2019,7 +2022,6 @@ typedef int (BI_config) LDAP_P((BackendInfo *bi,
2019 const char *fname, int lineno,2022 const char *fname, int lineno,
2020 int argc, char **argv));2023 int argc, char **argv));
20212024
2022typedef struct config_reply_s ConfigReply; /* slap-config.h */
2023typedef int (BI_db_func) LDAP_P((Backend *bd, ConfigReply *cr));2025typedef int (BI_db_func) LDAP_P((Backend *bd, ConfigReply *cr));
2024typedef BI_db_func BI_db_init;2026typedef BI_db_func BI_db_init;
2025typedef BI_db_func BI_db_open;2027typedef BI_db_func BI_db_open;
diff --git a/servers/slapd/slapi/Makefile.in b/servers/slapd/slapi/Makefile.in
index 0e46f78..32ade0c 100644
--- a/servers/slapd/slapi/Makefile.in
+++ b/servers/slapd/slapi/Makefile.in
@@ -19,9 +19,6 @@ LIBRARY = libslapi.la
19#all-common: $(LIBRARY) $(PROGRAMS)19#all-common: $(LIBRARY) $(PROGRAMS)
20# @touch plugin.c slapi_pblock.c slapi_utils.c slapi_ops.c slapi_ext.c20# @touch plugin.c slapi_pblock.c slapi_utils.c slapi_ops.c slapi_ext.c
2121
22NT_SRCS = nt_err.c
23NT_OBJS = nt_err.lo
24
25LIB_DEFS = -DSLAPI_LIBRARY22LIB_DEFS = -DSLAPI_LIBRARY
2623
27SRCS= plugin.c slapi_pblock.c slapi_utils.c printmsg.c slapi_ops.c slapi_dn.c slapi_ext.c slapi_overlay.c \24SRCS= plugin.c slapi_pblock.c slapi_utils.c printmsg.c slapi_ops.c slapi_dn.c slapi_ext.c slapi_overlay.c \
@@ -31,12 +28,15 @@ OBJS= plugin.lo slapi_pblock.lo slapi_utils.lo printmsg.lo slapi_ops.lo slapi_d
3128
32XSRCS= version.c29XSRCS= version.c
3330
34LDAP_INCDIR= ../../../include -I.. -I. 31LDAP_INCDIR= ../../../include -I.. -I.
35LDAP_LIBDIR= ../../../libraries 32LDAP_LIBDIR= ../../../libraries
33
34shared_LDAP_LIBS = $(LDAP_LIBLDAP_LA) $(LDAP_LIBLBER_LA)
3635
37XLIBS = $(LIBRARY)36XLIBS = $(LIBRARY)
38XXLIBS = 37XXLIBS =
39NT_LINK_LIBS = $(AC_LIBS)38MOD_LIBS = $(MODULES_LIBS)
39NT_LINK_LIBS = $(AC_LIBS) -L.. -lslapd $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS)
4040
41XINCPATH = -I$(srcdir)/.. -I$(srcdir)41XINCPATH = -I$(srcdir)/.. -I$(srcdir)
42XDEFS = $(MODULES_CPPFLAGS)42XDEFS = $(MODULES_CPPFLAGS)
diff --git a/servers/slapd/slapi/plugin.c b/servers/slapd/slapi/plugin.c
index de8c60d..ca5dbea 100644
--- a/servers/slapd/slapi/plugin.c
+++ b/servers/slapd/slapi/plugin.c
@@ -36,7 +36,7 @@
36#include <ltdl.h>36#include <ltdl.h>
3737
38static int slapi_int_load_plugin( Slapi_PBlock *, const char *, const char *, int, 38static int slapi_int_load_plugin( Slapi_PBlock *, const char *, const char *, int,
39 SLAPI_FUNC *, lt_dlhandle * );39 SLAPI_FUNC *, lt_dlhandle *, ConfigArgs *c );
4040
41/* pointer to link list of extended objects */41/* pointer to link list of extended objects */
42static ExtendedOp *pGExtendedOps = NULL;42static ExtendedOp *pGExtendedOps = NULL;
@@ -68,15 +68,15 @@ static Slapi_PBlock *
68plugin_pblock_new(68plugin_pblock_new(
69 int type, 69 int type,
70 int argc, 70 int argc,
71 char *argv[] ) 71 ConfigArgs *c )
72{72{
73 Slapi_PBlock *pPlugin = NULL; 73 Slapi_PBlock *pPlugin = NULL;
74 Slapi_PluginDesc *pPluginDesc = NULL;74 Slapi_PluginDesc *pPluginDesc = NULL;
75 lt_dlhandle hdLoadHandle;75 lt_dlhandle hdLoadHandle;
76 int rc;76 int rc;
77 char **av2 = NULL, **ppPluginArgv;77 char **av2 = NULL, **ppPluginArgv;
78 char *path = argv[2];78 char *path = c->argv[2];
79 char *initfunc = argv[3];79 char *initfunc = c->argv[3];
8080
81 pPlugin = slapi_pblock_new();81 pPlugin = slapi_pblock_new();
82 if ( pPlugin == NULL ) {82 if ( pPlugin == NULL ) {
@@ -87,7 +87,7 @@ plugin_pblock_new(
87 slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)&type );87 slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)&type );
88 slapi_pblock_set( pPlugin, SLAPI_PLUGIN_ARGC, (void *)&argc );88 slapi_pblock_set( pPlugin, SLAPI_PLUGIN_ARGC, (void *)&argc );
8989
90 av2 = ldap_charray_dup( argv );90 av2 = ldap_charray_dup( c->argv );
91 if ( av2 == NULL ) {91 if ( av2 == NULL ) {
92 rc = LDAP_NO_MEMORY;92 rc = LDAP_NO_MEMORY;
93 goto done;93 goto done;
@@ -102,7 +102,7 @@ plugin_pblock_new(
102 slapi_pblock_set( pPlugin, SLAPI_PLUGIN_ARGV, (void *)ppPluginArgv );102 slapi_pblock_set( pPlugin, SLAPI_PLUGIN_ARGV, (void *)ppPluginArgv );
103 slapi_pblock_set( pPlugin, SLAPI_X_CONFIG_ARGV, (void *)av2 );103 slapi_pblock_set( pPlugin, SLAPI_X_CONFIG_ARGV, (void *)av2 );
104104
105 rc = slapi_int_load_plugin( pPlugin, path, initfunc, 1, NULL, &hdLoadHandle );105 rc = slapi_int_load_plugin( pPlugin, path, initfunc, 1, NULL, &hdLoadHandle, c );
106 if ( rc != 0 ) {106 if ( rc != 0 ) {
107 goto done;107 goto done;
108 }108 }
@@ -556,7 +556,8 @@ slapi_int_load_plugin(
556 const char *initfunc, 556 const char *initfunc,
557 int doInit,557 int doInit,
558 SLAPI_FUNC *pInitFunc,558 SLAPI_FUNC *pInitFunc,
559 lt_dlhandle *pLdHandle ) 559 lt_dlhandle *pLdHandle,
560 ConfigArgs *c )
560{561{
561 int rc = LDAP_SUCCESS;562 int rc = LDAP_SUCCESS;
562 SLAPI_FUNC fpInitFunc = NULL;563 SLAPI_FUNC fpInitFunc = NULL;
@@ -570,15 +571,17 @@ slapi_int_load_plugin(
570 /* load in the module */571 /* load in the module */
571 *pLdHandle = lt_dlopen( path );572 *pLdHandle = lt_dlopen( path );
572 if ( *pLdHandle == NULL ) {573 if ( *pLdHandle == NULL ) {
573 fprintf( stderr, "failed to load plugin %s: %s\n",574 snprintf( c->cr_msg, sizeof( c->cr_msg ), "failed to load plugin %s: %s",
574 path, lt_dlerror() );575 path, lt_dlerror() );
576 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
575 return LDAP_LOCAL_ERROR;577 return LDAP_LOCAL_ERROR;
576 }578 }
577579
578 fpInitFunc = (SLAPI_FUNC)lt_dlsym( *pLdHandle, initfunc );580 fpInitFunc = (SLAPI_FUNC)lt_dlsym( *pLdHandle, initfunc );
579 if ( fpInitFunc == NULL ) {581 if ( fpInitFunc == NULL ) {
580 fprintf( stderr, "failed to find symbol %s in plugin %s: %s\n",582 snprintf( c->cr_msg, sizeof( c->cr_msg ), "failed to find symbol %s in plugin %s: %s",
581 initfunc, path, lt_dlerror() );583 initfunc, path, lt_dlerror() );
584 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
582 lt_dlclose( *pLdHandle );585 lt_dlclose( *pLdHandle );
583 return LDAP_LOCAL_ERROR;586 return LDAP_LOCAL_ERROR;
584 }587 }
@@ -643,50 +646,46 @@ slapi_int_call_plugins(
643646
644int647int
645slapi_int_read_config(648slapi_int_read_config(
646 Backend *be, 649 struct config_args_s *c )
647 const char *fname,
648 int lineno,
649 int argc,
650 char **argv,
651 int index )
652{650{
653 int iType = -1;651 int iType = -1;
654 int numPluginArgc = 0;652 int numPluginArgc = 0;
655653
656 if ( argc < 4 ) {654 if ( c->argc < 4 ) {
657 fprintf( stderr,655 snprintf( c->cr_msg, sizeof( c->cr_msg ),
658 "%s: line %d: missing arguments "656 "missing arguments "
659 "in \"plugin <plugin_type> <lib_path> "657 "in \"plugin <plugin_type> <lib_path> "
660 "<init_function> [<arguments>]\" line\n",658 "<init_function> [<arguments>]\" line" );
661 fname, lineno );659 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
662 return 1;660 return 1;
663 }661 }
664662
665 /* automatically instantiate overlay if necessary */663 /* automatically instantiate overlay if necessary */
666 if ( !slapi_over_is_inst( be ) ) {664 if ( !slapi_over_is_inst( c->be ) ) {
667 ConfigReply cr = { 0 };665 if ( slapi_over_config( c->be, &c->reply ) != 0 ) {
668 if ( slapi_over_config( be, &cr ) != 0 ) {666 Debug( LDAP_DEBUG_ANY, "%s: "
669 fprintf( stderr, "Failed to instantiate SLAPI overlay: "667 "Failed to instantiate SLAPI overlay: "
670 "err=%d msg=\"%s\"\n", cr.err, cr.msg );668 "err=%d msg=\"%s\"\n", c->log, c->reply.err, c->reply.msg );
671 return -1;669 return -1;
672 }670 }
673 }671 }
674 672
675 if ( strcasecmp( argv[1], "preoperation" ) == 0 ) {673 if ( strcasecmp( c->argv[1], "preoperation" ) == 0 ) {
676 iType = SLAPI_PLUGIN_PREOPERATION;674 iType = SLAPI_PLUGIN_PREOPERATION;
677 } else if ( strcasecmp( argv[1], "postoperation" ) == 0 ) {675 } else if ( strcasecmp( c->argv[1], "postoperation" ) == 0 ) {
678 iType = SLAPI_PLUGIN_POSTOPERATION;676 iType = SLAPI_PLUGIN_POSTOPERATION;
679 } else if ( strcasecmp( argv[1], "extendedop" ) == 0 ) {677 } else if ( strcasecmp( c->argv[1], "extendedop" ) == 0 ) {
680 iType = SLAPI_PLUGIN_EXTENDEDOP;678 iType = SLAPI_PLUGIN_EXTENDEDOP;
681 } else if ( strcasecmp( argv[1], "object" ) == 0 ) {679 } else if ( strcasecmp( c->argv[1], "object" ) == 0 ) {
682 iType = SLAPI_PLUGIN_OBJECT;680 iType = SLAPI_PLUGIN_OBJECT;
683 } else {681 } else {
684 fprintf( stderr, "%s: line %d: invalid plugin type \"%s\".\n",682 snprintf( c->cr_msg, sizeof( c->cr_msg ),
685 fname, lineno, argv[1] );683 "invalid plugin type \"%s\"", c->argv[1] );
684 Debug( LDAP_DEBUG_ANY, "%s: %s.\n", c->log, c->cr_msg );
686 return 1;685 return 1;
687 }686 }
688 687
689 numPluginArgc = argc - 4;688 numPluginArgc = c->argc - 4;
690689
691 if ( iType == SLAPI_PLUGIN_PREOPERATION ||690 if ( iType == SLAPI_PLUGIN_PREOPERATION ||
692 iType == SLAPI_PLUGIN_EXTENDEDOP ||691 iType == SLAPI_PLUGIN_EXTENDEDOP ||
@@ -695,23 +694,23 @@ slapi_int_read_config(
695 int rc;694 int rc;
696 Slapi_PBlock *pPlugin;695 Slapi_PBlock *pPlugin;
697696
698 pPlugin = plugin_pblock_new( iType, numPluginArgc, argv );697 pPlugin = plugin_pblock_new( iType, numPluginArgc, c->argv );
699 if (pPlugin == NULL) {698 if (pPlugin == NULL) {
700 return 1;699 return 1;
701 }700 }
702701
703 if (iType == SLAPI_PLUGIN_EXTENDEDOP) {702 if (iType == SLAPI_PLUGIN_EXTENDEDOP) {
704 rc = slapi_int_register_extop(be, &pGExtendedOps, pPlugin);703 rc = slapi_int_register_extop(c->be, &pGExtendedOps, pPlugin);
705 if ( rc != LDAP_SUCCESS ) {704 if ( rc != LDAP_SUCCESS ) {
706 slapi_pblock_destroy( pPlugin );705 slapi_pblock_destroy( pPlugin );
707 return 1;706 return 1;
708 }707 }
709 }708 }
710709
711 rc = slapi_int_register_plugin_index( be, pPlugin, index );710 rc = slapi_int_register_plugin_index( c->be, pPlugin, c->valx );
712 if ( rc != LDAP_SUCCESS ) {711 if ( rc != LDAP_SUCCESS ) {
713 if ( iType == SLAPI_PLUGIN_EXTENDEDOP ) {712 if ( iType == SLAPI_PLUGIN_EXTENDEDOP ) {
714 slapi_int_unregister_extop( be, &pGExtendedOps, pPlugin );713 slapi_int_unregister_extop( c->be, &pGExtendedOps, pPlugin );
715 }714 }
716 slapi_pblock_destroy( pPlugin );715 slapi_pblock_destroy( pPlugin );
717 return 1;716 return 1;
diff --git a/servers/slapd/slapi/printmsg.c b/servers/slapd/slapi/printmsg.c
index 15b6004..5251846 100644
--- a/servers/slapd/slapi/printmsg.c
+++ b/servers/slapd/slapi/printmsg.c
@@ -32,6 +32,10 @@
32#include <slap.h>32#include <slap.h>
33#include <slapi.h>33#include <slapi.h>
3434
35#ifdef _WIN32
36#include <io.h>
37#endif
38
35#include <ldap_pvt_thread.h>39#include <ldap_pvt_thread.h>
3640
37/* Single threads access to routine */41/* Single threads access to routine */
@@ -60,18 +64,30 @@ slapi_int_log_error(
6064
61 /* for now, we log all severities */65 /* for now, we log all severities */
62 if ( level <= slapi_log_level ) {66 if ( level <= slapi_log_level ) {
67#ifdef _WIN32
68 intptr_t fhandle;
69#endif
63 fp = fopen( slapi_log_file, "a" );70 fp = fopen( slapi_log_file, "a" );
64 if ( fp == NULL) {71 if ( fp == NULL) {
65 rc = -1;72 rc = -1;
66 goto done;73 goto done;
67 }74 }
6875
76#ifdef _WIN32
77 fhandle = _get_osfhandle( fileno( fp ));
78#endif
69 /*79 /*
70 * FIXME: could block80 * FIXME: could block
71 */81 */
82#ifdef _WIN32
83 while ( LockFile( fhandle, 0, 0, UINT_MAX, UINT_MAX ) == 0 ) {
84 /* DO NOTHING */ ;
85 }
86#else
72 while ( lockf( fileno( fp ), F_LOCK, 0 ) != 0 ) {87 while ( lockf( fileno( fp ), F_LOCK, 0 ) != 0 ) {
73 /* DO NOTHING */ ;88 /* DO NOTHING */ ;
74 }89 }
90#endif
7591
76 time( &currentTime );92 time( &currentTime );
77 ltm = localtime( &currentTime );93 ltm = localtime( &currentTime );
@@ -85,7 +101,11 @@ slapi_int_log_error(
85 }101 }
86 fflush( fp );102 fflush( fp );
87103
104#ifdef _WIN32
105 UnlockFile( fhandle, 0, 0, UINT_MAX, UINT_MAX );
106#else
88 lockf( fileno( fp ), F_ULOCK, 0 );107 lockf( fileno( fp ), F_ULOCK, 0 );
108#endif
89109
90 fclose( fp );110 fclose( fp );
91111
diff --git a/servers/slapd/slapi/proto-slapi.h b/servers/slapd/slapi/proto-slapi.h
index 9d52510..e9eb76b 100644
--- a/servers/slapd/slapi/proto-slapi.h
+++ b/servers/slapd/slapi/proto-slapi.h
@@ -72,8 +72,7 @@ LDAP_SLAPI_F (int) slapi_int_register_extop LDAP_P((Backend *pBE, ExtendedOp **o
72LDAP_SLAPI_F (int) slapi_int_get_extop_plugin LDAP_P((struct berval *reqoid, SLAPI_FUNC *pFuncAddr ));72LDAP_SLAPI_F (int) slapi_int_get_extop_plugin LDAP_P((struct berval *reqoid, SLAPI_FUNC *pFuncAddr ));
73LDAP_SLAPI_F (struct berval *) slapi_int_get_supported_extop LDAP_P(( int ));73LDAP_SLAPI_F (struct berval *) slapi_int_get_supported_extop LDAP_P(( int ));
74LDAP_SLAPI_F (int) slapi_int_unregister_plugins LDAP_P((Backend *be, int index));74LDAP_SLAPI_F (int) slapi_int_unregister_plugins LDAP_P((Backend *be, int index));
75LDAP_SLAPI_F (int) slapi_int_read_config LDAP_P((Backend *be, const char *fname, int lineno,75LDAP_SLAPI_F (int) slapi_int_read_config LDAP_P(( struct config_args_s *c ));
76 int argc, char **argv, int index ));
77LDAP_SLAPI_F (void) slapi_int_plugin_unparse LDAP_P((Backend *be, BerVarray *out ));76LDAP_SLAPI_F (void) slapi_int_plugin_unparse LDAP_P((Backend *be, BerVarray *out ));
78LDAP_SLAPI_F (int) slapi_int_initialize LDAP_P((void));77LDAP_SLAPI_F (int) slapi_int_initialize LDAP_P((void));
7978
diff --git a/servers/slapd/slapi/slapi_utils.c b/servers/slapd/slapi/slapi_utils.c
index 6c1cecf..c459122 100644
--- a/servers/slapd/slapi/slapi_utils.c
+++ b/servers/slapd/slapi/slapi_utils.c
@@ -31,7 +31,11 @@
31#include <slap.h>31#include <slap.h>
32#include <slapi.h>32#include <slapi.h>
3333
34#ifdef _WIN32
35#include <winsock.h>
36#else
34#include <netdb.h>37#include <netdb.h>
38#endif
3539
36#ifdef LDAP_SLAPI40#ifdef LDAP_SLAPI
3741
@@ -1971,6 +1975,8 @@ slapi_timer_current_time( void )
1971 */1975 */
1972#else /* _WIN32 */1976#else /* _WIN32 */
1973 LARGE_INTEGER now;1977 LARGE_INTEGER now;
1978 static LARGE_INTEGER base_time, performance_freq;
1979 static int performance_counter_present;
19741980
1975 if ( first_time ) {1981 if ( first_time ) {
1976 first_time = 0;1982 first_time = 0;
diff --git a/servers/slapd/slappasswd.c b/servers/slapd/slappasswd.c
index 9c2adef..e384364 100644
--- a/servers/slapd/slappasswd.c
+++ b/servers/slapd/slappasswd.c
@@ -250,11 +250,16 @@ slappasswd( int argc, char *argv[] )
250 if( newpw == NULL ) {250 if( newpw == NULL ) {
251 /* prompt for new password */251 /* prompt for new password */
252 char *cknewpw;252 char *cknewpw;
253 newpw = ch_strdup(getpassphrase("New password: "));253 newpw = getpassphrase("New password: ");
254 if ( newpw == NULL ) { /* Allow EOF to exit. */
255 rc = EXIT_FAILURE;
256 goto destroy;
257 }
258 newpw = ch_strdup(newpw);
254 cknewpw = getpassphrase("Re-enter new password: ");259 cknewpw = getpassphrase("Re-enter new password: ");
255 260 if( cknewpw == NULL || strcmp( newpw, cknewpw )) {
256 if( strcmp( newpw, cknewpw )) {261 fprintf( stderr,
257 fprintf( stderr, "Password values do not match\n" );262 "Password values do not match\n" );
258 rc = EXIT_FAILURE;263 rc = EXIT_FAILURE;
259 goto destroy;264 goto destroy;
260 }265 }
diff --git a/tests/progs/slapd-tester.c b/tests/progs/slapd-tester.c
index 7ad88b8..8f9656e 100644
--- a/tests/progs/slapd-tester.c
+++ b/tests/progs/slapd-tester.c
@@ -406,6 +406,9 @@ main( int argc, char **argv )
406406
407 if ( pw_ask ) {407 if ( pw_ask ) {
408 passwd = getpassphrase( _("Enter LDAP Password: ") );408 passwd = getpassphrase( _("Enter LDAP Password: ") );
409 if ( passwd == NULL ) { /* Allow EOF to exit. */
410 exit( EXIT_FAILURE );
411 }
409412
410 } else if ( pw_file ) {413 } else if ( pw_file ) {
411 struct berval pw;414 struct berval pw;

Subscribers

People subscribed via source and target branches