From: Kurt Zeilenga Date: Fri, 19 Aug 2005 20:09:03 +0000 (+0000) Subject: Sync with HEAD X-Git-Tag: OPENLDAP_REL_ENG_2_3_6~1 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=ce357b52c2cd49434ccb80ec3106bbd227386a1c;p=openldap Sync with HEAD ready for 2.3.6? --- diff --git a/CHANGES b/CHANGES index bc66c47a2a..715b234a62 100644 --- a/CHANGES +++ b/CHANGES @@ -1,29 +1,34 @@ 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) diff --git a/doc/drafts/draft-zeilenga-ldap-noop-xx.txt b/doc/drafts/draft-zeilenga-ldap-noop-xx.txt new file mode 100644 index 0000000000..9c65f9b360 --- /dev/null +++ b/doc/drafts/draft-zeilenga-ldap-noop-xx.txt @@ -0,0 +1,340 @@ + + + + + +INTERNET-DRAFT Kurt D. Zeilenga +Intended Category: Standard Track OpenLDAP Foundation +Expires in six months 10 February 2005 + + + + The LDAP No-Op Control + + + +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 . Please send editorial + comments directly to the author . + + 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] + +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] + +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] + +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 + 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 + 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 + 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] + +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] + +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] + + + diff --git a/libraries/libldap/dntest.c b/libraries/libldap/dntest.c index 9e0abe37ee..e99a0570c6 100644 --- a/libraries/libldap/dntest.c +++ b/libraries/libldap/dntest.c @@ -171,31 +171,32 @@ main( int argc, char *argv[] ) 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 ); diff --git a/libraries/libldap/schema.c b/libraries/libldap/schema.c index 07a315a957..bff6c5bdbe 100644 --- a/libraries/libldap/schema.c +++ b/libraries/libldap/schema.c @@ -959,21 +959,23 @@ ldap_attributetype2bv( LDAPAttributeType * at, struct berval *bv ) * 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; @@ -1145,7 +1147,7 @@ parse_qdescrs(const char **sp, int *code) { char ** res; char ** res1; - int kind; + tk_t kind; char * sval; int size; int pos; @@ -1212,7 +1214,7 @@ static char * parse_woid(const char **sp, int *code) { char * sval; - int kind; + tk_t kind; parse_whsp(sp); kind = get_token(sp, &sval); @@ -1227,10 +1229,13 @@ parse_woid(const char **sp, int *code) /* 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) */ @@ -1238,9 +1243,22 @@ parse_noidlen(const char **sp, int *code, int *len, int allow_quoted) 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)++; @@ -1279,7 +1297,7 @@ parse_oids(const char **sp, int *code, const int allow_quoted) { char ** res; char ** res1; - int kind; + tk_t kind; char * sval; int size; int pos; @@ -1441,7 +1459,7 @@ ldap_str2syntax( LDAP_CONST char * s, LDAP_CONST char ** errp, LDAP_CONST unsigned flags ) { - int kind; + tk_t kind; const char * ss = s; char * sval; int seen_name = 0; @@ -1583,7 +1601,7 @@ ldap_str2matchingrule( LDAP_CONST char * s, LDAP_CONST char ** errp, LDAP_CONST unsigned flags ) { - int kind; + tk_t kind; const char * ss = s; char * sval; int seen_name = 0; @@ -1782,7 +1800,7 @@ ldap_str2matchingruleuse( LDAP_CONST char * s, LDAP_CONST char ** errp, LDAP_CONST unsigned flags ) { - int kind; + tk_t kind; const char * ss = s; char * sval; int seen_name = 0; @@ -1984,7 +2002,7 @@ ldap_str2attributetype( LDAP_CONST char * s, LDAP_CONST char ** errp, LDAP_CONST unsigned flags ) { - int kind; + tk_t kind; const char * ss = s; char * sval; int seen_name = 0; @@ -2362,7 +2380,7 @@ ldap_str2objectclass( LDAP_CONST char * s, LDAP_CONST char ** errp, LDAP_CONST unsigned flags ) { - int kind; + tk_t kind; const char * ss = s; char * sval; int seen_name = 0; @@ -2437,6 +2455,7 @@ ldap_str2objectclass( LDAP_CONST char * s, } } LDAP_FREE(sval); + *code = 0; } else { *errp = ss; ldap_objectclass_free(oc); @@ -2525,6 +2544,7 @@ ldap_str2objectclass( LDAP_CONST char * s, ldap_objectclass_free(oc); return NULL; } + *code = 0; } else if ( !strcasecmp(sval,"ABSTRACT") ) { LDAP_FREE(sval); if ( seen_kind ) { @@ -2573,6 +2593,7 @@ ldap_str2objectclass( LDAP_CONST char * s, ldap_objectclass_free(oc); return NULL; } + *code = 0; parse_whsp(&ss); } else if ( !strcasecmp(sval,"MAY") ) { LDAP_FREE(sval); @@ -2589,10 +2610,12 @@ ldap_str2objectclass( LDAP_CONST char * s, 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); @@ -2644,7 +2667,7 @@ ldap_str2contentrule( LDAP_CONST char * s, LDAP_CONST char ** errp, LDAP_CONST unsigned flags ) { - int kind; + tk_t kind; const char * ss = s; char * sval; int seen_name = 0; @@ -2898,7 +2921,8 @@ ldap_str2structurerule( LDAP_CONST char * s, 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; @@ -3081,7 +3105,7 @@ ldap_str2nameform( LDAP_CONST char * s, LDAP_CONST char ** errp, LDAP_CONST unsigned flags ) { - int kind; + tk_t kind; const char * ss = s; char * sval; int seen_name = 0; diff --git a/servers/slapd/aci.c b/servers/slapd/aci.c index 3d587cd9e6..bfceacf03d 100644 --- a/servers/slapd/aci.c +++ b/servers/slapd/aci.c @@ -348,8 +348,7 @@ aci_mask( * 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; @@ -357,22 +356,21 @@ aci_mask( 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; } @@ -383,13 +381,12 @@ aci_mask( /* 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; } @@ -399,8 +396,7 @@ aci_mask( } /* 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; } @@ -417,95 +413,32 @@ aci_mask( 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 ); @@ -525,30 +458,26 @@ aci_mask( 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; } @@ -1079,6 +1008,7 @@ OpenLDAPaciNormalizeRights( static const struct berval *OpenLDAPaciscopes[] = { &aci_bv[ ACI_BV_ENTRY ], &aci_bv[ ACI_BV_CHILDREN ], + &aci_bv[ ACI_BV_SUBTREE ], NULL }; diff --git a/servers/slapd/acl.c b/servers/slapd/acl.c index d6bc21d311..a96104f84f 100644 --- a/servers/slapd/acl.c +++ b/servers/slapd/acl.c @@ -192,8 +192,12 @@ slap_access_allowed( * 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 ) { @@ -384,10 +388,17 @@ access_allowed_mask( 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 ) { @@ -528,10 +539,17 @@ access_allowed_mask( 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 ) { @@ -595,8 +613,12 @@ access_allowed_mask( * 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 ) { @@ -2237,8 +2259,7 @@ int acl_check_modlist( Operation *op, Entry *e, - Modifications *mlist -) + Modifications *mlist ) { struct berval *bv; AccessControlState state = ACL_STATE_INIT; @@ -2291,7 +2312,7 @@ acl_check_modlist( * 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", @@ -2307,7 +2328,9 @@ acl_check_modlist( * 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; @@ -2325,7 +2348,9 @@ acl_check_modlist( 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; @@ -2336,7 +2361,9 @@ acl_check_modlist( 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; @@ -2348,7 +2375,9 @@ acl_check_modlist( 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; diff --git a/servers/slapd/aclparse.c b/servers/slapd/aclparse.c index bc372d7e4b..bca6db91c2 100644 --- a/servers/slapd/aclparse.c +++ b/servers/slapd/aclparse.c @@ -2119,7 +2119,7 @@ acl_usage( void ) "\t[peername[.]=] [sockname[.