1 /* $OpenLDAP: pkg/ldap/servers/slapd/slapi/slapi_dn.c,v 1.5.2.3 2008/02/11 23:26:49 kurt Exp $ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 * Copyright 2005-2008 The OpenLDAP Foundation.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
11 * A copy of this license is available in the file LICENSE in the
12 * top-level directory of the distribution or, alternatively, at
13 * <http://www.OpenLDAP.org/license.html>.
16 * This work was initially developed by Luke Howard for inclusion
17 * in OpenLDAP Software.
22 #include <ac/string.h>
23 #include <ac/stdarg.h>
25 #include <ac/unistd.h>
35 void slapi_sdn_init( Slapi_DN
*sdn
)
38 BER_BVZERO( &sdn
->dn
);
39 BER_BVZERO( &sdn
->ndn
);
42 Slapi_DN
*slapi_sdn_new( void )
46 sdn
= (Slapi_DN
*)slapi_ch_malloc( sizeof(*sdn
));
47 slapi_sdn_init( sdn
);
52 void slapi_sdn_done( Slapi_DN
*sdn
)
57 if ( sdn
->flag
& FLAG_DN
) {
58 slapi_ch_free_string( &sdn
->dn
.bv_val
);
60 if ( sdn
->flag
& FLAG_NDN
) {
61 slapi_ch_free_string( &sdn
->ndn
.bv_val
);
64 slapi_sdn_init( sdn
);
67 void slapi_sdn_free( Slapi_DN
**sdn
)
69 slapi_sdn_done( *sdn
);
70 slapi_ch_free( (void **)sdn
);
73 const char *slapi_sdn_get_dn( const Slapi_DN
*sdn
)
75 if ( !BER_BVISNULL( &sdn
->dn
) )
76 return sdn
->dn
.bv_val
;
78 return sdn
->ndn
.bv_val
;
81 const char *slapi_sdn_get_ndn( const Slapi_DN
*sdn
)
83 if ( BER_BVISNULL( &sdn
->ndn
) ) {
84 dnNormalize( 0, NULL
, NULL
,
85 (struct berval
*)&sdn
->dn
, (struct berval
*)&sdn
->ndn
, NULL
);
86 ((Slapi_DN
*)sdn
)->flag
|= FLAG_NDN
;
89 return sdn
->ndn
.bv_val
;
92 Slapi_DN
*slapi_sdn_new_dn_byval( const char *dn
)
96 sdn
= slapi_sdn_new();
97 return slapi_sdn_set_dn_byval( sdn
, dn
);
100 Slapi_DN
*slapi_sdn_new_ndn_byval( const char *ndn
)
104 sdn
= slapi_sdn_new();
105 return slapi_sdn_set_ndn_byval( sdn
, ndn
);
108 Slapi_DN
*slapi_sdn_new_dn_byref( const char *dn
)
112 sdn
= slapi_sdn_new();
113 return slapi_sdn_set_dn_byref( sdn
, dn
);
116 Slapi_DN
*slapi_sdn_new_ndn_byref( const char *ndn
)
120 sdn
= slapi_sdn_new();
121 return slapi_sdn_set_ndn_byref( sdn
, ndn
);
124 Slapi_DN
*slapi_sdn_new_dn_passin( const char *dn
)
128 sdn
= slapi_sdn_new();
129 return slapi_sdn_set_dn_passin( sdn
, dn
);
132 Slapi_DN
*slapi_sdn_set_dn_byval( Slapi_DN
*sdn
, const char *dn
)
138 slapi_sdn_done( sdn
);
140 sdn
->dn
.bv_val
= slapi_ch_strdup( dn
);
141 sdn
->dn
.bv_len
= strlen( dn
);
143 sdn
->flag
|= FLAG_DN
;
148 Slapi_DN
*slapi_sdn_set_dn_byref( Slapi_DN
*sdn
, const char *dn
)
153 slapi_sdn_done( sdn
);
155 sdn
->dn
.bv_val
= (char *)dn
;
156 sdn
->dn
.bv_len
= strlen( dn
);
162 Slapi_DN
*slapi_sdn_set_dn_passin( Slapi_DN
*sdn
, const char *dn
)
167 slapi_sdn_set_dn_byref( sdn
, dn
);
168 sdn
->flag
|= FLAG_DN
;
173 Slapi_DN
*slapi_sdn_set_ndn_byval( Slapi_DN
*sdn
, const char *ndn
)
179 slapi_sdn_done( sdn
);
181 sdn
->ndn
.bv_val
= slapi_ch_strdup( ndn
);
182 sdn
->ndn
.bv_len
= strlen( ndn
);
184 sdn
->flag
|= FLAG_NDN
;
189 Slapi_DN
*slapi_sdn_set_ndn_byref( Slapi_DN
*sdn
, const char *ndn
)
194 slapi_sdn_done( sdn
);
196 sdn
->ndn
.bv_val
= (char *)ndn
;
197 sdn
->ndn
.bv_len
= strlen( ndn
);
203 Slapi_DN
*slapi_sdn_set_ndn_passin( Slapi_DN
*sdn
, const char *ndn
)
208 slapi_sdn_set_ndn_byref( sdn
, ndn
);
209 sdn
->flag
|= FLAG_NDN
;
214 void slapi_sdn_get_parent( const Slapi_DN
*sdn
, Slapi_DN
*sdn_parent
)
216 struct berval parent_dn
;
218 if ( !(sdn
->flag
& FLAG_DN
) ) {
219 dnParent( (struct berval
*)&sdn
->ndn
, &parent_dn
);
220 slapi_sdn_set_ndn_byval( sdn_parent
, parent_dn
.bv_val
);
222 dnParent( (struct berval
*)&sdn
->dn
, &parent_dn
);
223 slapi_sdn_set_dn_byval( sdn_parent
, parent_dn
.bv_val
);
227 void slapi_sdn_get_backend_parent( const Slapi_DN
*sdn
,
228 Slapi_DN
*sdn_parent
,
229 const Slapi_Backend
*backend
)
231 slapi_sdn_get_ndn( sdn
);
233 if ( backend
== NULL
||
234 be_issuffix( (Slapi_Backend
*)backend
, (struct berval
*)&sdn
->ndn
) == 0 ) {
235 slapi_sdn_get_parent( sdn
, sdn_parent
);
240 Slapi_DN
* slapi_sdn_dup( const Slapi_DN
*sdn
)
244 new_sdn
= slapi_sdn_new();
245 slapi_sdn_copy( sdn
, new_sdn
);
250 void slapi_sdn_copy( const Slapi_DN
*from
, Slapi_DN
*to
)
252 slapi_sdn_set_dn_byval( to
, from
->dn
.bv_val
);
255 int slapi_sdn_compare( const Slapi_DN
*sdn1
, const Slapi_DN
*sdn2
)
259 slapi_sdn_get_ndn( sdn1
);
260 slapi_sdn_get_ndn( sdn2
);
262 dnMatch( &match
, 0, slap_schema
.si_syn_distinguishedName
, NULL
,
263 (struct berval
*)&sdn1
->ndn
, (void *)&sdn2
->ndn
);
268 int slapi_sdn_isempty( const Slapi_DN
*sdn
)
270 return ( BER_BVISEMPTY( &sdn
->dn
) && BER_BVISEMPTY( &sdn
->ndn
) );
273 int slapi_sdn_issuffix( const Slapi_DN
*sdn
, const Slapi_DN
*suffix_sdn
)
275 slapi_sdn_get_ndn( sdn
);
276 slapi_sdn_get_ndn( suffix_sdn
);
278 return dnIsSuffix( &sdn
->ndn
, &suffix_sdn
->ndn
);
281 int slapi_sdn_isparent( const Slapi_DN
*parent
, const Slapi_DN
*child
)
283 Slapi_DN child_parent
;
285 slapi_sdn_get_ndn( child
);
287 slapi_sdn_init( &child_parent
);
288 dnParent( (struct berval
*)&child
->ndn
, &child_parent
.ndn
);
290 return ( slapi_sdn_compare( parent
, &child_parent
) == 0 );
293 int slapi_sdn_isgrandparent( const Slapi_DN
*parent
, const Slapi_DN
*child
)
295 Slapi_DN child_grandparent
;
297 slapi_sdn_get_ndn( child
);
299 slapi_sdn_init( &child_grandparent
);
300 dnParent( (struct berval
*)&child
->ndn
, &child_grandparent
.ndn
);
301 if ( child_grandparent
.ndn
.bv_len
== 0 ) {
305 dnParent( &child_grandparent
.ndn
, &child_grandparent
.ndn
);
307 return ( slapi_sdn_compare( parent
, &child_grandparent
) == 0 );
310 int slapi_sdn_get_ndn_len( const Slapi_DN
*sdn
)
312 slapi_sdn_get_ndn( sdn
);
314 return sdn
->ndn
.bv_len
;
317 int slapi_sdn_scope_test( const Slapi_DN
*dn
, const Slapi_DN
*base
, int scope
)
322 case LDAP_SCOPE_BASE
:
323 rc
= ( slapi_sdn_compare( dn
, base
) == 0 );
325 case LDAP_SCOPE_ONELEVEL
:
326 rc
= slapi_sdn_isparent( base
, dn
);
328 case LDAP_SCOPE_SUBTREE
:
329 rc
= slapi_sdn_issuffix( dn
, base
);
339 void slapi_rdn_init( Slapi_RDN
*rdn
)
342 BER_BVZERO( &rdn
->bv
);
346 Slapi_RDN
*slapi_rdn_new( void )
350 rdn
= (Slapi_RDN
*)slapi_ch_malloc( sizeof(*rdn
));
351 slapi_rdn_init( rdn
);
356 Slapi_RDN
*slapi_rdn_new_dn( const char *dn
)
360 rdn
= slapi_rdn_new();
361 slapi_rdn_init_dn( rdn
, dn
);
365 Slapi_RDN
*slapi_rdn_new_sdn( const Slapi_DN
*sdn
)
367 return slapi_rdn_new_dn( slapi_sdn_get_dn( sdn
) );
370 Slapi_RDN
*slapi_rdn_new_rdn( const Slapi_RDN
*fromrdn
)
372 return slapi_rdn_new_dn( fromrdn
->bv
.bv_val
);
375 void slapi_rdn_init_dn( Slapi_RDN
*rdn
, const char *dn
)
377 slapi_rdn_init( rdn
);
378 slapi_rdn_set_dn( rdn
, dn
);
381 void slapi_rdn_init_sdn( Slapi_RDN
*rdn
, const Slapi_DN
*sdn
)
383 slapi_rdn_init( rdn
);
384 slapi_rdn_set_sdn( rdn
, sdn
);
387 void slapi_rdn_init_rdn( Slapi_RDN
*rdn
, const Slapi_RDN
*fromrdn
)
389 slapi_rdn_init( rdn
);
390 slapi_rdn_set_rdn( rdn
, fromrdn
);
393 void slapi_rdn_set_dn( Slapi_RDN
*rdn
, const char *dn
)
397 slapi_rdn_done( rdn
);
402 bv
.bv_val
= (char *)dn
;
403 bv
.bv_len
= strlen( dn
);
406 dnExtractRdn( &bv
, &rdn
->bv
, NULL
);
407 rdn
->flag
|= FLAG_DN
;
410 void slapi_rdn_set_sdn( Slapi_RDN
*rdn
, const Slapi_DN
*sdn
)
412 slapi_rdn_set_dn( rdn
, slapi_sdn_get_dn( sdn
) );
415 void slapi_rdn_set_rdn( Slapi_RDN
*rdn
, const Slapi_RDN
*fromrdn
)
417 slapi_rdn_set_dn( rdn
, fromrdn
->bv
.bv_val
);
420 void slapi_rdn_free( Slapi_RDN
**rdn
)
422 slapi_rdn_done( *rdn
);
423 slapi_ch_free( (void **)rdn
);
426 void slapi_rdn_done( Slapi_RDN
*rdn
)
428 if ( rdn
->rdn
!= NULL
) {
429 ldap_rdnfree( rdn
->rdn
);
432 slapi_ch_free_string( &rdn
->bv
.bv_val
);
433 slapi_rdn_init( rdn
);
436 const char *slapi_rdn_get_rdn( const Slapi_RDN
*rdn
)
438 return rdn
->bv
.bv_val
;
441 static int slapi_int_rdn_explode( Slapi_RDN
*rdn
)
445 if ( rdn
->rdn
!= NULL
) {
449 return ldap_bv2rdn( &rdn
->bv
, &rdn
->rdn
, &next
, LDAP_DN_FORMAT_LDAP
);
452 static int slapi_int_rdn_implode( Slapi_RDN
*rdn
)
457 if ( rdn
->rdn
== NULL
) {
461 rc
= ldap_rdn2bv( rdn
->rdn
, &bv
, LDAP_DN_FORMAT_LDAPV3
| LDAP_DN_PRETTY
);
462 if ( rc
!= LDAP_SUCCESS
) {
466 slapi_ch_free_string( &rdn
->bv
.bv_val
);
472 int slapi_rdn_get_num_components( Slapi_RDN
*rdn
)
476 if ( slapi_int_rdn_explode( rdn
) != LDAP_SUCCESS
)
479 for ( i
= 0; rdn
->rdn
[i
] != NULL
; i
++ )
485 int slapi_rdn_get_first( Slapi_RDN
*rdn
, char **type
, char **value
)
487 return slapi_rdn_get_next( rdn
, 0, type
, value
);
490 int slapi_rdn_get_next( Slapi_RDN
*rdn
, int index
, char **type
, char **value
)
492 slapi_int_rdn_explode( rdn
);
494 if ( rdn
->rdn
== NULL
|| rdn
->rdn
[index
] == NULL
)
497 *type
= rdn
->rdn
[index
]->la_attr
.bv_val
;
498 *value
= rdn
->rdn
[index
]->la_value
.bv_val
;
503 int slapi_rdn_get_index( Slapi_RDN
*rdn
, const char *type
, const char *value
, size_t length
)
507 AttributeDescription
*ad
= NULL
;
510 slapi_int_rdn_explode( rdn
);
512 if ( slap_str2ad( type
, &ad
, &text
) != LDAP_SUCCESS
) {
516 bv
.bv_val
= (char *)value
;
519 for ( i
= 0; rdn
->rdn
[i
] != NULL
; i
++ ) {
520 if ( !slapi_attr_types_equivalent( ad
->ad_cname
.bv_val
, type
))
523 if ( value_match( &match
, ad
, ad
->ad_type
->sat_equality
, 0,
524 &rdn
->rdn
[i
]->la_value
, (void *)&bv
, &text
) != LDAP_SUCCESS
)
534 int slapi_rdn_get_index_attr( Slapi_RDN
*rdn
, const char *type
, char **value
)
538 for ( i
= 0; rdn
->rdn
[i
] != NULL
; i
++ ) {
539 if ( slapi_attr_types_equivalent( rdn
->rdn
[i
]->la_attr
.bv_val
, type
) ) {
540 *value
= rdn
->rdn
[i
]->la_value
.bv_val
;
548 int slapi_rdn_contains( Slapi_RDN
*rdn
, const char *type
, const char *value
, size_t length
)
550 return ( slapi_rdn_get_index( rdn
, type
, value
, length
) != -1 );
553 int slapi_rdn_contains_attr( Slapi_RDN
*rdn
, const char *type
, char **value
)
555 return ( slapi_rdn_get_index_attr( rdn
, type
, value
) != -1 );
558 int slapi_rdn_compare( Slapi_RDN
*rdn1
, Slapi_RDN
*rdn2
)
560 struct berval nrdn1
= BER_BVNULL
;
561 struct berval nrdn2
= BER_BVNULL
;
564 rdnNormalize( 0, NULL
, NULL
, (struct berval
*)&rdn1
->bv
, &nrdn1
, NULL
);
565 rdnNormalize( 0, NULL
, NULL
, (struct berval
*)&rdn2
->bv
, &nrdn2
, NULL
);
567 if ( rdnMatch( &match
, 0, NULL
, NULL
, &nrdn1
, (void *)&nrdn2
) != LDAP_SUCCESS
) {
574 int slapi_rdn_isempty( const Slapi_RDN
*rdn
)
576 return ( BER_BVISEMPTY( &rdn
->bv
) );
579 int slapi_rdn_add( Slapi_RDN
*rdn
, const char *type
, const char *value
)
584 len
= strlen(type
) + 1 + strlen( value
);
585 if ( !BER_BVISEMPTY( &rdn
->bv
) ) {
586 len
+= 1 + rdn
->bv
.bv_len
;
589 s
= slapi_ch_malloc( len
+ 1 );
591 if ( BER_BVISEMPTY( &rdn
->bv
) ) {
592 snprintf( s
, len
+ 1, "%s=%s", type
, value
);
594 snprintf( s
, len
+ 1, "%s=%s+%s", type
, value
, rdn
->bv
.bv_val
);
597 slapi_rdn_done( rdn
);
599 rdn
->bv
.bv_len
= len
;
605 int slapi_rdn_remove_index( Slapi_RDN
*rdn
, int atindex
)
609 count
= slapi_rdn_get_num_components( rdn
);
611 if ( atindex
< 0 || atindex
>= count
)
614 if ( rdn
->rdn
== NULL
)
617 slapi_ch_free_string( &rdn
->rdn
[atindex
]->la_attr
.bv_val
);
618 slapi_ch_free_string( &rdn
->rdn
[atindex
]->la_value
.bv_val
);
620 for ( i
= atindex
; i
< count
; i
++ ) {
621 rdn
->rdn
[i
] = rdn
->rdn
[i
+ 1];
624 if ( slapi_int_rdn_implode( rdn
) != LDAP_SUCCESS
)
630 int slapi_rdn_remove( Slapi_RDN
*rdn
, const char *type
, const char *value
, size_t length
)
632 int index
= slapi_rdn_get_index( rdn
, type
, value
, length
);
634 return slapi_rdn_remove_index( rdn
, index
);
637 int slapi_rdn_remove_attr( Slapi_RDN
*rdn
, const char *type
)
640 int index
= slapi_rdn_get_index_attr( rdn
, type
, &value
);
642 return slapi_rdn_remove_index( rdn
, index
);
645 Slapi_DN
*slapi_sdn_add_rdn( Slapi_DN
*sdn
, const Slapi_RDN
*rdn
)
649 build_new_dn( &bv
, &sdn
->dn
, (struct berval
*)&rdn
->bv
, NULL
);
651 slapi_sdn_done( sdn
);
657 Slapi_DN
*slapi_sdn_set_parent( Slapi_DN
*sdn
, const Slapi_DN
*parentdn
)
661 slapi_rdn_init_sdn( &rdn
, sdn
);
662 slapi_sdn_set_dn_byref( sdn
, slapi_sdn_get_dn( parentdn
) );
663 slapi_sdn_add_rdn( sdn
, &rdn
);
664 slapi_rdn_done( &rdn
);
669 #endif /* LDAP_SLAPI */