Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / bsd / openldap / dist / servers / slapd / slapi / slapi_dn.c
blob792c6bff392f68ed27f0811a73d9dee95413af7a
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.
5 * All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted only as authorized by the OpenLDAP
9 * Public License.
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>.
15 /* ACKNOWLEDGEMENTS:
16 * This work was initially developed by Luke Howard for inclusion
17 * in OpenLDAP Software.
20 #include "portable.h"
22 #include <ac/string.h>
23 #include <ac/stdarg.h>
24 #include <ac/ctype.h>
25 #include <ac/unistd.h>
26 #include <ldap_pvt.h>
28 #include <slap.h>
29 #include <slapi.h>
31 #ifdef LDAP_SLAPI
32 #define FLAG_DN 0x1
33 #define FLAG_NDN 0x2
35 void slapi_sdn_init( Slapi_DN *sdn )
37 sdn->flag = 0;
38 BER_BVZERO( &sdn->dn );
39 BER_BVZERO( &sdn->ndn );
42 Slapi_DN *slapi_sdn_new( void )
44 Slapi_DN *sdn;
46 sdn = (Slapi_DN *)slapi_ch_malloc( sizeof(*sdn ));
47 slapi_sdn_init( sdn );
49 return sdn;
52 void slapi_sdn_done( Slapi_DN *sdn )
54 if ( sdn == NULL )
55 return;
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;
77 else
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 )
94 Slapi_DN *sdn;
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 )
102 Slapi_DN *sdn;
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 )
110 Slapi_DN *sdn;
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 )
118 Slapi_DN *sdn;
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 )
126 Slapi_DN *sdn;
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 )
134 if ( sdn == NULL ) {
135 return NULL;
138 slapi_sdn_done( sdn );
139 if ( dn != NULL ) {
140 sdn->dn.bv_val = slapi_ch_strdup( dn );
141 sdn->dn.bv_len = strlen( dn );
143 sdn->flag |= FLAG_DN;
145 return sdn;
148 Slapi_DN *slapi_sdn_set_dn_byref( Slapi_DN *sdn, const char *dn )
150 if ( sdn == NULL )
151 return NULL;
153 slapi_sdn_done( sdn );
154 if ( dn != NULL ) {
155 sdn->dn.bv_val = (char *)dn;
156 sdn->dn.bv_len = strlen( dn );
159 return sdn;
162 Slapi_DN *slapi_sdn_set_dn_passin( Slapi_DN *sdn, const char *dn )
164 if ( sdn == NULL )
165 return NULL;
167 slapi_sdn_set_dn_byref( sdn, dn );
168 sdn->flag |= FLAG_DN;
170 return sdn;
173 Slapi_DN *slapi_sdn_set_ndn_byval( Slapi_DN *sdn, const char *ndn )
175 if ( sdn == NULL ) {
176 return NULL;
179 slapi_sdn_done( sdn );
180 if ( ndn != NULL ) {
181 sdn->ndn.bv_val = slapi_ch_strdup( ndn );
182 sdn->ndn.bv_len = strlen( ndn );
184 sdn->flag |= FLAG_NDN;
186 return sdn;
189 Slapi_DN *slapi_sdn_set_ndn_byref( Slapi_DN *sdn, const char *ndn )
191 if ( sdn == NULL )
192 return NULL;
194 slapi_sdn_done( sdn );
195 if ( ndn != NULL ) {
196 sdn->ndn.bv_val = (char *)ndn;
197 sdn->ndn.bv_len = strlen( ndn );
200 return sdn;
203 Slapi_DN *slapi_sdn_set_ndn_passin( Slapi_DN *sdn, const char *ndn )
205 if ( sdn == NULL )
206 return NULL;
208 slapi_sdn_set_ndn_byref( sdn, ndn );
209 sdn->flag |= FLAG_NDN;
211 return sdn;
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 );
221 } else {
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 )
242 Slapi_DN *new_sdn;
244 new_sdn = slapi_sdn_new();
245 slapi_sdn_copy( sdn, new_sdn );
247 return 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 )
257 int match = -1;
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 );
265 return match;
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 ) {
302 return 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 )
319 int rc;
321 switch ( scope ) {
322 case LDAP_SCOPE_BASE:
323 rc = ( slapi_sdn_compare( dn, base ) == 0 );
324 break;
325 case LDAP_SCOPE_ONELEVEL:
326 rc = slapi_sdn_isparent( base, dn );
327 break;
328 case LDAP_SCOPE_SUBTREE:
329 rc = slapi_sdn_issuffix( dn, base );
330 break;
331 default:
332 rc = 0;
333 break;
336 return rc;
339 void slapi_rdn_init( Slapi_RDN *rdn )
341 rdn->flag = 0;
342 BER_BVZERO( &rdn->bv );
343 rdn->rdn = NULL;
346 Slapi_RDN *slapi_rdn_new( void )
348 Slapi_RDN *rdn;
350 rdn = (Slapi_RDN *)slapi_ch_malloc( sizeof(*rdn ));
351 slapi_rdn_init( rdn );
353 return rdn;
356 Slapi_RDN *slapi_rdn_new_dn( const char *dn )
358 Slapi_RDN *rdn;
360 rdn = slapi_rdn_new();
361 slapi_rdn_init_dn( rdn, dn );
362 return rdn;
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 )
395 struct berval bv;
397 slapi_rdn_done( rdn );
399 BER_BVZERO( &bv );
401 if ( dn != NULL ) {
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 );
430 rdn->rdn = NULL;
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 )
443 char *next;
445 if ( rdn->rdn != NULL ) {
446 return LDAP_SUCCESS;
449 return ldap_bv2rdn( &rdn->bv, &rdn->rdn, &next, LDAP_DN_FORMAT_LDAP );
452 static int slapi_int_rdn_implode( Slapi_RDN *rdn )
454 struct berval bv;
455 int rc;
457 if ( rdn->rdn == NULL ) {
458 return LDAP_SUCCESS;
461 rc = ldap_rdn2bv( rdn->rdn, &bv, LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY );
462 if ( rc != LDAP_SUCCESS ) {
463 return rc;
466 slapi_ch_free_string( &rdn->bv.bv_val );
467 rdn->bv = bv;
469 return 0;
472 int slapi_rdn_get_num_components( Slapi_RDN *rdn )
474 int i;
476 if ( slapi_int_rdn_explode( rdn ) != LDAP_SUCCESS )
477 return 0;
479 for ( i = 0; rdn->rdn[i] != NULL; i++ )
482 return 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 )
495 return -1;
497 *type = rdn->rdn[index]->la_attr.bv_val;
498 *value = rdn->rdn[index]->la_value.bv_val;
500 return index + 1;
503 int slapi_rdn_get_index( Slapi_RDN *rdn, const char *type, const char *value, size_t length )
505 int i, match;
506 struct berval bv;
507 AttributeDescription *ad = NULL;
508 const char *text;
510 slapi_int_rdn_explode( rdn );
512 if ( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
513 return -1;
516 bv.bv_val = (char *)value;
517 bv.bv_len = length;
519 for ( i = 0; rdn->rdn[i] != NULL; i++ ) {
520 if ( !slapi_attr_types_equivalent( ad->ad_cname.bv_val, type ))
521 continue;
523 if ( value_match( &match, ad, ad->ad_type->sat_equality, 0,
524 &rdn->rdn[i]->la_value, (void *)&bv, &text ) != LDAP_SUCCESS )
525 match = -1;
527 if ( match == 0 )
528 return i;
531 return -1;
534 int slapi_rdn_get_index_attr( Slapi_RDN *rdn, const char *type, char **value )
536 int i;
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;
541 return i;
545 return -1;
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;
562 int match;
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) {
568 match = -1;
571 return match;
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 )
581 char *s;
582 size_t len;
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 );
593 } else {
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;
600 rdn->bv.bv_val = s;
602 return 1;
605 int slapi_rdn_remove_index( Slapi_RDN *rdn, int atindex )
607 int count, i;
609 count = slapi_rdn_get_num_components( rdn );
611 if ( atindex < 0 || atindex >= count )
612 return 0;
614 if ( rdn->rdn == NULL )
615 return 0;
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 )
625 return 0;
627 return 1;
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 )
639 char *value;
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 )
647 struct berval bv;
649 build_new_dn( &bv, &sdn->dn, (struct berval *)&rdn->bv, NULL );
651 slapi_sdn_done( sdn );
652 sdn->dn = bv;
654 return sdn;
657 Slapi_DN *slapi_sdn_set_parent( Slapi_DN *sdn, const Slapi_DN *parentdn )
659 Slapi_RDN rdn;
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 );
666 return sdn;
669 #endif /* LDAP_SLAPI */