OpenLDAP 2.3 Change Log
OpenLDAP 2.3.6 Engineering
+ 3951
Fixed slapd dnRelativeMatch return (ITS#3931)
- Added slapd ACI syntax validater (ITS#3877)
- Added slapd posixgroup ACL module to contrib
Fixed slapd-bdb/hdb release entry in paged resposne
- Added slapd-meta overlapping targets enhancement (ITS#3711)
Fixed slapd-meta resources release issue (ITS#3943)
- Updated slapo-syncprov CSN filter checks
Fixed slapd-ldap/meta matched return (ITS#3942,ITS#3944)
Fixed slapo-ppolicy reset lockouts issue (ITS#3946)
Fixed nis.schema posixGroup object class kind (ITS#3941)
Revert librewrite regex mutex change (ITS#3932)
+ Updated slapd manage capability
+ Updated slapo-syncprov CSN filter checks
Updated libldap url list parsing
+ Added slapd SASL rootpw support (ITS#3845)
+ Added slapd Stats logging for additional cases
+ Added slapd ACI syntax validater (ITS#3877)
+ Added slapd posixgroup ACL module to contrib
Added slapi SLAPI_X_ADD_STRUCTURAL_CLASS extension
- Add slapd SASL rootpw support (ITS#3845)
- Add slapd Stats logging for additional cases
+ Added slapd-ldap subtree renaming proxing
+ Added slapd-meta overlapping targets enhancement (ITS#3711)
Removed lint
Documentation
Added slapcat(8) -a usage example (ITS#3930)
Updated slapo-unique(5) for clarity (ITS#3936)
Updated slapo-syncprov(5) sessionlog description (ITS#3935)
+ Updated doc/drafts
Build Environment
Updated test prog bind retry code
Fixed test015-xsearch regression (ITS#3506)
+ Added test040-subtree-rename
OpenLDAP 2.3.5 Release
Fixed slapd integerBitOr/AndMatch logic (ITS#3782)
--- /dev/null
+
+
+
+
+
+INTERNET-DRAFT Kurt D. Zeilenga
+Intended Category: Standard Track OpenLDAP Foundation
+Expires in six months 10 February 2005
+
+
+
+ The LDAP No-Op Control
+ <draft-zeilenga-ldap-noop-06.txt>
+
+
+Status of this Memo
+
+ This document is intended to be, after appropriate review and
+ revision, submitted to the IESG for consideration as a Standard Track
+ document. Distribution of this memo is unlimited. Technical
+ discussion of this document will take place on the IETF LDAP
+ Extensions mailing list <ldapext@ietf.org>. Please send editorial
+ comments directly to the author <Kurt@OpenLDAP.org>.
+
+ By submitting this Internet-Draft, I accept the provisions of Section
+ 4 of RFC 3667. By submitting this Internet-Draft, I certify that any
+ applicable patent or other IPR claims of which I am aware have been
+ disclosed, or will be disclosed, and any of which I become aware will
+ be disclosed, in accordance with RFC 3668.
+
+ Internet-Drafts are working documents of the Internet Engineering Task
+ Force (IETF), its areas, and its working groups. Note that other
+ groups may also distribute working documents as Internet-Drafts.
+
+ Internet-Drafts are draft documents valid for a maximum of six months
+ and may be updated, replaced, or obsoleted by other documents at any
+ time. It is inappropriate to use Internet-Drafts as reference material
+ or to cite them other than as "work in progress."
+
+ The list of current Internet-Drafts can be accessed at
+ http://www.ietf.org/1id-abstracts.html
+
+ The list of Internet-Draft Shadow Directories can be accessed at
+ http://www.ietf.org/shadow.html
+
+
+ Copyright (C) The Internet Society (2005). All Rights Reserved.
+
+ Please see the Full Copyright section near the end of this document
+ for more information.
+
+
+
+
+
+
+Zeilenga LDAP No-Op Control [Page 1]
+\f
+INTERNET-DRAFT draft-zeilenga-ldap-noop-06 10 February 2005
+
+
+Abstract
+
+ This document defines the Lightweight Directory Access Protocol (LDAP)
+ No-Op control which can be used to disable the normal effect of an
+ operation. The control can be used to discover how a server might
+ react to a particular update request without updating the directory.
+
+
+1. Overview
+
+ It is often desirable to be able to determine if a directory operation
+ [Protocol] would successful complete or not without having the normal
+ effect of the operation take place. For example, an administrative
+ client might want to verify that new user could update their entry
+ (and not other entries) without the directory actually being updated.
+ The mechanism could be used to build more sophisticated security
+ auditing tools.
+
+ This document defines the Lightweight Directory Access Protocol (LDAP)
+ [Roadmap] No-Op control extension. The presence of the No-Op control
+ in an operation request message disables its normal effect upon the
+ directory which operation would otherwise have. Instead of updating
+ the directory and return the normal indication of success, the server
+ does not update the directory and indicates so by returning the
+ noOperation resultCode (introduced below).
+
+ For example, when the No-Op control is present in a LDAP modify
+ operation [Protocol], the server is do all processing necessary to
+ perform the operation without actually updating the directory. If it
+ detects an error during this processing, it returns a non-success
+ (other than noOperation) resultCode as it normally would. Otherwise,
+ it returns the noOperation. In either case, the directory is left
+ unchanged.
+
+ This No-Op control is not intended to be to an "effective access"
+ mechanism [RFC2820, U12].
+
+
+1.1. Terminology
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+ document are to be interpreted as described in BCP 14 [RFC2119].
+
+ DN stands for Distinguished Name.
+ DSA stands for Directory System Agent.
+ DSE stands for DSA-specific entry.
+
+
+
+
+Zeilenga LDAP No-Op Control [Page 2]
+\f
+INTERNET-DRAFT draft-zeilenga-ldap-noop-06 10 February 2005
+
+
+2. No-Op Control
+
+ The No-Op control is an LDAP Control [Protocol] whose controlType is
+ IANA-ASSIGNED-OID and controlValue is absent. Clients MUST provide a
+ criticality value of TRUE to prevent unintended modification of the
+ directory.
+
+ The control is appropriate for request messages of LDAP Add, Delete,
+ Modify and ModifyDN operations [Protocol]. The control is also
+ appropriate for requests of extended operations which update the
+ directory (or other data stores), such as Password Modify Extended
+ Operation [RFC3062]. There is no corresponding response control.
+
+ When the control is attached to an LDAP request, the server does all
+ normal processing possible for the operation without modification of
+ the directory. That is, when the control is attached to an LDAP
+ request, the directory SHALL NOT be updated and the response SHALL NOT
+ have a resultCode of success (0).
+
+ A result code other than noOperation (IANA-ASSIGNED-CODE) means that
+ the server is unable or unwilling to complete the processing for the
+ reason indicated by the result code. A result code of noOperation
+ (IANA-ASSIGNED-CODE) indicates that the server discovered no reason
+ why the operation would fail if submitted without the No-Op control.
+
+ Servers SHOULD indicate their support for this control by providing
+ IANA-ASSIGNED-OID as a value of the 'supportedControl' attribute type
+ [Models] in their root DSE entry. A server MAY choose to advertise
+ this extension only when the client is authorized to use this
+ operation.
+
+
+3. Security Considerations
+
+ The No-Op control mechanism allows directory administrators and users
+ to verify that access control and other administrative policy controls
+ are properly configured. The mechanism may also lead to the
+ development (and deployment) of more effective security auditing
+ tools.
+
+ Implementors of this LDAP extension should be familiar with security
+ considerations applicable to the LDAP operations [Protocol] extended
+ by this control, as well as general LDAP security considerations
+ [Roadmap].
+
+
+4. IANA Considerations
+
+
+
+
+Zeilenga LDAP No-Op Control [Page 3]
+\f
+INTERNET-DRAFT draft-zeilenga-ldap-noop-06 10 February 2005
+
+
+4.1. Object Identifier
+
+ It is requested that IANA assign an LDAP Object Identifier [BCP64bis]
+ to identify the LDAP No-Op Control defined in this document.
+
+ Subject: Request for LDAP Object Identifier Registration
+ Person & email address to contact for further information:
+ Kurt Zeilenga <kurt@OpenLDAP.org>
+ Specification: RFC XXXX
+ Author/Change Controller: IESG
+ Comments:
+ Identifies the LDAP No-Op Control
+
+
+4.2 LDAP Protocol Mechanism
+
+ Registration of this protocol mechanism is requested [RFC3383].
+
+ Subject: Request for LDAP Protocol Mechanism Registration
+ Object Identifier: IANA-ASSIGNED-OID
+ Description: No-Op Control
+ Person & email address to contact for further information:
+ Kurt Zeilenga <kurt@openldap.org>
+ Usage: Control
+ Specification: RFC XXXX
+ Author/Change Controller: IESG
+ Comments: none
+
+
+4.3 LDAP Result Code
+
+ Assignment of an LDAP Result Code called 'noOperation' is requested.
+
+ Subject: LDAP Result Code Registration
+ Person & email address to contact for further information:
+ Kurt Zeilenga <kurt@OpenLDAP.org>
+ Result Code Name: noOperation
+ Specification: RFC XXXX
+ Author/Change Controller: IESG
+ Comments: none
+
+
+5. Author's Address
+
+ Kurt D. Zeilenga
+ OpenLDAP Foundation
+
+ Email: Kurt@OpenLDAP.org
+
+
+
+Zeilenga LDAP No-Op Control [Page 4]
+\f
+INTERNET-DRAFT draft-zeilenga-ldap-noop-06 10 February 2005
+
+
+6. References
+
+ [[Note to the RFC Editor: please replace the citation tags used in
+ referencing Internet-Drafts with tags of the form RFCnnnn where
+ possible.]]
+
+
+6.1. Normative References
+
+ [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
+ Requirement Levels", BCP 14 (also RFC 2119), March 1997.
+
+ [Protocol] Sermersheim, J. (editor), "LDAP: The Protocol",
+ draft-ietf-ldapbis-protocol-xx.txt, a work in progress.
+
+ [Roadmap] Zeilenga, K. (editor), "LDAP: Technical Specification
+ Road Map", draft-ietf-ldapbis-roadmap-xx.txt, a work in
+ progress.
+
+ [Models] Zeilenga, K. (editor), "LDAP: Directory Information
+ Models", draft-ietf-ldapbis-models-xx.txt, a work in
+ progress.
+
+
+6.2. Informative References
+
+ [X.500] International Telecommunication Union -
+ Telecommunication Standardization Sector, "The Directory
+ -- Overview of concepts, models and services,"
+ X.500(1993) (also ISO/IEC 9594-1:1994).
+
+ [RFC2820] Stokes, E., et. al., "Access Control Requirements for
+ LDAP", RFC 2820, May 2000.
+
+ [RFC3062] Zeilenga, K., "LDAP Password Modify Extended Operation",
+ RFC 3062, February 2000.
+
+ [BCP64bis] Zeilenga, K., "IANA Considerations for LDAP",
+ draft-ietf-ldapbis-bcp64-xx.txt, a work in progress.
+
+
+
+Intellectual Property Rights
+
+ The IETF takes no position regarding the validity or scope of any
+ Intellectual Property Rights or other rights that might be claimed to
+ pertain to the implementation or use of the technology described in
+ this document or the extent to which any license under such rights
+
+
+
+Zeilenga LDAP No-Op Control [Page 5]
+\f
+INTERNET-DRAFT draft-zeilenga-ldap-noop-06 10 February 2005
+
+
+ might or might not be available; nor does it represent that it has
+ made any independent effort to identify any such rights. Information
+ on the procedures with respect to rights in RFC documents can be found
+ in BCP 78 and BCP 79.
+
+ Copies of IPR disclosures made to the IETF Secretariat and any
+ assurances of licenses to be made available, or the result of an
+ attempt made to obtain a general license or permission for the use of
+ such proprietary rights by implementers or users of this specification
+ can be obtained from the IETF on-line IPR repository at
+ http://www.ietf.org/ipr.
+
+ The IETF invites any interested party to bring to its attention any
+ copyrights, patents or patent applications, or other proprietary
+ rights that may cover technology that may be required to implement
+ this standard. Please address the information to the IETF at
+ ietf-ipr@ietf.org.
+
+
+
+Full Copyright
+
+ Copyright (C) The Internet Society (2005). This document is subject
+ to the rights, licenses and restrictions contained in BCP 78, and
+ except as set forth therein, the authors retain all their rights.
+
+ This document and the information contained herein are provided on an
+ "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+ OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
+ ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
+ INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
+ INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Zeilenga LDAP No-Op Control [Page 6]
+\f
+
+
case LDAP_DN_FORMAT_LDAPV3:
case LDAP_DN_FORMAT_LDAPV2:
n = ldap_dn2domain( strin, &tmp );
- if( n ) {
+ if ( n ) {
fprintf( stdout, "\nldap_dn2domain(\"%s\") FAILED\n", strin );
} else {
fprintf( stdout, "\nldap_dn2domain(\"%s\")\n"
- "\t= \"%s\"\n", strin, tmp );
+ "\t= \"%s\"\n", strin, tmp ? tmp : "" );
}
ldap_memfree( tmp );
tmp = ldap_dn2ufn( strin );
fprintf( stdout, "\nldap_dn2ufn(\"%s\")\n"
- "\t= \"%s\"\n", strin, tmp );
+ "\t= \"%s\"\n", strin, tmp ? tmp : "" );
ldap_memfree( tmp );
tmp = ldap_dn2dcedn( strin );
fprintf( stdout, "\nldap_dn2dcedn(\"%s\")\n"
- "\t= \"%s\"\n", strin, tmp );
+ "\t= \"%s\"\n", strin, tmp ? tmp : "" );
tmp2 = ldap_dcedn2dn( tmp );
fprintf( stdout, "\nldap_dcedn2dn(\"%s\")\n"
- "\t= \"%s\"\n", tmp, tmp2 );
+ "\t= \"%s\"\n",
+ tmp ? tmp : "", tmp2 ? tmp2 : "" );
ldap_memfree( tmp );
ldap_memfree( tmp2 );
tmp = ldap_dn2ad_canonical( strin );
fprintf( stdout, "\nldap_dn2ad_canonical(\"%s\")\n"
- "\t= \"%s\"\n", strin, tmp );
+ "\t= \"%s\"\n", strin, tmp ? tmp : "" );
ldap_memfree( tmp );
fprintf( stdout, "\nldap_explode_dn(\"%s\"):\n", str );
* interpretation of the specs).
*/
-#define TK_NOENDQUOTE -2
-#define TK_OUTOFMEM -1
-#define TK_EOS 0
-#define TK_UNEXPCHAR 1
-#define TK_BAREWORD 2
-#define TK_QDSTRING 3
-#define TK_LEFTPAREN 4
-#define TK_RIGHTPAREN 5
-#define TK_DOLLAR 6
-#define TK_QDESCR TK_QDSTRING
-
-static int
+typedef enum tk_t {
+ TK_NOENDQUOTE = -2,
+ TK_OUTOFMEM = -1,
+ TK_EOS = 0,
+ TK_UNEXPCHAR = 1,
+ TK_BAREWORD = 2,
+ TK_QDSTRING = 3,
+ TK_LEFTPAREN = 4,
+ TK_RIGHTPAREN = 5,
+ TK_DOLLAR = 6,
+ TK_QDESCR = TK_QDSTRING
+} tk_t;
+
+static tk_t
get_token( const char ** sp, char ** token_val )
{
- int kind;
+ tk_t kind;
const char * p;
const char * q;
char * res;
{
char ** res;
char ** res1;
- int kind;
+ tk_t kind;
char * sval;
int size;
int pos;
parse_woid(const char **sp, int *code)
{
char * sval;
- int kind;
+ tk_t kind;
parse_whsp(sp);
kind = get_token(sp, &sval);
/* Parse a noidlen */
static char *
-parse_noidlen(const char **sp, int *code, int *len, int allow_quoted)
+parse_noidlen(const char **sp, int *code, int *len, int flags)
{
char * sval;
+ const char *savepos;
int quoted = 0;
+ int allow_quoted = ( flags & LDAP_SCHEMA_ALLOW_QUOTED );
+ int allow_oidmacro = ( flags & LDAP_SCHEMA_ALLOW_OID_MACRO );
*len = 0;
/* Netscape puts the SYNTAX value in quotes (incorrectly) */
quoted = 1;
(*sp)++;
}
+ savepos = *sp;
sval = ldap_int_parse_numericoid(sp, code, 0);
if ( !sval ) {
- return NULL;
+ if ( allow_oidmacro
+ && *sp == savepos
+ && *code == LDAP_SCHERR_NODIGIT )
+ {
+ if ( get_token(sp, &sval) != TK_BAREWORD ) {
+ if ( sval != NULL ) {
+ LDAP_FREE(sval);
+ }
+ return NULL;
+ }
+ } else {
+ return NULL;
+ }
}
if ( **sp == '{' /*}*/ ) {
(*sp)++;
{
char ** res;
char ** res1;
- int kind;
+ tk_t kind;
char * sval;
int size;
int pos;
LDAP_CONST char ** errp,
LDAP_CONST unsigned flags )
{
- int kind;
+ tk_t kind;
const char * ss = s;
char * sval;
int seen_name = 0;
LDAP_CONST char ** errp,
LDAP_CONST unsigned flags )
{
- int kind;
+ tk_t kind;
const char * ss = s;
char * sval;
int seen_name = 0;
LDAP_CONST char ** errp,
LDAP_CONST unsigned flags )
{
- int kind;
+ tk_t kind;
const char * ss = s;
char * sval;
int seen_name = 0;
LDAP_CONST char ** errp,
LDAP_CONST unsigned flags )
{
- int kind;
+ tk_t kind;
const char * ss = s;
char * sval;
int seen_name = 0;
LDAP_CONST char ** errp,
LDAP_CONST unsigned flags )
{
- int kind;
+ tk_t kind;
const char * ss = s;
char * sval;
int seen_name = 0;
}
}
LDAP_FREE(sval);
+ *code = 0;
} else {
*errp = ss;
ldap_objectclass_free(oc);
ldap_objectclass_free(oc);
return NULL;
}
+ *code = 0;
} else if ( !strcasecmp(sval,"ABSTRACT") ) {
LDAP_FREE(sval);
if ( seen_kind ) {
ldap_objectclass_free(oc);
return NULL;
}
+ *code = 0;
parse_whsp(&ss);
} else if ( !strcasecmp(sval,"MAY") ) {
LDAP_FREE(sval);
ldap_objectclass_free(oc);
return NULL;
}
+ *code = 0;
parse_whsp(&ss);
} else if ( sval[0] == 'X' && sval[1] == '-' ) {
/* Should be parse_qdstrings */
ext_vals = parse_qdescrs(&ss, code);
+ *code = 0;
if ( !ext_vals ) {
*errp = ss;
ldap_objectclass_free(oc);
LDAP_CONST char ** errp,
LDAP_CONST unsigned flags )
{
- int kind;
+ tk_t kind;
const char * ss = s;
char * sval;
int seen_name = 0;
LDAP_CONST char ** errp,
LDAP_CONST unsigned flags )
{
- int kind, ret;
+ tk_t kind;
+ int ret;
const char * ss = s;
char * sval;
int seen_name = 0;
LDAP_CONST char ** errp,
LDAP_CONST unsigned flags )
{
- int kind;
+ tk_t kind;
const char * ss = s;
char * sval;
int seen_name = 0;
* both match "subtree" */
switch ( asserted_scope ) {
case SLAP_ACI_SCOPE_ENTRY:
- /* TODO: use ber_bvcmp */
- if ( ber_bvstrcasecmp( &scope, &aci_bv[ ACI_BV_ENTRY ] ) != 0
+ if ( ber_bvcmp( &scope, &aci_bv[ ACI_BV_ENTRY ] ) != 0
&& ber_bvstrcasecmp( &scope, &aci_bv[ ACI_BV_SUBTREE ] ) != 0 )
{
return 0;
break;
case SLAP_ACI_SCOPE_CHILDREN:
- /* TODO: use ber_bvcmp */
- if ( ber_bvstrcasecmp( &scope, &aci_bv[ ACI_BV_CHILDREN ] ) != 0
+ if ( ber_bvcmp( &scope, &aci_bv[ ACI_BV_CHILDREN ] ) != 0
&& ber_bvstrcasecmp( &scope, &aci_bv[ ACI_BV_SUBTREE ] ) != 0 )
{
return 0;
}
break;
- default:
- /* TODO: add assertion */
+ case SLAP_ACI_SCOPE_SUBTREE:
+ /* TODO: add assertion? */
return 0;
}
/* get the list of permissions clauses, bail if empty */
if ( acl_get_part( aci, 2, '#', &perms ) <= 0 ) {
- /* TODO: add assertion */
+ assert( 0 );
return 0;
}
/* see if we have a DN match */
if ( acl_get_part( aci, 3, '#', &type ) < 0 ) {
- /* TODO: add assertion */
+ assert( 0 );
return 0;
}
/* see if we have a public (i.e. anonymous) access */
- /* TODO: use ber_bvcmp */
- if ( ber_bvstrcasecmp( &aci_bv[ ACI_BV_PUBLIC ], &type ) == 0 ) {
+ if ( ber_bvcmp( &aci_bv[ ACI_BV_PUBLIC ], &type ) == 0 ) {
return 1;
}
}
/* see if we have a users access */
- /* TODO: use ber_bvcmp */
- if ( ber_bvstrcasecmp( &aci_bv[ ACI_BV_USERS ], &type ) == 0 ) {
+ if ( ber_bvcmp( &aci_bv[ ACI_BV_USERS ], &type ) == 0 ) {
return 1;
}
sdn.bv_val = type.bv_val + type.bv_len + STRLENOF( "#" );
sdn.bv_len = aci->bv_len - ( sdn.bv_val - aci->bv_val );
- /* TODO: use ber_bvcmp */
- if ( ber_bvstrcasecmp( &aci_bv[ ACI_BV_ACCESS_ID ], &type ) == 0 ) {
- struct berval ndn;
-
- /* TODO: don't normalize */
- rc = dnNormalize( 0, NULL, NULL, &sdn, &ndn, op->o_tmpmemctx );
- if ( rc != LDAP_SUCCESS ) {
- return 0;
- }
-
- if ( dn_match( &op->o_ndn, &ndn ) ) {
- rc = 1;
- }
- slap_sl_free( ndn.bv_val, op->o_tmpmemctx );
-
- return rc;
-
- /* TODO: use ber_bvcmp */
- } else if ( ber_bvstrcasecmp( &aci_bv[ ACI_BV_SUBTREE ], &type ) == 0 ) {
- struct berval ndn;
-
- /* TODO: don't normalize */
- rc = dnNormalize( 0, NULL, NULL, &sdn, &ndn, op->o_tmpmemctx );
- if ( rc != LDAP_SUCCESS ) {
- return 0;
- }
-
- if ( dnIsSuffix( &op->o_ndn, &ndn ) ) {
- rc = 1;
- }
- slap_sl_free( ndn.bv_val, op->o_tmpmemctx );
-
- return rc;
-
- /* TODO: use ber_bvcmp */
- } else if ( ber_bvstrcasecmp( &aci_bv[ ACI_BV_ONELEVEL ], &type ) == 0 ) {
- struct berval ndn, pndn;
-
- /* TODO: don't normalize */
- rc = dnNormalize( 0, NULL, NULL, &sdn, &ndn, op->o_tmpmemctx );
- if ( rc != LDAP_SUCCESS ) {
- return 0;
- }
-
- dnParent( &ndn, &pndn );
-
- if ( dn_match( &op->o_ndn, &pndn ) ) {
- rc = 1;
- }
- slap_sl_free( ndn.bv_val, op->o_tmpmemctx );
+ if ( ber_bvcmp( &aci_bv[ ACI_BV_ACCESS_ID ], &type ) == 0 ) {
+ return dn_match( &op->o_ndn, &sdn );
- return rc;
+ } else if ( ber_bvcmp( &aci_bv[ ACI_BV_SUBTREE ], &type ) == 0 ) {
+ return dnIsSuffix( &op->o_ndn, &sdn );
- /* TODO: use ber_bvcmp */
- } else if ( ber_bvstrcasecmp( &aci_bv[ ACI_BV_CHILDREN ], &type ) == 0 ) {
- struct berval ndn;
+ } else if ( ber_bvcmp( &aci_bv[ ACI_BV_ONELEVEL ], &type ) == 0 ) {
+ struct berval pdn;
- /* TODO: don't normalize */
- rc = dnNormalize( 0, NULL, NULL, &sdn, &ndn, op->o_tmpmemctx );
- if ( rc != LDAP_SUCCESS ) {
- return 0;
- }
+ dnParent( &sdn, &pdn );
- if ( !dn_match( &op->o_ndn, &ndn )
- && dnIsSuffix( &op->o_ndn, &ndn ) )
- {
- rc = 1;
- }
- slap_sl_free( ndn.bv_val, op->o_tmpmemctx );
+ return dn_match( &op->o_ndn, &pdn );
- return rc;
+ } else if ( ber_bvcmp( &aci_bv[ ACI_BV_CHILDREN ], &type ) == 0 ) {
+ return ( !dn_match( &op->o_ndn, &sdn ) && dnIsSuffix( &op->o_ndn, &sdn ) );
- /* TODO: use ber_bvcmp */
- } else if ( ber_bvstrcasecmp( &aci_bv[ ACI_BV_SELF ], &type ) == 0 ) {
- if ( dn_match( &op->o_ndn, &e->e_nname ) ) {
- return 1;
- }
+ } else if ( ber_bvcmp( &aci_bv[ ACI_BV_SELF ], &type ) == 0 ) {
+ return dn_match( &op->o_ndn, &e->e_nname );
- /* TODO: use ber_bvcmp */
- } else if ( ber_bvstrcasecmp( &aci_bv[ ACI_BV_DNATTR ], &type ) == 0 ) {
+ } else if ( ber_bvcmp( &aci_bv[ ACI_BV_DNATTR ], &type ) == 0 ) {
Attribute *at;
AttributeDescription *ad = NULL;
const char *text;
rc = slap_bv2ad( &sdn, &ad, &text );
- if ( rc != LDAP_SUCCESS ) {
- /* TODO: add assertion */
- return 0;
- }
+ assert( rc == LDAP_SUCCESS );
rc = 0;
for ( at = attrs_find( e->e_attrs, ad );
return rc;
- /* TODO: use ber_bvcmp */
- } else if ( ber_bvstrcasecmp( &aci_bv[ ACI_BV_GROUP ], &type ) == 0 ) {
+ } else if ( ber_bvcmp( &aci_bv[ ACI_BV_GROUP ], &type ) == 0 ) {
if ( aci_group_member( &sdn, &aci_bv[ ACI_BV_GROUP_CLASS ],
&aci_bv[ ACI_BV_GROUP_ATTR ], op, e, nmatch, matches ) )
{
return 1;
}
- /* TODO: use ber_bvcmp */
- } else if ( ber_bvstrcasecmp( &aci_bv[ ACI_BV_ROLE ], &type ) == 0 ) {
+ } else if ( ber_bvcmp( &aci_bv[ ACI_BV_ROLE ], &type ) == 0 ) {
if ( aci_group_member( &sdn, &aci_bv[ ACI_BV_ROLE_CLASS ],
&aci_bv[ ACI_BV_ROLE_ATTR ], op, e, nmatch, matches ) )
{
return 1;
}
- /* TODO: use ber_bvcmp */
- } else if ( ber_bvstrcasecmp( &aci_bv[ ACI_BV_SET ], &type ) == 0 ) {
+ } else if ( ber_bvcmp( &aci_bv[ ACI_BV_SET ], &type ) == 0 ) {
if ( acl_match_set( &sdn, op, e, 0 ) ) {
return 1;
}
- /* TODO: use ber_bvcmp */
- } else if ( ber_bvstrcasecmp( &aci_bv[ ACI_BV_SET_REF ], &type ) == 0 ) {
+ } else if ( ber_bvcmp( &aci_bv[ ACI_BV_SET_REF ], &type ) == 0 ) {
if ( acl_match_set( &sdn, op, e, 1 ) ) {
return 1;
}
static const struct berval *OpenLDAPaciscopes[] = {
&aci_bv[ ACI_BV_ENTRY ],
&aci_bv[ ACI_BV_CHILDREN ],
+ &aci_bv[ ACI_BV_SUBTREE ],
NULL
};
* no-user-modification operational attributes are ignored
* by ACL_WRITE checking as any found here are not provided
* by the user
+ *
+ * NOTE: but they are not ignored for ACL_MANAGE, because
+ * if we get here it means a non-root user is trying to
+ * manage data, so we need to check its privileges.
*/
- if ( access_level >= ACL_WRITE && is_at_no_user_mod( desc->ad_type )
+ if ( access_level == ACL_WRITE && is_at_no_user_mod( desc->ad_type )
&& desc != slap_schema.si_ad_entry
&& desc != slap_schema.si_ad_children )
{
assert( attr != NULL );
- if ( op && op->o_is_auth_check &&
- ( access_level == ACL_SEARCH || access_level == ACL_READ ) )
- {
- access = ACL_AUTH;
+ if ( op ) {
+ if ( op->o_is_auth_check &&
+ ( access_level == ACL_SEARCH || access_level == ACL_READ ) )
+ {
+ access = ACL_AUTH;
+
+ } else if ( get_manageDIT( op ) && access_level == ACL_WRITE &&
+ desc == slap_schema.si_ad_entry )
+ {
+ access = ACL_MANAGE;
+ }
}
if ( state ) {
assert( attr != NULL );
- if ( op && op->o_is_auth_check &&
- ( access_level == ACL_SEARCH || access_level == ACL_READ ) )
- {
- access = ACL_AUTH;
+ if ( op ) {
+ if ( op->o_is_auth_check &&
+ ( access_level == ACL_SEARCH || access_level == ACL_READ ) )
+ {
+ access = ACL_AUTH;
+
+ } else if ( get_manageDIT( op ) && access_level == ACL_WRITE &&
+ desc == slap_schema.si_ad_entry )
+ {
+ access = ACL_MANAGE;
+ }
}
if ( state ) {
* no-user-modification operational attributes are ignored
* by ACL_WRITE checking as any found here are not provided
* by the user
+ *
+ * NOTE: but they are not ignored for ACL_MANAGE, because
+ * if we get here it means a non-root user is trying to
+ * manage data, so we need to check its privileges.
*/
- if ( access_level >= ACL_WRITE && is_at_no_user_mod( desc->ad_type )
+ if ( access_level == ACL_WRITE && is_at_no_user_mod( desc->ad_type )
&& desc != slap_schema.si_ad_entry
&& desc != slap_schema.si_ad_children )
{
acl_check_modlist(
Operation *op,
Entry *e,
- Modifications *mlist
-)
+ Modifications *mlist )
{
struct berval *bv;
AccessControlState state = ACL_STATE_INIT;
* by the user
*/
if ( is_at_no_user_mod( mlist->sml_desc->ad_type )
- && !mlist->sml_managing )
+ && ! ( mlist->sml_flags & SLAP_MOD_MANAGING ) )
{
Debug( LDAP_DEBUG_ACL, "acl: no-user-mod %s:"
" modify access granted\n",
* This prevents abuse from selfwriters.
*/
if ( ! access_allowed( op, e,
- mlist->sml_desc, NULL, ACL_WDEL, &state ) )
+ mlist->sml_desc, NULL,
+ ( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WDEL,
+ &state ) )
{
ret = 0;
goto done;
bv->bv_val != NULL; bv++ )
{
if ( ! access_allowed( op, e,
- mlist->sml_desc, bv, ACL_WADD, &state ) )
+ mlist->sml_desc, bv,
+ ( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WADD,
+ &state ) )
{
ret = 0;
goto done;
case LDAP_MOD_DELETE:
if ( mlist->sml_values == NULL ) {
if ( ! access_allowed( op, e,
- mlist->sml_desc, NULL, ACL_WDEL, NULL ) )
+ mlist->sml_desc, NULL,
+ ( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WDEL,
+ NULL ) )
{
ret = 0;
goto done;
bv->bv_val != NULL; bv++ )
{
if ( ! access_allowed( op, e,
- mlist->sml_desc, bv, ACL_WDEL, &state ) )
+ mlist->sml_desc, bv,
+ ( mlist->sml_flags & SLAP_MOD_MANAGING ) ? ACL_MANAGE : ACL_WDEL,
+ &state ) )
{
ret = 0;
goto done;
"\t[peername[.<peernamestyle>]=<peer>] [sockname[.<style>]=<name>]\n"
"\t[domain[.<domainstyle>]=<domain>] [sockurl[.<style>]=<url>]\n"
#ifdef SLAPD_ACI_ENABLED
- "\t[aci=[<attrname>]]\n"
+ "\t[aci[=<attrname>]]\n"
#endif
#ifdef SLAP_DYNACL
"\t[dynacl/<name>[.<dynstyle>][=<pattern>]]\n"
continue;
}
+ if ( ber_bvccmp( &attrs->an_name, '*' ) ) {
+ if ( !is_at_operational( desc->ad_type ) ) {
+ return 1;
+ }
+ continue;
+ }
+
+ if ( ber_bvccmp( &attrs->an_name, '+' ) ) {
+ if ( is_at_operational( desc->ad_type ) ) {
+ return 1;
+ }
+ continue;
+ }
+
/*
* EXTENSION: see if requested description is @objectClass
* if so, return attributes which the class requires/allows
}
/* no subschemaSubentry */
- if ( attr->a_desc == slap_schema.si_ad_subschemaSubentry ) {
+ if ( attr->a_desc == slap_schema.si_ad_subschemaSubentry
+ || attr->a_desc == slap_schema.si_ad_entryDN )
+ {
/*
* We eat target's subschemaSubentry because
* to resolve to the appropriate backend;
* later, the local subschemaSubentry is
* added.
+ *
+ * We also eat entryDN because the frontend
+ * will reattach it without checking if already
+ * present...
*/
( void )ber_scanf( &ber, "x" /* [W] */ );
#endif
if ( initial_candidates == 0 ) {
+ /* NOTE: here we are not sending any matchedDN;
+ * this is intended, because if the back-meta
+ * is serving this search request, but no valid
+ * candidate could be looked up, it means that
+ * there is a hole in the mapping of the targets
+ * and thus no knowledge of any remote superior
+ * is available */
+ Debug( LDAP_DEBUG_ANY, "%s meta_back_search: "
+ "base=\"%s\" scope=%d: "
+ "no candidate could be selected\n",
+ op->o_log_prefix, op->o_req_dn.bv_val,
+ op->ors_scope );
+
send_ldap_error( op, rs, LDAP_NO_SUCH_OBJECT, NULL );
- /* FIXME: find a way to look up the best match */
rc = LDAP_NO_SUCH_OBJECT;
goto finish;
}
/* no subschemaSubentry */
- if ( attr->a_desc == slap_schema.si_ad_subschemaSubentry ) {
+ if ( attr->a_desc == slap_schema.si_ad_subschemaSubentry
+ || attr->a_desc == slap_schema.si_ad_entryDN )
+ {
/*
* We eat target's subschemaSubentry because
* to resolve to the appropriate backend;
* later, the local subschemaSubentry is
* added.
+ *
+ * We also eat entryDN because the frontend
+ * will reattach it without checking if already
+ * present...
*/
( void )ber_scanf( &ber, "x" /* [W] */ );
}
}
+ /* temporarily removed */
+#if 0
/* check should be generalized */
if( get_manageDIT(op) && !be_isroot(op)) {
rs->sr_text = "requires manager authorization";
rs->sr_err = LDAP_UNWILLING_TO_PERFORM;
}
+#endif
done:;
return rs->sr_err;
/* Let the overlays have a chance at this */
be_orig = op->o_bd;
op->o_bd = select_backend( &op->o_req_ndn, 0, 0 );
- if ( op->o_bd != frontendDB &&
+ if ( !be_match( op->o_bd, frontendDB ) &&
( SLAP_OPATTRS( rs->sr_attr_flags ) || rs->sr_attrs ) &&
op->o_bd != NULL && op->o_bd->be_operational != NULL )
{
goto cleanup;
}
- if( mod->sml_values[1].bv_val ) {
+ if ( !BER_BVISNULL( &mod->sml_values[ 1 ] ) ) {
Debug( LDAP_DEBUG_ANY, "do_modify: modify/increment "
"operation (%ld) requires single value\n",
(long) mop, 0, 0 );
if ( tmp->sml_values == NULL ) {
Debug( LDAP_DEBUG_ARGS, "%s\n",
"\t\tno values", NULL, NULL );
- } else if ( tmp->sml_values[0].bv_val == NULL ) {
+ } else if ( BER_BVISNULL( &tmp->sml_values[ 0 ] ) ) {
Debug( LDAP_DEBUG_ARGS, "%s\n",
"\t\tzero values", NULL, NULL );
- } else if ( tmp->sml_values[1].bv_val == NULL ) {
+ } else if ( BER_BVISNULL( &tmp->sml_values[ 1 ] ) ) {
Debug( LDAP_DEBUG_ARGS, "%s, length %ld\n",
"\t\tone value", (long) tmp->sml_values[0].bv_len, NULL );
} else {
if ( get_manageDIT( op ) ) {
if ( ml->sml_desc->ad_type->sat_flags & SLAP_AT_MANAGEABLE ) {
- ml->sml_managing = 1;
+ ml->sml_flags |= SLAP_MOD_MANAGING;
continue;
}
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
mod->sml_op = mop;
mod->sml_flags = SLAP_MOD_INTERNAL;
- mod->sml_type.bv_val = NULL;
+ BER_BVZERO( &mod->sml_type );
mod->sml_desc = slap_schema.si_ad_structuralObjectClass;
mod->sml_values =
(BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
ber_dupbv( &mod->sml_values[0], &tmpval );
- mod->sml_values[1].bv_len = 0;
- mod->sml_values[1].bv_val = NULL;
- assert( mod->sml_values[0].bv_val != NULL );
+ BER_BVZERO( &mod->sml_values[1] );
+ assert( !BER_BVISNULL( &mod->sml_values[0] ) );
mod->sml_nvalues =
(BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
ber_dupbv( &mod->sml_nvalues[0], &tmpval );
- mod->sml_nvalues[1].bv_len = 0;
- mod->sml_nvalues[1].bv_val = NULL;
- assert( mod->sml_nvalues[0].bv_val != NULL );
+ BER_BVZERO( &mod->sml_nvalues[1] );
+ assert( !BER_BVISNULL( &mod->sml_nvalues[0] ) );
*modtail = mod;
modtail = &mod->sml_next;
}
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
mod->sml_op = mop;
mod->sml_flags = SLAP_MOD_INTERNAL;
- mod->sml_type.bv_val = NULL;
+ BER_BVZERO( &mod->sml_type );
mod->sml_desc = slap_schema.si_ad_entryUUID;
mod->sml_values =
(BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
ber_dupbv( &mod->sml_values[0], &tmpval );
- mod->sml_values[1].bv_len = 0;
- mod->sml_values[1].bv_val = NULL;
- assert( mod->sml_values[0].bv_val != NULL );
+ BER_BVZERO( &mod->sml_values[1] );
+ assert( !BER_BVISNULL( &mod->sml_values[0] ) );
mod->sml_nvalues =
(BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
(*mod->sml_desc->ad_type->sat_equality->smr_normalize)(
mod->sml_desc->ad_type->sat_syntax,
mod->sml_desc->ad_type->sat_equality,
mod->sml_values, mod->sml_nvalues, NULL );
- mod->sml_nvalues[1].bv_len = 0;
- mod->sml_nvalues[1].bv_val = NULL;
+ BER_BVZERO( &mod->sml_nvalues[1] );
*modtail = mod;
modtail = &mod->sml_next;
}
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
mod->sml_op = mop;
mod->sml_flags = SLAP_MOD_INTERNAL;
- mod->sml_type.bv_val = NULL;
+ BER_BVZERO( &mod->sml_type );
mod->sml_desc = slap_schema.si_ad_creatorsName;
mod->sml_values =
(BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
ber_dupbv( &mod->sml_values[0], &name );
- mod->sml_values[1].bv_len = 0;
- mod->sml_values[1].bv_val = NULL;
- assert( mod->sml_values[0].bv_val != NULL );
+ BER_BVZERO( &mod->sml_values[1] );
+ assert( !BER_BVISNULL( &mod->sml_values[0] ) );
mod->sml_nvalues =
(BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
ber_dupbv( &mod->sml_nvalues[0], &nname );
- mod->sml_nvalues[1].bv_len = 0;
- mod->sml_nvalues[1].bv_val = NULL;
- assert( mod->sml_nvalues[0].bv_val != NULL );
+ BER_BVZERO( &mod->sml_nvalues[1] );
+ assert( !BER_BVISNULL( &mod->sml_nvalues[0] ) );
*modtail = mod;
modtail = &mod->sml_next;
}
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
mod->sml_op = mop;
mod->sml_flags = SLAP_MOD_INTERNAL;
- mod->sml_type.bv_val = NULL;
+ BER_BVZERO( &mod->sml_type );
mod->sml_desc = slap_schema.si_ad_createTimestamp;
mod->sml_values =
(BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
ber_dupbv( &mod->sml_values[0], ×tamp );
- mod->sml_values[1].bv_len = 0;
- mod->sml_values[1].bv_val = NULL;
- assert( mod->sml_values[0].bv_val != NULL );
+ BER_BVZERO( &mod->sml_values[1] );
+ assert( !BER_BVISNULL( &mod->sml_values[0] ) );
mod->sml_nvalues = NULL;
*modtail = mod;
modtail = &mod->sml_next;
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
mod->sml_op = mop;
mod->sml_flags = SLAP_MOD_INTERNAL;
- mod->sml_type.bv_val = NULL;
+ BER_BVZERO( &mod->sml_type );
mod->sml_desc = slap_schema.si_ad_entryCSN;
mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
ber_dupbv( &mod->sml_values[0], &csn );
- mod->sml_values[1].bv_len = 0;
- mod->sml_values[1].bv_val = NULL;
- assert( mod->sml_values[0].bv_val != NULL );
+ BER_BVZERO( &mod->sml_values[1] );
+ assert( !BER_BVISNULL( &mod->sml_values[0] ) );
mod->sml_nvalues = NULL;
*modtail = mod;
modtail = &mod->sml_next;
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
mod->sml_op = mop;
mod->sml_flags = SLAP_MOD_INTERNAL;
- mod->sml_type.bv_val = NULL;
+ BER_BVZERO( &mod->sml_type );
mod->sml_desc = slap_schema.si_ad_modifiersName;
mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
ber_dupbv( &mod->sml_values[0], &name );
- mod->sml_values[1].bv_len = 0;
- mod->sml_values[1].bv_val = NULL;
- assert( mod->sml_values[0].bv_val != NULL );
+ BER_BVZERO( &mod->sml_values[1] );
+ assert( !BER_BVISNULL( &mod->sml_values[0] ) );
mod->sml_nvalues =
(BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
ber_dupbv( &mod->sml_nvalues[0], &nname );
- mod->sml_nvalues[1].bv_len = 0;
- mod->sml_nvalues[1].bv_val = NULL;
- assert( mod->sml_nvalues[0].bv_val != NULL );
+ BER_BVZERO( &mod->sml_nvalues[1] );
+ assert( !BER_BVISNULL( &mod->sml_nvalues[0] ) );
*modtail = mod;
modtail = &mod->sml_next;
}
mod = (Modifications *) ch_malloc( sizeof( Modifications ) );
mod->sml_op = mop;
mod->sml_flags = SLAP_MOD_INTERNAL;
- mod->sml_type.bv_val = NULL;
+ BER_BVZERO( &mod->sml_type );
mod->sml_desc = slap_schema.si_ad_modifyTimestamp;
mod->sml_values = (BerVarray) ch_malloc( 2 * sizeof( struct berval ) );
ber_dupbv( &mod->sml_values[0], ×tamp );
- mod->sml_values[1].bv_len = 0;
- mod->sml_values[1].bv_val = NULL;
- assert( mod->sml_values[0].bv_val != NULL );
+ BER_BVZERO( &mod->sml_values[1] );
+ assert( !BER_BVISNULL( &mod->sml_values[0] ) );
mod->sml_nvalues = NULL;
*modtail = mod;
modtail = &mod->sml_next;
{
slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
+ /* Reset lockout status on all Bind requests */
+ pwcons[op->o_conn->c_conn_idx].restricted = 0;
+
/* Root bypasses policy */
if ( !be_isroot_dn( op->o_bd, &op->o_req_ndn )) {
Entry *e;
/*
* backend.c
*/
+
+#define be_match( be1, be2 ) ( (be1) == (be2) || \
+ ( (be1) && (be2) && (be1)->be_nsuffix == (be2)->be_nsuffix ) )
+
LDAP_SLAPD_F (int) backend_init LDAP_P((void));
LDAP_SLAPD_F (int) backend_add LDAP_P((BackendInfo *aBackendInfo));
LDAP_SLAPD_F (int) backend_num LDAP_P((Backend *be));
};
static AttributeType slap_at_undefined = {
- { "1.1.1", NULL, NULL, 1, NULL,
+ { "1.1.1", NULL, "Catchall for undefined attribute types", 1, NULL,
NULL, NULL, NULL, NULL,
- 0, 0, 0, 1, 3, NULL }, /* LDAPAttributeType */
+ 0, 0, 0, 1, LDAP_SCHEMA_DSA_OPERATION, NULL }, /* LDAPAttributeType */
BER_BVC("UNDEFINED"), /* cname */
NULL, /* sup */
NULL, /* subtypes */
* running as non-root user, for user modifiable attributes.
*/
#define SLAP_MOD_INTERNAL 0x01
+#define SLAP_MOD_MANAGING 0x02
AttributeDescription *sm_desc;
struct berval sm_type;
#define sml_type sml_mod.sm_type
#define sml_values sml_mod.sm_values
#define sml_nvalues sml_mod.sm_nvalues
- char sml_managing;
struct slap_mod_list *sml_next;
} Modifications;
exit( EXIT_FAILURE );
}
+#ifdef SLAP_DYNACL
+ if ( acl_init() ) {
+ fprintf( stderr, "%s: acl_init failed!\n", progname );
+ exit( EXIT_FAILURE );
+ }
+#endif /* SLAP_DYNACL */
+
rc = read_config( conffile, confdir );
if ( rc != 0 ) {
PBLOCK_ASSERT_OP( pb, 0 );
op = pb->pb_op;
- if ( op->o_bd != frontendDB ) {
+ if ( !be_match( op->o_bd, frontendDB ) ) {
rc = slapi_int_call_plugins( frontendDB, type, pb );
}
if ( rc >= 0 ) {
retcode-item "cn=strongerAuthRequired" 0x08 text="same as strongAuthRequired"
#retcode-item "cn=partialResults" 0x09 "LDAPv2+ (not LDAPv3)"
-retcode-item "cn=referral" 0x0a text="LDAPv3"
+retcode-item "cn=referral" 0x0a text="LDAPv3" ref="ldap://:9010"
retcode-item "cn=adminLimitExceeded" 0x0b text="LDAPv3"
retcode-item "cn=unavailableCriticalExtension" 0x0c text="LDAPv3"
retcode-item "cn=confidentialityRequired" 0x0d text="LDAPv3"
--- /dev/null
+# Searching all database (after add)...
+dn: ou=Another parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Another parent
+
+dn: ou=Child,ou=Parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Child
+
+dn: dc=example,dc=com
+objectClass: organization
+objectClass: dcObject
+o: Example, Inc.
+dc: example
+
+dn: ou=Grandchild,ou=Child,ou=Parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Grandchild
+
+dn: ou=Parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Parent
+
+# Searching all database (after PASS1)...
+dn: ou=Another parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Another parent
+
+dn: dc=example,dc=com
+objectClass: organization
+objectClass: dcObject
+o: Example, Inc.
+dc: example
+
+dn: ou=Grandchild,ou=Renamed child,ou=Parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Grandchild
+
+dn: ou=Parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Parent
+
+dn: ou=Renamed child,ou=Parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Child
+ou: Renamed child
+
+# Searching all database (after PASS2)...
+dn: ou=Another parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Another parent
+
+dn: dc=example,dc=com
+objectClass: organization
+objectClass: dcObject
+o: Example, Inc.
+dc: example
+
+dn: ou=Grandchild,ou=Renamed child,ou=Renamed parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Grandchild
+
+dn: ou=Renamed child,ou=Renamed parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Child
+ou: Renamed child
+
+dn: ou=Renamed parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Parent
+ou: Renamed parent
+
+# Searching all database (after PASS3)...
+dn: ou=Another parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Another parent
+
+dn: dc=example,dc=com
+objectClass: organization
+objectClass: dcObject
+o: Example, Inc.
+dc: example
+
+dn: ou=Grandchild,ou=Renamed child,ou=Another parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Grandchild
+
+dn: ou=Renamed child,ou=Another parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Child
+ou: Renamed child
+
+dn: ou=Renamed parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Parent
+ou: Renamed parent
+
static void
do_addel( char *uri, char *host, int port, char *manager, char *passwd,
- char *dn, LDAPMod **attrs, int maxloop, int maxretries );
+ char *dn, LDAPMod **attrs, int maxloop, int maxretries, int delay );
static void
usage( char *name )
{
- fprintf( stderr, "usage: %s [-h <host>] -p port -D <managerDN> -w <passwd> -f <addfile> [-l <loops>]\n",
+ fprintf( stderr,
+ "usage: %s "
+ "-H <uri> | ([-h <host>] -p <port>) "
+ "-D <manager> "
+ "-w <passwd> "
+ "-f <addfile> "
+ "[-l <loops>] "
+ "[-r <maxretries>] "
+ "[-t <delay>]\n",
name );
exit( EXIT_FAILURE );
}
char *entry = NULL;
int loops = LOOPS;
int retries = RETRIES;
+ int delay = 0;
LDAPMod **attrs = NULL;
- while ( (i = getopt( argc, argv, "H:h:p:D:w:f:l:r:" )) != EOF ) {
+ while ( (i = getopt( argc, argv, "H:h:p:D:w:f:l:r:t:" )) != EOF ) {
switch( i ) {
case 'H': /* the server's URI */
uri = strdup( optarg );
loops = atoi( optarg );
break;
- case 'r':
+ case 'r': /* number of retries */
retries = atoi( optarg );
break;
+ case 't': /* delay in seconds */
+ delay = atoi( optarg );
+ break;
+
default:
usage( argv[0] );
break;
}
do_addel( uri, host, port, manager, passwd, entry, attrs,
- loops, retries );
+ loops, retries, delay );
exit( EXIT_SUCCESS );
}
char *entry,
LDAPMod **attrs,
int maxloop,
- int maxretries
+ int maxretries,
+ int delay
)
{
LDAP *ld = NULL;
switch ( rc ) {
case LDAP_BUSY:
case LDAP_UNAVAILABLE:
- if ( do_retry == 1 ) {
- do_retry = 0;
- sleep( 1 );
+ if ( do_retry > 0 ) {
+ do_retry--;
+ if ( delay != 0 ) {
+ sleep( delay );
+ }
goto retry;
}
/* fallthru */
static void
do_modify( char *uri, char *host, int port, char *manager, char *passwd,
char *entry, char *attr, char *value, int maxloop,
- int maxretries );
+ int maxretries, int delay );
static void
usage( char *name )
{
- fprintf( stderr, "usage: %s [-h <host>] -p port -D <managerDN> -w <passwd> -e <entry> [-l <loops>]\n",
+ fprintf( stderr,
+ "usage: %s "
+ "-H <uri> | ([-h <host>] -p <port>) "
+ "-D <manager> "
+ "-w <passwd> "
+ "-e <entry> "
+ "[-l <loops>] "
+ "[-r <maxretries>] "
+ "[-t <delay>]\n",
name );
exit( EXIT_FAILURE );
}
char *value = NULL;
int loops = LOOPS;
int retries = RETRIES;
+ int delay = 0;
- while ( (i = getopt( argc, argv, "H:h:p:D:w:e:a:l:r:" )) != EOF ) {
+ while ( (i = getopt( argc, argv, "H:h:p:D:w:e:a:l:r:t:" )) != EOF ) {
switch( i ) {
case 'H': /* the server uri */
uri = strdup( optarg );
loops = atoi( optarg );
break;
- case 'r':
+ case 'r': /* number of retries */
retries = atoi( optarg );
break;
+ case 't': /* delay in seconds */
+ delay = atoi( optarg );
+ break;
+
default:
usage( argv[0] );
break;
value++;
do_modify( uri, host, port, manager, passwd, entry, ava, value,
- loops, retries );
+ loops, retries, delay );
exit( EXIT_SUCCESS );
}
static void
do_modify( char *uri, char *host, int port, char *manager,
char *passwd, char *entry, char* attr, char* value,
- int maxloop, int maxretries )
+ int maxloop, int maxretries, int delay )
{
LDAP *ld = NULL;
int i = 0, do_retry = maxretries;
switch ( rc ) {
case LDAP_BUSY:
case LDAP_UNAVAILABLE:
- if ( do_retry == 1 ) {
- do_retry = 0;
- sleep( 1 );
+ if ( do_retry > 0 ) {
+ do_retry--;
+ if ( delay > 0 ) {
+ sleep( delay );
+ }
goto retry;
}
/* fallthru */
static void
do_modrdn( char *uri, char *host, int port, char *manager, char *passwd,
- char *entry, int maxloop, int maxretries );
+ char *entry, int maxloop, int maxretries, int delay );
static void
usage( char *name )
{
- fprintf( stderr, "usage: %s [-h <host>] -p port -D <managerDN> -w <passwd> -e <entry> [-l <loops>]\n",
+ fprintf( stderr,
+ "usage: %s "
+ "-H <uri> | ([-h <host>] -p <port>) "
+ "-D <manager> "
+ "-w <passwd> "
+ "-e <entry> "
+ "[-l <loops>] "
+ "[-r <maxretries>] "
+ "[-t <delay>]\n",
name );
exit( EXIT_FAILURE );
}
char *entry = NULL;
int loops = LOOPS;
int retries = RETRIES;
+ int delay = 0;
- while ( (i = getopt( argc, argv, "H:h:p:D:w:e:l:r:" )) != EOF ) {
+ while ( (i = getopt( argc, argv, "H:h:p:D:w:e:l:r:t:" )) != EOF ) {
switch( i ) {
case 'H': /* the server uri */
uri = strdup( optarg );
retries = atoi( optarg );
break;
+ case 't': /* delay in seconds */
+ delay = atoi( optarg );
+ break;
+
default:
usage( argv[0] );
break;
}
- do_modrdn( uri, host, port, manager, passwd, entry, loops, retries );
+ do_modrdn( uri, host, port, manager, passwd, entry, loops, retries, delay );
exit( EXIT_SUCCESS );
}
static void
do_modrdn( char *uri, char *host, int port, char *manager,
- char *passwd, char *entry, int maxloop, int maxretries )
+ char *passwd, char *entry, int maxloop, int maxretries, int delay )
{
LDAP *ld = NULL;
int i = 0, do_retry = maxretries;
switch ( rc ) {
case LDAP_BUSY:
case LDAP_UNAVAILABLE:
- if ( do_retry == 1 ) {
- do_retry = 0;
- sleep( 1 );
+ if ( do_retry > 0 ) {
+ do_retry--;
+ if ( delay > 0) {
+ sleep( delay );
+ }
goto retry;
}
/* fallthru */
static void
do_read( char *uri, char *host, int port, char *entry, int maxloop,
- int maxretries );
+ int maxretries, int delay );
static void
usage( char *name )
{
- fprintf( stderr, "usage: %s [-h <host>] -p port -e <entry> [-l <loops>]\n",
+ fprintf( stderr,
+ "usage: %s "
+ "-H <uri> | ([-h <host>] -p <port>) "
+ "-e <entry> "
+ "[-l <loops>] "
+ "[-r <maxretries>] "
+ "[-t <delay>]\n",
name );
exit( EXIT_FAILURE );
}
char *entry = NULL;
int loops = LOOPS;
int retries = RETRIES;
+ int delay = 0;
- while ( (i = getopt( argc, argv, "H:h:p:e:l:r:" )) != EOF ) {
+ while ( (i = getopt( argc, argv, "H:h:p:e:l:r:t:" )) != EOF ) {
switch( i ) {
case 'H': /* the server uri */
uri = strdup( optarg );
retries = atoi( optarg );
break;
+ case 't': /* delay in seconds */
+ delay = atoi( optarg );
+ break;
+
default:
usage( argv[0] );
break;
exit( EXIT_FAILURE );
}
- do_read( uri, host, port, entry, ( 20 * loops ), retries );
+ do_read( uri, host, port, entry, ( 20 * loops ), retries, delay );
exit( EXIT_SUCCESS );
}
static void
do_read( char *uri, char *host, int port, char *entry, int maxloop,
- int maxretries )
+ int maxretries, int delay )
{
LDAP *ld = NULL;
int i = 0, do_retry = maxretries;
switch ( rc ) {
case LDAP_BUSY:
case LDAP_UNAVAILABLE:
- if ( do_retry == 1 ) {
- do_retry = 0;
- sleep( 1 );
+ if ( do_retry > 0 ) {
+ do_retry--;
+ if ( delay > 0 ) {
+ sleep( delay );
+ }
goto retry;
}
/* fallthru */
static void
do_search( char *uri, char *host, int port, char *manager, char *passwd,
- char *sbase, char *filter, int maxloop, int maxretries );
+ char *sbase, char *filter, int maxloop, int maxretries, int delay );
static void
usage( char *name )
{
- fprintf( stderr, "usage: %s [-h <host>] -p port -b <searchbase> -f <searchfiter> [-l <loops>]\n",
+ fprintf( stderr,
+ "usage: %s "
+ "-H <uri> | ([-h <host>] -p <port>) "
+ "-D <manager> "
+ "-w <passwd> "
+ "-b <searchbase> "
+ "-f <searchfilter> "
+ "[-l <loops>] "
+ "[-r <maxretries>] "
+ "[-t <delay>]\n",
name );
exit( EXIT_FAILURE );
}
char *filter = NULL;
int loops = LOOPS;
int retries = RETRIES;
+ int delay = 0;
- while ( (i = getopt( argc, argv, "b:D:f:H:h:l:p:w:r:" )) != EOF ) {
+ while ( (i = getopt( argc, argv, "b:D:f:H:h:l:p:w:r:t:" )) != EOF ) {
switch( i ) {
case 'H': /* the server uri */
uri = strdup( optarg );
retries = atoi( optarg );
break;
+ case 't': /* delay in seconds */
+ delay = atoi( optarg );
+ break;
+
default:
usage( argv[0] );
break;
}
do_search( uri, host, port, manager, passwd, sbase, filter,
- ( 10 * loops ), retries );
+ ( 10 * loops ), retries, delay );
exit( EXIT_SUCCESS );
}
static void
do_search( char *uri, char *host, int port, char *manager, char *passwd,
- char *sbase, char *filter, int maxloop, int maxretries )
+ char *sbase, char *filter, int maxloop, int maxretries, int delay )
{
LDAP *ld = NULL;
int i = 0, do_retry = maxretries;
case LDAP_UNAVAILABLE:
if ( do_retry > 0 ) {
do_retry--;
- sleep( 1 );
+ if ( delay != 0 ) {
+ sleep( delay );
+ }
goto retry;
}
/* fallthru */
ldap_unbind( ld );
}
-
-
"[-j <maxchild>] "
"[-l <loops>] "
"-P <progdir> "
- "[-r <maxretries>]\n",
+ "[-r <maxretries>]"
+ "[-t <delay>]\n",
name );
exit( EXIT_FAILURE );
}
char *progdir = NULL;
char *loops = LOOPS;
char *retries = RETRIES;
+ char *delay = "0";
DIR *datadir;
struct dirent *file;
char *sfile = NULL;
char *moddn[MAXREQS];
int modnum = 0;
- while ( (i = getopt( argc, argv, "D:d:H:h:j:l:P:p:r:w:" )) != EOF ) {
+ while ( (i = getopt( argc, argv, "D:d:H:h:j:l:P:p:r:t:w:" )) != EOF ) {
switch( i ) {
case 'D': /* slapd manager */
manager = ArgDup( optarg );
port = strdup( optarg );
break;
- case 'r':
+ case 'r': /* the number of retries in case of error */
retries = strdup( optarg );
break;
+ case 't': /* the delay in seconds between each retry */
+ delay = strdup( optarg );
+ break;
+
case 'w': /* the managers passwd */
passwd = ArgDup( optarg );
break;
sargs[sanum++] = loops;
sargs[sanum++] = "-r";
sargs[sanum++] = retries;
+ sargs[sanum++] = "-t";
+ sargs[sanum++] = delay;
sargs[sanum++] = "-b";
sargs[sanum++] = NULL; /* will hold the search base */
sargs[sanum++] = "-f";
rargs[ranum++] = loops;
rargs[ranum++] = "-r";
rargs[ranum++] = retries;
+ rargs[ranum++] = "-t";
+ rargs[ranum++] = delay;
rargs[ranum++] = "-e";
rargs[ranum++] = NULL; /* will hold the read entry */
rargs[ranum++] = NULL;
margs[manum++] = loops;
margs[manum++] = "-r";
margs[manum++] = retries;
+ margs[manum++] = "-t";
+ margs[manum++] = delay;
margs[manum++] = "-e";
margs[manum++] = NULL; /* will hold the modrdn entry */
margs[manum++] = NULL;
modargs[modanum++] = loops;
modargs[modanum++] = "-r";
modargs[modanum++] = retries;
+ modargs[modanum++] = "-t";
+ modargs[modanum++] = delay;
modargs[modanum++] = "-e";
modargs[modanum++] = NULL; /* will hold the modify entry */
modargs[modanum++] = "-a";;
aargs[aanum++] = loops;
aargs[aanum++] = "-r";
aargs[aanum++] = retries;
+ aargs[aanum++] = "-t";
+ aargs[aanum++] = delay;
aargs[aanum++] = "-f";
aargs[aanum++] = NULL; /* will hold the add data file */
aargs[aanum++] = NULL;
METAOUT=$DATADIR/meta.out
METACONCURRENCYOUT=$DATADIR/metaconcurrency.out
MANAGEOUT=$DATADIR/manage.out
+SUBTREERENAMEOUT=$DATADIR/subtree-rename.out
# Just in case we linked the binaries dynamically
LD_LIBRARY_PATH=`pwd`/../libraries:${LD_LIBRARY_PATH} export LD_LIBRARY_PATH
--- /dev/null
+#! /bin/sh
+# $OpenLDAP$ */
+## This work is part of OpenLDAP Software <http://www.openldap.org/>.
+##
+## Copyright 1998-2005 The OpenLDAP Foundation.
+## All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted only as authorized by the OpenLDAP
+## Public License.
+##
+## A copy of this license is available in the file LICENSE in the
+## top-level directory of the distribution or, alternatively, at
+## <http://www.OpenLDAP.org/license.html>.
+
+echo "running defines.sh"
+. $SRCDIR/scripts/defines.sh
+
+case $BACKEND in
+hdb)
+ ;;
+*)
+ echo "subtree rename not supported by back-$BACKEND"
+ exit 0
+esac
+
+mkdir -p $TESTDIR $DBDIR1
+
+echo "Starting slapd on TCP/IP port $PORT1..."
+. $CONFFILTER $BACKEND $MONITORDB < $CONF > $CONF1
+$SLAPD -f $CONF1 -h $URI1 -d $LVL $TIMING > $LOG1 2>&1 &
+PID=$!
+if test $WAIT != 0 ; then
+ echo PID $PID
+ read foo
+fi
+KILLPIDS="$PID"
+
+echo "Testing slapd searching..."
+for i in 0 1 2 3 4 5; do
+ $LDAPSEARCH -s base -b "$MONITOR" -h $LOCALHOST -p $PORT1 \
+ '(objectclass=*)' > /dev/null 2>&1
+ RC=$?
+ if test $RC = 0 ; then
+ break
+ fi
+ echo "Waiting 5 seconds for slapd to start..."
+ sleep 5
+done
+
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+cat /dev/null > $TESTOUT
+cat /dev/null > $SEARCHOUT
+
+# Add
+echo "Populating the database..."
+echo "# Populating the database..." >> $TESTOUT
+$LDAPADD -v -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD \
+ >> $TESTOUT 2>&1 << EOMODS0
+dn: dc=example,dc=com
+objectClass: organization
+objectClass: dcObject
+o: Example, Inc.
+dc: example
+
+dn: ou=Parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Parent
+
+dn: ou=Another parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Another parent
+
+dn: ou=Child,ou=Parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Child
+
+dn: ou=Grandchild,ou=Child,ou=Parent,dc=example,dc=com
+objectClass: organizationalUnit
+ou: Grandchild
+EOMODS0
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapadd failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Searching all database..."
+echo "# Searching all database (after add)..." >> $SEARCHOUT
+$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \
+ '(objectClass=*)' >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+# Rename (PASS1)
+echo "Renaming (PASS1)..."
+echo "# Renaming (PASS1)..." >> $TESTOUT
+$LDAPMODIFY -v -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD \
+ >> $TESTOUT 2>&1 << EOMODS1
+dn: ou=Child,ou=Parent,dc=example,dc=com
+changetype: modrdn
+newrdn: ou=Renamed child
+deleteoldrdn: 0
+EOMODS1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapadd failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Searching all database..."
+echo "# Searching all database (after PASS1)..." >> $SEARCHOUT
+$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \
+ '(objectClass=*)' >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+# Rename (PASS2)
+echo "Renaming (PASS2)..."
+echo "# Renaming (PASS2)..." >> $TESTOUT
+$LDAPMODIFY -v -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD \
+ >> $TESTOUT 2>&1 << EOMODS2
+dn: ou=Parent,dc=example,dc=com
+changetype: modrdn
+newrdn: ou=Renamed parent
+deleteoldrdn: 0
+EOMODS2
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapadd failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Searching all database..."
+echo "# Searching all database (after PASS2)..." >> $SEARCHOUT
+$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \
+ '(objectClass=*)' >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+# Rename (PASS3)
+echo "Renaming (PASS3)..."
+echo "# Renaming (PASS3)..." >> $TESTOUT
+$LDAPMODIFY -v -D "$MANAGERDN" -h $LOCALHOST -p $PORT1 -w $PASSWD \
+ >> $TESTOUT 2>&1 << EOMODS3
+dn: ou=Renamed child,ou=Renamed parent,dc=example,dc=com
+changetype: modrdn
+newrdn: ou=Renamed child
+deleteoldrdn: 0
+newsuperior: ou=Another parent,dc=example,dc=com
+EOMODS3
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapadd failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+echo "Searching all database..."
+echo "# Searching all database (after PASS3)..." >> $SEARCHOUT
+$LDAPSEARCH -S "" -b "$BASEDN" -h $LOCALHOST -p $PORT1 \
+ '(objectClass=*)' >> $SEARCHOUT 2>&1
+RC=$?
+if test $RC != 0 ; then
+ echo "ldapsearch failed ($RC)!"
+ test $KILLSERVERS != no && kill -HUP $KILLPIDS
+ exit $RC
+fi
+
+test $KILLSERVERS != no && kill -HUP $KILLPIDS
+
+LDIF=$SUBTREERENAMEOUT
+
+echo "Filtering ldapsearch results..."
+. $LDIFFILTER < $SEARCHOUT > $SEARCHFLT
+echo "Filtering original ldif used to create database..."
+. $LDIFFILTER < $LDIF > $LDIFFLT
+echo "Comparing filter output..."
+$CMP $SEARCHFLT $LDIFFLT > $CMPOUT
+
+if test $? != 0 ; then
+ echo "Comparison failed"
+ exit 1
+fi
+
+echo ">>>>> Test succeeded"
+exit 0