1 /* dn.c - routines for dealing with distinguished names */
2 /* $OpenLDAP: pkg/ldap/servers/slapd/dn.c,v 1.182.2.8 2008/02/11 23:26:44 kurt Exp $ */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 1998-2008 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
16 /* Portions Copyright (c) 1995 Regents of the University of Michigan.
17 * All rights reserved.
19 * Redistribution and use in source and binary forms are permitted
20 * provided that this notice is preserved and that due credit is given
21 * to the University of Michigan at Ann Arbor. The name of the University
22 * may not be used to endorse or promote products derived from this
23 * software without specific prior written permission. This software
24 * is provided ``as is'' without express or implied warranty.
32 #include <ac/socket.h>
33 #include <ac/string.h>
40 * The DN syntax-related functions take advantage of the dn representation
41 * handling functions ldap_str2dn/ldap_dn2str. The latter are not schema-
42 * aware, so the attributes and their values need be validated (and possibly
43 * normalized). In the current implementation the required validation/nor-
44 * malization/"pretty"ing are done on newly created DN structural represen-
45 * tations; however the idea is to move towards DN handling in structural
46 * representation instead of the current string representation. To this
47 * purpose, we need to do only the required operations and keep track of
48 * what has been done to minimize their impact on performances.
50 * Developers are strongly encouraged to use this feature, to speed-up
54 #define AVA_PRIVATE( ava ) ( ( AttributeDescription * )(ava)->la_private )
56 int slap_DN_strict
= SLAP_AD_NOINSERT
;
59 LDAPRDN_validate( LDAPRDN rdn
)
64 assert( rdn
!= NULL
);
66 for ( iAVA
= 0; rdn
[ iAVA
]; iAVA
++ ) {
67 LDAPAVA
*ava
= rdn
[ iAVA
];
68 AttributeDescription
*ad
;
69 slap_syntax_validate_func
*validate
= NULL
;
71 assert( ava
!= NULL
);
73 if ( ( ad
= AVA_PRIVATE( ava
) ) == NULL
) {
74 const char *text
= NULL
;
76 rc
= slap_bv2ad( &ava
->la_attr
, &ad
, &text
);
77 if ( rc
!= LDAP_SUCCESS
) {
78 rc
= slap_bv2undef_ad( &ava
->la_attr
,
80 SLAP_AD_PROXIED
|slap_DN_strict
);
81 if ( rc
!= LDAP_SUCCESS
) {
82 return LDAP_INVALID_SYNTAX
;
86 ava
->la_private
= ( void * )ad
;
90 * Do not allow X-ORDERED 'VALUES' naming attributes
92 if ( ad
->ad_type
->sat_flags
& SLAP_AT_ORDERED_VAL
) {
93 return LDAP_INVALID_SYNTAX
;
97 * Replace attr oid/name with the canonical name
99 ava
->la_attr
= ad
->ad_cname
;
101 validate
= ad
->ad_type
->sat_syntax
->ssyn_validate
;
105 * validate value by validate function
107 rc
= ( *validate
)( ad
->ad_type
->sat_syntax
,
110 if ( rc
!= LDAP_SUCCESS
) {
111 return LDAP_INVALID_SYNTAX
;
120 * In-place, schema-aware validation of the
121 * structural representation of a distinguished name.
124 LDAPDN_validate( LDAPDN dn
)
129 assert( dn
!= NULL
);
131 for ( iRDN
= 0; dn
[ iRDN
]; iRDN
++ ) {
132 rc
= LDAPRDN_validate( dn
[ iRDN
] );
133 if ( rc
!= LDAP_SUCCESS
) {
142 * dn validate routine
152 assert( in
!= NULL
);
154 if ( in
->bv_len
== 0 ) {
157 } else if ( in
->bv_len
> SLAP_LDAPDN_MAXLEN
) {
158 return LDAP_INVALID_SYNTAX
;
161 rc
= ldap_bv2dn( in
, &dn
, LDAP_DN_FORMAT_LDAP
);
162 if ( rc
!= LDAP_SUCCESS
) {
163 return LDAP_INVALID_SYNTAX
;
166 assert( strlen( in
->bv_val
) == in
->bv_len
);
169 * Schema-aware validate
171 rc
= LDAPDN_validate( dn
);
174 if ( rc
!= LDAP_SUCCESS
) {
175 return LDAP_INVALID_SYNTAX
;
190 assert( in
!= NULL
);
191 if ( in
->bv_len
== 0 ) {
194 } else if ( in
->bv_len
> SLAP_LDAPDN_MAXLEN
) {
195 return LDAP_INVALID_SYNTAX
;
198 rc
= ldap_bv2rdn_x( in
, &rdn
, (char **) &p
,
199 LDAP_DN_FORMAT_LDAP
, NULL
);
200 if ( rc
!= LDAP_SUCCESS
) {
201 return LDAP_INVALID_SYNTAX
;
204 assert( strlen( in
->bv_val
) == in
->bv_len
);
207 * Schema-aware validate
209 rc
= LDAPRDN_validate( rdn
);
212 if ( rc
!= LDAP_SUCCESS
) {
213 return LDAP_INVALID_SYNTAX
;
221 * AVA sorting inside a RDN
223 * rule: sort attributeTypes in alphabetical order; in case of multiple
224 * occurrences of the same attributeType, sort values in byte order
225 * (use memcmp, which implies alphabetical order in case of IA5 value;
226 * this should guarantee the repeatability of the operation).
228 * Note: the sorting can be slightly improved by sorting first
229 * by attribute type length, then by alphabetical order.
231 * uses an insertion sort; should be fine since the number of AVAs in
232 * a RDN should be limited.
235 AVA_Sort( LDAPRDN rdn
, int nAVAs
)
240 assert( rdn
!= NULL
);
242 for ( i
= 1; i
< nAVAs
; i
++ ) {
247 for ( j
= i
-1; j
>=0; j
-- ) {
251 a
= strcmp( ava_i
->la_attr
.bv_val
, ava_j
->la_attr
.bv_val
);
256 d
= ava_i
->la_value
.bv_len
- ava_j
->la_value
.bv_len
;
258 a
= memcmp( ava_i
->la_value
.bv_val
,
259 ava_j
->la_value
.bv_val
,
260 d
<= 0 ? ava_i
->la_value
.bv_len
261 : ava_j
->la_value
.bv_len
);
267 /* Duplicates are not allowed */
269 return LDAP_INVALID_DN_SYNTAX
;
274 rdn
[ j
+1 ] = rdn
[ j
];
282 LDAPRDN_rewrite( LDAPRDN rdn
, unsigned flags
, void *ctx
)
285 int rc
, iAVA
, do_sort
= 0;
287 for ( iAVA
= 0; rdn
[ iAVA
]; iAVA
++ ) {
288 LDAPAVA
*ava
= rdn
[ iAVA
];
289 AttributeDescription
*ad
;
290 slap_syntax_validate_func
*validf
= NULL
;
291 slap_mr_normalize_func
*normf
= NULL
;
292 slap_syntax_transform_func
*transf
= NULL
;
293 MatchingRule
*mr
= NULL
;
294 struct berval bv
= BER_BVNULL
;
296 assert( ava
!= NULL
);
298 if ( ( ad
= AVA_PRIVATE( ava
) ) == NULL
) {
299 const char *text
= NULL
;
301 rc
= slap_bv2ad( &ava
->la_attr
, &ad
, &text
);
302 if ( rc
!= LDAP_SUCCESS
) {
303 rc
= slap_bv2undef_ad( &ava
->la_attr
,
305 SLAP_AD_PROXIED
|slap_DN_strict
);
306 if ( rc
!= LDAP_SUCCESS
) {
307 return LDAP_INVALID_SYNTAX
;
311 ava
->la_private
= ( void * )ad
;
316 * Replace attr oid/name with the canonical name
318 ava
->la_attr
= ad
->ad_cname
;
320 if( ava
->la_flags
& LDAP_AVA_BINARY
) {
321 if( ava
->la_value
.bv_len
== 0 ) {
322 /* BER encoding is empty */
323 return LDAP_INVALID_SYNTAX
;
326 /* Do not allow X-ORDERED 'VALUES' naming attributes */
327 } else if( ad
->ad_type
->sat_flags
& SLAP_AT_ORDERED_VAL
) {
328 return LDAP_INVALID_SYNTAX
;
330 /* AVA is binary encoded, don't muck with it */
331 } else if( flags
& SLAP_LDAPDN_PRETTY
) {
332 transf
= ad
->ad_type
->sat_syntax
->ssyn_pretty
;
334 validf
= ad
->ad_type
->sat_syntax
->ssyn_validate
;
336 } else { /* normalization */
337 validf
= ad
->ad_type
->sat_syntax
->ssyn_validate
;
338 mr
= ad
->ad_type
->sat_equality
;
339 if( mr
&& (!( mr
->smr_usage
& SLAP_MR_MUTATION_NORMALIZER
))) {
340 normf
= mr
->smr_normalize
;
345 /* validate value before normalization */
346 rc
= ( *validf
)( ad
->ad_type
->sat_syntax
,
349 : (struct berval
*) &slap_empty_bv
);
351 if ( rc
!= LDAP_SUCCESS
) {
352 return LDAP_INVALID_SYNTAX
;
358 * transform value by pretty function
359 * if value is empty, use empty_bv
361 rc
= ( *transf
)( ad
->ad_type
->sat_syntax
,
364 : (struct berval
*) &slap_empty_bv
,
367 if ( rc
!= LDAP_SUCCESS
) {
368 return LDAP_INVALID_SYNTAX
;
375 * if value is empty, use empty_bv
378 SLAP_MR_VALUE_OF_ASSERTION_SYNTAX
,
379 ad
->ad_type
->sat_syntax
,
383 : (struct berval
*) &slap_empty_bv
,
386 if ( rc
!= LDAP_SUCCESS
) {
387 return LDAP_INVALID_SYNTAX
;
393 if ( ava
->la_flags
& LDAP_AVA_FREE_VALUE
)
394 ber_memfree_x( ava
->la_value
.bv_val
, ctx
);
396 ava
->la_flags
|= LDAP_AVA_FREE_VALUE
;
402 rc
= AVA_Sort( rdn
, iAVA
);
409 * In-place, schema-aware normalization / "pretty"ing of the
410 * structural representation of a distinguished name.
413 LDAPDN_rewrite( LDAPDN dn
, unsigned flags
, void *ctx
)
418 assert( dn
!= NULL
);
420 for ( iRDN
= 0; dn
[ iRDN
]; iRDN
++ ) {
421 rc
= LDAPRDN_rewrite( dn
[ iRDN
], flags
, ctx
);
422 if ( rc
!= LDAP_SUCCESS
) {
439 assert( val
!= NULL
);
440 assert( out
!= NULL
);
442 Debug( LDAP_DEBUG_TRACE
, ">>> dnNormalize: <%s>\n", val
->bv_val
? val
->bv_val
: "", 0, 0 );
444 if ( val
->bv_len
!= 0 ) {
449 * Go to structural representation
451 rc
= ldap_bv2dn_x( val
, &dn
, LDAP_DN_FORMAT_LDAP
, ctx
);
452 if ( rc
!= LDAP_SUCCESS
) {
453 return LDAP_INVALID_SYNTAX
;
456 assert( strlen( val
->bv_val
) == val
->bv_len
);
459 * Schema-aware rewrite
461 if ( LDAPDN_rewrite( dn
, 0, ctx
) != LDAP_SUCCESS
) {
462 ldap_dnfree_x( dn
, ctx
);
463 return LDAP_INVALID_SYNTAX
;
467 * Back to string representation
469 rc
= ldap_dn2bv_x( dn
, out
,
470 LDAP_DN_FORMAT_LDAPV3
| LDAP_DN_PRETTY
, ctx
);
472 ldap_dnfree_x( dn
, ctx
);
474 if ( rc
!= LDAP_SUCCESS
) {
475 return LDAP_INVALID_SYNTAX
;
478 ber_dupbv_x( out
, val
, ctx
);
481 Debug( LDAP_DEBUG_TRACE
, "<<< dnNormalize: <%s>\n", out
->bv_val
? out
->bv_val
: "", 0, 0 );
495 assert( val
!= NULL
);
496 assert( out
!= NULL
);
498 Debug( LDAP_DEBUG_TRACE
, ">>> dnNormalize: <%s>\n", val
->bv_val
? val
->bv_val
: "", 0, 0 );
499 if ( val
->bv_len
!= 0 ) {
505 * Go to structural representation
507 rc
= ldap_bv2rdn_x( val
, &rdn
, (char **) &p
,
508 LDAP_DN_FORMAT_LDAP
, ctx
);
510 if ( rc
!= LDAP_SUCCESS
) {
511 return LDAP_INVALID_SYNTAX
;
514 assert( strlen( val
->bv_val
) == val
->bv_len
);
517 * Schema-aware rewrite
519 if ( LDAPRDN_rewrite( rdn
, 0, ctx
) != LDAP_SUCCESS
) {
520 ldap_rdnfree_x( rdn
, ctx
);
521 return LDAP_INVALID_SYNTAX
;
525 * Back to string representation
527 rc
= ldap_rdn2bv_x( rdn
, out
,
528 LDAP_DN_FORMAT_LDAPV3
| LDAP_DN_PRETTY
, ctx
);
530 ldap_rdnfree_x( rdn
, ctx
);
532 if ( rc
!= LDAP_SUCCESS
) {
533 return LDAP_INVALID_SYNTAX
;
536 ber_dupbv_x( out
, val
, ctx
);
539 Debug( LDAP_DEBUG_TRACE
, "<<< dnNormalize: <%s>\n", out
->bv_val
? out
->bv_val
: "", 0, 0 );
551 assert( val
!= NULL
);
552 assert( out
!= NULL
);
554 Debug( LDAP_DEBUG_TRACE
, ">>> dnPretty: <%s>\n", val
->bv_val
? val
->bv_val
: "", 0, 0 );
556 if ( val
->bv_len
== 0 ) {
557 ber_dupbv_x( out
, val
, ctx
);
559 } else if ( val
->bv_len
> SLAP_LDAPDN_MAXLEN
) {
560 return LDAP_INVALID_SYNTAX
;
566 /* FIXME: should be liberal in what we accept */
567 rc
= ldap_bv2dn_x( val
, &dn
, LDAP_DN_FORMAT_LDAP
, ctx
);
568 if ( rc
!= LDAP_SUCCESS
) {
569 return LDAP_INVALID_SYNTAX
;
572 assert( strlen( val
->bv_val
) == val
->bv_len
);
575 * Schema-aware rewrite
577 if ( LDAPDN_rewrite( dn
, SLAP_LDAPDN_PRETTY
, ctx
) != LDAP_SUCCESS
) {
578 ldap_dnfree_x( dn
, ctx
);
579 return LDAP_INVALID_SYNTAX
;
582 /* FIXME: not sure why the default isn't pretty */
583 /* RE: the default is the form that is used as
584 * an internal representation; the pretty form
586 rc
= ldap_dn2bv_x( dn
, out
,
587 LDAP_DN_FORMAT_LDAPV3
| LDAP_DN_PRETTY
, ctx
);
589 ldap_dnfree_x( dn
, ctx
);
591 if ( rc
!= LDAP_SUCCESS
) {
592 return LDAP_INVALID_SYNTAX
;
596 Debug( LDAP_DEBUG_TRACE
, "<<< dnPretty: <%s>\n", out
->bv_val
? out
->bv_val
: "", 0, 0 );
608 assert( val
!= NULL
);
609 assert( out
!= NULL
);
611 Debug( LDAP_DEBUG_TRACE
, ">>> rdnPretty: <%s>\n", val
->bv_val
? val
->bv_val
: "", 0, 0 );
613 if ( val
->bv_len
== 0 ) {
614 ber_dupbv_x( out
, val
, ctx
);
616 } else if ( val
->bv_len
> SLAP_LDAPDN_MAXLEN
) {
617 return LDAP_INVALID_SYNTAX
;
624 /* FIXME: should be liberal in what we accept */
625 rc
= ldap_bv2rdn_x( val
, &rdn
, (char **) &p
,
626 LDAP_DN_FORMAT_LDAP
, ctx
);
627 if ( rc
!= LDAP_SUCCESS
) {
628 return LDAP_INVALID_SYNTAX
;
631 assert( strlen( val
->bv_val
) == val
->bv_len
);
634 * Schema-aware rewrite
636 if ( LDAPRDN_rewrite( rdn
, SLAP_LDAPDN_PRETTY
, ctx
) != LDAP_SUCCESS
) {
637 ldap_rdnfree_x( rdn
, ctx
);
638 return LDAP_INVALID_SYNTAX
;
641 /* FIXME: not sure why the default isn't pretty */
642 /* RE: the default is the form that is used as
643 * an internal representation; the pretty form
645 rc
= ldap_rdn2bv_x( rdn
, out
,
646 LDAP_DN_FORMAT_LDAPV3
| LDAP_DN_PRETTY
, ctx
);
648 ldap_rdnfree_x( rdn
, ctx
);
650 if ( rc
!= LDAP_SUCCESS
) {
651 return LDAP_INVALID_SYNTAX
;
655 Debug( LDAP_DEBUG_TRACE
, "<<< dnPretty: <%s>\n", out
->bv_val
? out
->bv_val
: "", 0, 0 );
669 assert( val
!= NULL
);
670 assert( dn
!= NULL
);
672 Debug( LDAP_DEBUG_TRACE
, ">>> dn%sDN: <%s>\n",
673 flags
== SLAP_LDAPDN_PRETTY
? "Pretty" : "Normal",
674 val
->bv_val
? val
->bv_val
: "", 0 );
676 if ( val
->bv_len
== 0 ) {
679 } else if ( val
->bv_len
> SLAP_LDAPDN_MAXLEN
) {
680 return LDAP_INVALID_SYNTAX
;
685 /* FIXME: should be liberal in what we accept */
686 rc
= ldap_bv2dn_x( val
, dn
, LDAP_DN_FORMAT_LDAP
, ctx
);
687 if ( rc
!= LDAP_SUCCESS
) {
688 return LDAP_INVALID_SYNTAX
;
691 assert( strlen( val
->bv_val
) == val
->bv_len
);
694 * Schema-aware rewrite
696 if ( LDAPDN_rewrite( *dn
, flags
, ctx
) != LDAP_SUCCESS
) {
697 ldap_dnfree_x( *dn
, ctx
);
699 return LDAP_INVALID_SYNTAX
;
703 Debug( LDAP_DEBUG_TRACE
, "<<< dn%sDN\n",
704 flags
== SLAP_LDAPDN_PRETTY
? "Pretty" : "Normal",
711 * Combination of both dnPretty and dnNormalize
717 struct berval
*pretty
,
718 struct berval
*normal
,
721 Debug( LDAP_DEBUG_TRACE
, ">>> dnPrettyNormal: <%s>\n", val
->bv_val
? val
->bv_val
: "", 0, 0 );
723 assert( val
!= NULL
);
724 assert( pretty
!= NULL
);
725 assert( normal
!= NULL
);
727 if ( val
->bv_len
== 0 ) {
728 ber_dupbv_x( pretty
, val
, ctx
);
729 ber_dupbv_x( normal
, val
, ctx
);
731 } else if ( val
->bv_len
> SLAP_LDAPDN_MAXLEN
) {
733 return LDAP_INVALID_SYNTAX
;
739 pretty
->bv_val
= NULL
;
740 normal
->bv_val
= NULL
;
744 /* FIXME: should be liberal in what we accept */
745 rc
= ldap_bv2dn_x( val
, &dn
, LDAP_DN_FORMAT_LDAP
, ctx
);
746 if ( rc
!= LDAP_SUCCESS
) {
747 return LDAP_INVALID_SYNTAX
;
750 assert( strlen( val
->bv_val
) == val
->bv_len
);
753 * Schema-aware rewrite
755 if ( LDAPDN_rewrite( dn
, SLAP_LDAPDN_PRETTY
, ctx
) != LDAP_SUCCESS
) {
756 ldap_dnfree_x( dn
, ctx
);
757 return LDAP_INVALID_SYNTAX
;
760 rc
= ldap_dn2bv_x( dn
, pretty
,
761 LDAP_DN_FORMAT_LDAPV3
| LDAP_DN_PRETTY
, ctx
);
763 if ( rc
!= LDAP_SUCCESS
) {
764 ldap_dnfree_x( dn
, ctx
);
765 return LDAP_INVALID_SYNTAX
;
768 if ( LDAPDN_rewrite( dn
, 0, ctx
) != LDAP_SUCCESS
) {
769 ldap_dnfree_x( dn
, ctx
);
770 ber_memfree_x( pretty
->bv_val
, ctx
);
771 pretty
->bv_val
= NULL
;
773 return LDAP_INVALID_SYNTAX
;
776 rc
= ldap_dn2bv_x( dn
, normal
,
777 LDAP_DN_FORMAT_LDAPV3
| LDAP_DN_PRETTY
, ctx
);
779 ldap_dnfree_x( dn
, ctx
);
780 if ( rc
!= LDAP_SUCCESS
) {
781 ber_memfree_x( pretty
->bv_val
, ctx
);
782 pretty
->bv_val
= NULL
;
784 return LDAP_INVALID_SYNTAX
;
788 Debug( LDAP_DEBUG_TRACE
, "<<< dnPrettyNormal: <%s>, <%s>\n",
789 pretty
->bv_val
? pretty
->bv_val
: "",
790 normal
->bv_val
? normal
->bv_val
: "", 0 );
804 struct berval
*value
,
805 void *assertedValue
)
808 struct berval
*asserted
= (struct berval
*) assertedValue
;
810 assert( matchp
!= NULL
);
811 assert( value
!= NULL
);
812 assert( assertedValue
!= NULL
);
813 assert( !BER_BVISNULL( value
) );
814 assert( !BER_BVISNULL( asserted
) );
816 match
= value
->bv_len
- asserted
->bv_len
;
819 match
= memcmp( value
->bv_val
, asserted
->bv_val
,
823 Debug( LDAP_DEBUG_ARGS
, "dnMatch %d\n\t\"%s\"\n\t\"%s\"\n",
824 match
, value
->bv_val
, asserted
->bv_val
);
831 * dnRelativeMatch routine
839 struct berval
*value
,
840 void *assertedValue
)
843 struct berval
*asserted
= (struct berval
*) assertedValue
;
845 assert( matchp
!= NULL
);
846 assert( value
!= NULL
);
847 assert( assertedValue
!= NULL
);
848 assert( !BER_BVISNULL( value
) );
849 assert( !BER_BVISNULL( asserted
) );
851 if( mr
== slap_schema
.si_mr_dnSubtreeMatch
) {
852 if( asserted
->bv_len
> value
->bv_len
) {
854 } else if ( asserted
->bv_len
== value
->bv_len
) {
855 match
= memcmp( value
->bv_val
, asserted
->bv_val
,
859 value
->bv_val
[value
->bv_len
- asserted
->bv_len
- 1] ))
862 &value
->bv_val
[value
->bv_len
- asserted
->bv_len
],
874 if( mr
== slap_schema
.si_mr_dnSuperiorMatch
) {
876 value
= (struct berval
*) assertedValue
;
877 mr
= slap_schema
.si_mr_dnSubordinateMatch
;
880 if( mr
== slap_schema
.si_mr_dnSubordinateMatch
) {
881 if( asserted
->bv_len
>= value
->bv_len
) {
885 value
->bv_val
[value
->bv_len
- asserted
->bv_len
- 1] ))
888 &value
->bv_val
[value
->bv_len
- asserted
->bv_len
],
900 if( mr
== slap_schema
.si_mr_dnOneLevelMatch
) {
901 if( asserted
->bv_len
>= value
->bv_len
) {
905 value
->bv_val
[value
->bv_len
- asserted
->bv_len
- 1] ))
908 &value
->bv_val
[value
->bv_len
- asserted
->bv_len
],
914 rdn
.bv_val
= value
->bv_val
;
915 rdn
.bv_len
= value
->bv_len
- asserted
->bv_len
- 1;
916 match
= dnIsOneLevelRDN( &rdn
) ? 0 : 1;
927 /* should not be reachable */
938 struct berval
*value
,
939 void *assertedValue
)
942 struct berval
*asserted
= (struct berval
*) assertedValue
;
944 assert( matchp
!= NULL
);
945 assert( value
!= NULL
);
946 assert( assertedValue
!= NULL
);
948 match
= value
->bv_len
- asserted
->bv_len
;
951 match
= memcmp( value
->bv_val
, asserted
->bv_val
,
955 Debug( LDAP_DEBUG_ARGS
, "rdnMatch %d\n\t\"%s\"\n\t\"%s\"\n",
956 match
, value
->bv_val
, asserted
->bv_val
);
964 * dnParent - dn's parent, in-place
965 * note: the incoming dn is assumed to be normalized/prettyfied,
966 * so that escaped rdn/ava separators are in '\'+hexpair form
968 * note: "dn" and "pdn" can point to the same berval;
969 * beware that, in this case, the pointer to the original buffer
979 p
= ber_bvchr( dn
, ',' );
984 pdn
->bv_val
= dn
->bv_val
+ dn
->bv_len
;
988 assert( DN_SEPARATOR( p
[ 0 ] ) );
991 assert( ATTR_LEADCHAR( p
[ 0 ] ) );
992 pdn
->bv_len
= dn
->bv_len
- (p
- dn
->bv_val
);
999 * dnRdn - dn's rdn, in-place
1000 * note: the incoming dn is assumed to be normalized/prettyfied,
1001 * so that escaped rdn/ava separators are in '\'+hexpair form
1006 struct berval
*rdn
)
1011 p
= ber_bvchr( dn
, ',' );
1018 assert( DN_SEPARATOR( p
[ 0 ] ) );
1019 assert( ATTR_LEADCHAR( p
[ 1 ] ) );
1020 rdn
->bv_len
= p
- dn
->bv_val
;
1035 assert( dn
!= NULL
);
1036 assert( rdn
!= NULL
);
1038 if( dn
->bv_len
== 0 ) {
1042 rc
= ldap_bv2rdn_x( dn
, &tmpRDN
, (char **)&p
, LDAP_DN_FORMAT_LDAP
, ctx
);
1043 if ( rc
!= LDAP_SUCCESS
) {
1047 rc
= ldap_rdn2bv_x( tmpRDN
, rdn
, LDAP_DN_FORMAT_LDAPV3
| LDAP_DN_PRETTY
,
1050 ldap_rdnfree_x( tmpRDN
, ctx
);
1055 * We can assume the input is a prettied or normalized DN
1060 struct berval
*dn_in
)
1064 assert( dn_in
!= NULL
);
1066 if ( dn_in
== NULL
) {
1070 if ( !dn_in
->bv_len
) {
1074 if ( be
!= NULL
&& be_issuffix( be
, dn_in
) ) {
1078 p
= ber_bvchr( dn_in
, ',' );
1080 return p
? p
- dn_in
->bv_val
: dn_in
->bv_len
;
1086 * LDAP_SUCCESS if rdn is a legal rdn;
1087 * LDAP_INVALID_SYNTAX otherwise (including a sequence of rdns)
1090 rdn_validate( struct berval
*rdn
)
1094 * input is a pretty or normalized DN
1095 * hence, we can just search for ','
1097 if( rdn
== NULL
|| rdn
->bv_len
== 0 ||
1098 rdn
->bv_len
> SLAP_LDAPDN_MAXLEN
)
1100 return LDAP_INVALID_SYNTAX
;
1102 return ber_bvchr( rdn
, ',' ) == NULL
1103 ? LDAP_SUCCESS
: LDAP_INVALID_SYNTAX
;
1106 LDAPRDN
*RDN
, **DN
[ 2 ] = { &RDN
, NULL
};
1113 if ( rdn
== NULL
|| rdn
== '\0' ) {
1120 rc
= ldap_bv2rdn( rdn
, &RDN
, (char **)&p
, LDAP_DN_FORMAT_LDAP
);
1121 if ( rc
!= LDAP_SUCCESS
) {
1128 if ( p
[ 0 ] != '\0' ) {
1133 * Schema-aware validate
1135 if ( rc
== LDAP_SUCCESS
) {
1136 rc
= LDAPDN_validate( DN
);
1138 ldap_rdnfree( RDN
);
1141 * Must validate (there's a repeated parsing ...)
1143 return ( rc
== LDAP_SUCCESS
);
1150 * Used by back-bdb back_modrdn to create the new dn of entries being
1153 * new_dn = parent (p_dn) + separator + rdn (newrdn) + null.
1157 build_new_dn( struct berval
* new_dn
,
1158 struct berval
* parent_dn
,
1159 struct berval
* newrdn
,
1164 if ( parent_dn
== NULL
|| parent_dn
->bv_len
== 0 ) {
1165 ber_dupbv_x( new_dn
, newrdn
, memctx
);
1169 new_dn
->bv_len
= parent_dn
->bv_len
+ newrdn
->bv_len
+ 1;
1170 new_dn
->bv_val
= (char *) slap_sl_malloc( new_dn
->bv_len
+ 1, memctx
);
1172 ptr
= lutil_strncopy( new_dn
->bv_val
, newrdn
->bv_val
, newrdn
->bv_len
);
1174 strcpy( ptr
, parent_dn
->bv_val
);
1179 * dnIsSuffix - tells whether suffix is a suffix of dn.
1180 * Both dn and suffix must be normalized.
1184 const struct berval
*dn
,
1185 const struct berval
*suffix
)
1187 int d
= dn
->bv_len
- suffix
->bv_len
;
1189 assert( dn
!= NULL
);
1190 assert( suffix
!= NULL
);
1192 /* empty suffix matches any dn */
1193 if ( suffix
->bv_len
== 0 ) {
1197 /* suffix longer than dn */
1202 /* no rdn separator or escaped rdn separator */
1203 if ( d
> 1 && !DN_SEPARATOR( dn
->bv_val
[ d
- 1 ] ) ) {
1207 /* no possible match or malformed dn */
1213 return( strcmp( dn
->bv_val
+ d
, suffix
->bv_val
) == 0 );
1217 dnIsOneLevelRDN( struct berval
*rdn
)
1219 ber_len_t len
= rdn
->bv_len
;
1221 if ( DN_SEPARATOR( rdn
->bv_val
[ len
] ) ) {
1230 static SLAP_CERT_MAP_FN
*DNX509PeerNormalizeCertMap
= NULL
;
1233 int register_certificate_map_function(SLAP_CERT_MAP_FN
*fn
)
1236 if ( DNX509PeerNormalizeCertMap
== NULL
) {
1237 DNX509PeerNormalizeCertMap
= fn
;
1246 * Convert an X.509 DN into a normalized LDAP DN
1249 dnX509normalize( void *x509_name
, struct berval
*out
)
1251 /* Invoke the LDAP library's converter with our schema-rewriter */
1252 int rc
= ldap_X509dn2bv( x509_name
, out
, LDAPDN_rewrite
, 0 );
1254 Debug( LDAP_DEBUG_TRACE
,
1255 "dnX509Normalize: <%s> (%d)\n",
1256 BER_BVISNULL( out
) ? "(null)" : out
->bv_val
, rc
, 0 );
1263 * Get the TLS session's peer's DN into a normalized LDAP DN
1266 dnX509peerNormalize( void *ssl
, struct berval
*dn
)
1268 int rc
= LDAP_INVALID_CREDENTIALS
;
1270 if ( DNX509PeerNormalizeCertMap
!= NULL
)
1271 rc
= (*DNX509PeerNormalizeCertMap
)( ssl
, dn
);
1273 if ( rc
!= LDAP_SUCCESS
) {
1274 rc
= ldap_pvt_tls_get_peer_dn( ssl
, dn
,
1275 (LDAPDN_rewrite_dummy
*)LDAPDN_rewrite
, 0 );