]> git.sur5r.net Git - openldap/blob - servers/slapd/slapi/slapi_dn.c
1b5912d869b6d69da2686ef80425d2ac4e24a213
[openldap] / servers / slapd / slapi / slapi_dn.c
1 /* $OpenLDAP$ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 2005-2013 The OpenLDAP Foundation.
5  * All rights reserved.
6  *
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.
10  *
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>.
14  */
15 /* ACKNOWLEDGEMENTS:
16  * This work was initially developed by Luke Howard for inclusion
17  * in OpenLDAP Software.
18  */
19
20 #include "portable.h"
21
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>
27
28 #include <slap.h>
29 #include <slapi.h>
30
31 #ifdef LDAP_SLAPI
32 #define FLAG_DN 0x1
33 #define FLAG_NDN 0x2
34
35 void slapi_sdn_init( Slapi_DN *sdn )
36 {
37         sdn->flag = 0;
38         BER_BVZERO( &sdn->dn );
39         BER_BVZERO( &sdn->ndn );
40 }
41
42 Slapi_DN *slapi_sdn_new( void )
43 {
44         Slapi_DN *sdn;
45
46         sdn = (Slapi_DN *)slapi_ch_malloc( sizeof(*sdn ));
47         slapi_sdn_init( sdn );
48
49         return sdn;
50 }
51
52 void slapi_sdn_done( Slapi_DN *sdn )
53 {
54         if ( sdn == NULL )
55                 return;
56
57         if ( sdn->flag & FLAG_DN ) {
58                 slapi_ch_free_string( &sdn->dn.bv_val );
59         }
60         if ( sdn->flag & FLAG_NDN ) {
61                 slapi_ch_free_string( &sdn->ndn.bv_val );
62         }
63
64         slapi_sdn_init( sdn );
65 }
66
67 void slapi_sdn_free( Slapi_DN **sdn )
68 {
69         slapi_sdn_done( *sdn );
70         slapi_ch_free( (void **)sdn );
71 }
72
73 const char *slapi_sdn_get_dn( const Slapi_DN *sdn )
74 {
75         if ( !BER_BVISNULL( &sdn->dn ) )
76                 return sdn->dn.bv_val;
77         else
78                 return sdn->ndn.bv_val;
79 }
80
81 const char *slapi_sdn_get_ndn( const Slapi_DN *sdn )
82 {
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;
87         }
88
89         return sdn->ndn.bv_val;
90 }
91
92 Slapi_DN *slapi_sdn_new_dn_byval( const char *dn )
93 {
94         Slapi_DN *sdn;
95
96         sdn = slapi_sdn_new();
97         return slapi_sdn_set_dn_byval( sdn, dn );
98 }
99
100 Slapi_DN *slapi_sdn_new_ndn_byval( const char *ndn )
101 {
102         Slapi_DN *sdn;
103
104         sdn = slapi_sdn_new();
105         return slapi_sdn_set_ndn_byval( sdn, ndn );
106 }
107
108 Slapi_DN *slapi_sdn_new_dn_byref( const char *dn )
109 {
110         Slapi_DN *sdn;
111
112         sdn = slapi_sdn_new();
113         return slapi_sdn_set_dn_byref( sdn, dn );
114 }
115
116 Slapi_DN *slapi_sdn_new_ndn_byref( const char *ndn )
117 {
118         Slapi_DN *sdn;
119
120         sdn = slapi_sdn_new();
121         return slapi_sdn_set_ndn_byref( sdn, ndn );
122 }
123
124 Slapi_DN *slapi_sdn_new_dn_passin( const char *dn )
125 {
126         Slapi_DN *sdn;
127
128         sdn = slapi_sdn_new();
129         return slapi_sdn_set_dn_passin( sdn, dn );
130 }
131
132 Slapi_DN *slapi_sdn_set_dn_byval( Slapi_DN *sdn, const char *dn )
133 {
134         if ( sdn == NULL ) {
135                 return NULL;
136         }
137
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 );
142         }
143         sdn->flag |= FLAG_DN;
144
145         return sdn;
146 }
147
148 Slapi_DN *slapi_sdn_set_dn_byref( Slapi_DN *sdn, const char *dn )
149 {
150         if ( sdn == NULL )
151                 return NULL;
152
153         slapi_sdn_done( sdn );
154         if ( dn != NULL ) {
155                 sdn->dn.bv_val = (char *)dn;
156                 sdn->dn.bv_len = strlen( dn );
157         }
158
159         return sdn;
160 }
161
162 Slapi_DN *slapi_sdn_set_dn_passin( Slapi_DN *sdn, const char *dn )
163 {
164         if ( sdn == NULL )
165                 return NULL;
166
167         slapi_sdn_set_dn_byref( sdn, dn );
168         sdn->flag |= FLAG_DN;
169
170         return sdn;
171 }
172
173 Slapi_DN *slapi_sdn_set_ndn_byval( Slapi_DN *sdn, const char *ndn )
174 {
175         if ( sdn == NULL ) {
176                 return NULL;
177         }
178
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 );
183         }
184         sdn->flag |= FLAG_NDN;
185
186         return sdn;
187 }
188
189 Slapi_DN *slapi_sdn_set_ndn_byref( Slapi_DN *sdn, const char *ndn )
190 {
191         if ( sdn == NULL )
192                 return NULL;
193
194         slapi_sdn_done( sdn );
195         if ( ndn != NULL ) {
196                 sdn->ndn.bv_val = (char *)ndn;
197                 sdn->ndn.bv_len = strlen( ndn );
198         }
199
200         return sdn;
201 }
202
203 Slapi_DN *slapi_sdn_set_ndn_passin( Slapi_DN *sdn, const char *ndn )
204 {
205         if ( sdn == NULL )
206                 return NULL;
207
208         slapi_sdn_set_ndn_byref( sdn, ndn );
209         sdn->flag |= FLAG_NDN;
210
211         return sdn;
212 }
213
214 void slapi_sdn_get_parent( const Slapi_DN *sdn, Slapi_DN *sdn_parent )
215 {
216         struct berval parent_dn;
217
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 );
224         }
225 }
226
227 void slapi_sdn_get_backend_parent( const Slapi_DN *sdn,
228         Slapi_DN *sdn_parent,
229         const Slapi_Backend *backend )
230 {
231         slapi_sdn_get_ndn( sdn );
232
233         if ( backend == NULL ||
234              be_issuffix( (Slapi_Backend *)backend, (struct berval *)&sdn->ndn ) == 0 ) {
235                 slapi_sdn_get_parent( sdn, sdn_parent );
236         }
237
238 }
239
240 Slapi_DN * slapi_sdn_dup( const Slapi_DN *sdn )
241 {
242         Slapi_DN *new_sdn;
243
244         new_sdn = slapi_sdn_new();
245         slapi_sdn_copy( sdn, new_sdn );
246
247         return new_sdn;
248 }
249
250 void slapi_sdn_copy( const Slapi_DN *from, Slapi_DN *to )
251 {
252         slapi_sdn_set_dn_byval( to, from->dn.bv_val );
253 }
254
255 int slapi_sdn_compare( const Slapi_DN *sdn1, const Slapi_DN *sdn2 )
256 {
257         int match = -1;
258
259         slapi_sdn_get_ndn( sdn1 );
260         slapi_sdn_get_ndn( sdn2 );
261
262         dnMatch( &match, 0, slap_schema.si_syn_distinguishedName, NULL,
263                 (struct berval *)&sdn1->ndn, (void *)&sdn2->ndn );
264
265         return match;
266 }
267
268 int slapi_sdn_isempty( const Slapi_DN *sdn)
269 {
270         return ( BER_BVISEMPTY( &sdn->dn ) && BER_BVISEMPTY( &sdn->ndn ) );
271 }
272
273 int slapi_sdn_issuffix( const Slapi_DN *sdn, const Slapi_DN *suffix_sdn )
274 {
275         slapi_sdn_get_ndn( sdn );
276         slapi_sdn_get_ndn( suffix_sdn );
277
278         return dnIsSuffix( &sdn->ndn, &suffix_sdn->ndn );
279 }
280
281 int slapi_sdn_isparent( const Slapi_DN *parent, const Slapi_DN *child )
282 {
283         Slapi_DN child_parent;
284
285         slapi_sdn_get_ndn( child );
286
287         slapi_sdn_init( &child_parent );
288         dnParent( (struct berval *)&child->ndn, &child_parent.ndn );
289
290         return ( slapi_sdn_compare( parent, &child_parent ) == 0 );
291 }
292
293 int slapi_sdn_isgrandparent( const Slapi_DN *parent, const Slapi_DN *child )
294 {
295         Slapi_DN child_grandparent;
296
297         slapi_sdn_get_ndn( child );
298
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;
303         }
304
305         dnParent( &child_grandparent.ndn, &child_grandparent.ndn );
306
307         return ( slapi_sdn_compare( parent, &child_grandparent ) == 0 );
308 }
309
310 int slapi_sdn_get_ndn_len( const Slapi_DN *sdn )
311 {
312         slapi_sdn_get_ndn( sdn );
313
314         return sdn->ndn.bv_len;
315 }
316
317 int slapi_sdn_scope_test( const Slapi_DN *dn, const Slapi_DN *base, int scope )
318 {
319         int rc;
320
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;
334         }
335
336         return rc;
337 }
338
339 void slapi_rdn_init( Slapi_RDN *rdn )
340 {
341         rdn->flag = 0;
342         BER_BVZERO( &rdn->bv );
343         rdn->rdn = NULL;
344 }
345
346 Slapi_RDN *slapi_rdn_new( void )
347 {
348         Slapi_RDN *rdn;
349
350         rdn = (Slapi_RDN *)slapi_ch_malloc( sizeof(*rdn ));
351         slapi_rdn_init( rdn );
352
353         return rdn;
354 }
355
356 Slapi_RDN *slapi_rdn_new_dn( const char *dn )
357 {
358         Slapi_RDN *rdn;
359
360         rdn = slapi_rdn_new();
361         slapi_rdn_init_dn( rdn, dn );
362         return rdn;
363 }
364
365 Slapi_RDN *slapi_rdn_new_sdn( const Slapi_DN *sdn )
366 {
367         return slapi_rdn_new_dn( slapi_sdn_get_dn( sdn ) );
368 }
369
370 Slapi_RDN *slapi_rdn_new_rdn( const Slapi_RDN *fromrdn )
371 {
372         return slapi_rdn_new_dn( fromrdn->bv.bv_val );
373 }
374
375 void slapi_rdn_init_dn( Slapi_RDN *rdn, const char *dn )
376 {
377         slapi_rdn_init( rdn );
378         slapi_rdn_set_dn( rdn, dn );
379 }
380
381 void slapi_rdn_init_sdn( Slapi_RDN *rdn, const Slapi_DN *sdn )
382 {
383         slapi_rdn_init( rdn );
384         slapi_rdn_set_sdn( rdn, sdn );
385 }
386
387 void slapi_rdn_init_rdn( Slapi_RDN *rdn, const Slapi_RDN *fromrdn )
388 {
389         slapi_rdn_init( rdn );
390         slapi_rdn_set_rdn( rdn, fromrdn );
391 }
392
393 void slapi_rdn_set_dn( Slapi_RDN *rdn, const char *dn )
394 {
395         struct berval bv;
396
397         slapi_rdn_done( rdn );
398
399         BER_BVZERO( &bv );
400
401         if ( dn != NULL ) {
402                 bv.bv_val = (char *)dn;
403                 bv.bv_len = strlen( dn );
404         }
405
406         dnExtractRdn( &bv, &rdn->bv, NULL );
407         rdn->flag |= FLAG_DN;
408 }
409
410 void slapi_rdn_set_sdn( Slapi_RDN *rdn, const Slapi_DN *sdn )
411 {
412         slapi_rdn_set_dn( rdn, slapi_sdn_get_dn( sdn ) );
413 }
414
415 void slapi_rdn_set_rdn( Slapi_RDN *rdn, const Slapi_RDN *fromrdn )
416 {
417         slapi_rdn_set_dn( rdn, fromrdn->bv.bv_val );
418 }
419
420 void slapi_rdn_free( Slapi_RDN **rdn )
421 {
422         slapi_rdn_done( *rdn );
423         slapi_ch_free( (void **)rdn );
424 }
425
426 void slapi_rdn_done( Slapi_RDN *rdn )
427 {
428         if ( rdn->rdn != NULL ) {
429                 ldap_rdnfree( rdn->rdn );
430                 rdn->rdn = NULL;
431         }
432         slapi_ch_free_string( &rdn->bv.bv_val );
433         slapi_rdn_init( rdn );
434 }
435
436 const char *slapi_rdn_get_rdn( const Slapi_RDN *rdn )
437 {
438         return rdn->bv.bv_val;
439 }
440
441 static int slapi_int_rdn_explode( Slapi_RDN *rdn )
442 {
443         char *next;
444
445         if ( rdn->rdn != NULL ) {
446                 return LDAP_SUCCESS;
447         }
448
449         return ldap_bv2rdn( &rdn->bv, &rdn->rdn, &next, LDAP_DN_FORMAT_LDAP );
450 }
451
452 static int slapi_int_rdn_implode( Slapi_RDN *rdn )
453 {
454         struct berval bv;
455         int rc;
456
457         if ( rdn->rdn == NULL ) {
458                 return LDAP_SUCCESS;
459         }
460
461         rc = ldap_rdn2bv( rdn->rdn, &bv, LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY );
462         if ( rc != LDAP_SUCCESS ) {
463                 return rc;
464         }
465
466         slapi_ch_free_string( &rdn->bv.bv_val );
467         rdn->bv = bv;
468
469         return 0;
470 }
471
472 int slapi_rdn_get_num_components( Slapi_RDN *rdn )
473 {
474         int i;
475
476         if ( slapi_int_rdn_explode( rdn ) != LDAP_SUCCESS )
477                 return 0;
478
479         for ( i = 0; rdn->rdn[i] != NULL; i++ )
480                 ;
481
482         return i;
483 }
484
485 int slapi_rdn_get_first( Slapi_RDN *rdn, char **type, char **value )
486 {
487         return slapi_rdn_get_next( rdn, 0, type, value );
488 }
489
490 int slapi_rdn_get_next( Slapi_RDN *rdn, int index, char **type, char **value )
491 {
492         slapi_int_rdn_explode( rdn );
493
494         if ( rdn->rdn == NULL || rdn->rdn[index] == NULL )
495                 return -1;
496
497         *type = rdn->rdn[index]->la_attr.bv_val;
498         *value = rdn->rdn[index]->la_value.bv_val;
499
500         return index + 1;
501 }
502
503 int slapi_rdn_get_index( Slapi_RDN *rdn, const char *type, const char *value, size_t length )
504 {
505         int i, match;
506         struct berval bv;
507         AttributeDescription *ad = NULL;
508         const char *text;
509
510         slapi_int_rdn_explode( rdn );
511
512         if ( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
513                 return -1;
514         }
515
516         bv.bv_val = (char *)value;
517         bv.bv_len = length;
518
519         for ( i = 0; rdn->rdn[i] != NULL; i++ ) {
520                 if ( !slapi_attr_types_equivalent( ad->ad_cname.bv_val, type ))
521                         continue;
522
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;
526
527                 if ( match == 0 )
528                         return i;
529         }
530
531         return -1;
532 }
533
534 int slapi_rdn_get_index_attr( Slapi_RDN *rdn, const char *type, char **value )
535 {
536         int i;
537
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;
542                 }
543         }
544
545         return -1;
546 }
547
548 int slapi_rdn_contains( Slapi_RDN *rdn, const char *type, const char *value, size_t length )
549 {
550         return ( slapi_rdn_get_index( rdn, type, value, length ) != -1 );
551 }
552
553 int slapi_rdn_contains_attr( Slapi_RDN *rdn, const char *type, char **value )
554 {
555         return ( slapi_rdn_get_index_attr( rdn, type, value ) != -1 );
556 }
557
558 int slapi_rdn_compare( Slapi_RDN *rdn1, Slapi_RDN *rdn2 )
559 {
560         struct berval nrdn1 = BER_BVNULL;
561         struct berval nrdn2 = BER_BVNULL;
562         int match;
563
564         rdnNormalize( 0, NULL, NULL, (struct berval *)&rdn1->bv, &nrdn1, NULL );
565         rdnNormalize( 0, NULL, NULL, (struct berval *)&rdn2->bv, &nrdn2, NULL );
566
567         if ( rdnMatch( &match, 0, NULL, NULL, &nrdn1, (void *)&nrdn2 ) != LDAP_SUCCESS) {
568                 match = -1;
569         }
570
571         return match;
572 }
573
574 int slapi_rdn_isempty( const Slapi_RDN *rdn )
575 {
576         return ( BER_BVISEMPTY( &rdn->bv ) ); 
577 }
578
579 int slapi_rdn_add( Slapi_RDN *rdn, const char *type, const char *value )
580 {
581         char *s;
582         size_t len;
583
584         len = strlen(type) + 1 + strlen( value );
585         if ( !BER_BVISEMPTY( &rdn->bv ) ) {
586                 len += 1 + rdn->bv.bv_len;
587         }
588
589         s = slapi_ch_malloc( len + 1 );
590
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 );
595         }
596
597         slapi_rdn_done( rdn );
598
599         rdn->bv.bv_len = len;
600         rdn->bv.bv_val = s;
601
602         return 1;
603 }
604
605 int slapi_rdn_remove_index( Slapi_RDN *rdn, int atindex )
606 {
607         int count, i;
608
609         count = slapi_rdn_get_num_components( rdn );
610
611         if ( atindex < 0 || atindex >= count )
612                 return 0;
613
614         if ( rdn->rdn == NULL )
615                 return 0;
616
617         slapi_ch_free_string( &rdn->rdn[atindex]->la_attr.bv_val );
618         slapi_ch_free_string( &rdn->rdn[atindex]->la_value.bv_val );
619
620         for ( i = atindex; i < count; i++ ) {
621                 rdn->rdn[i] = rdn->rdn[i + 1];
622         }
623
624         if ( slapi_int_rdn_implode( rdn ) != LDAP_SUCCESS )
625                 return 0;
626
627         return 1;
628 }
629
630 int slapi_rdn_remove( Slapi_RDN *rdn, const char *type, const char *value, size_t length )
631 {
632         int index = slapi_rdn_get_index( rdn, type, value, length );
633
634         return slapi_rdn_remove_index( rdn, index );
635 }
636
637 int slapi_rdn_remove_attr( Slapi_RDN *rdn, const char *type )
638 {
639         char *value;
640         int index = slapi_rdn_get_index_attr( rdn, type, &value );
641
642         return slapi_rdn_remove_index( rdn, index );
643 }
644
645 Slapi_DN *slapi_sdn_add_rdn( Slapi_DN *sdn, const Slapi_RDN *rdn )
646 {
647         struct berval bv;
648
649         build_new_dn( &bv, &sdn->dn, (struct berval *)&rdn->bv, NULL );
650
651         slapi_sdn_done( sdn );
652         sdn->dn = bv;
653
654         return sdn;
655 }
656
657 Slapi_DN *slapi_sdn_set_parent( Slapi_DN *sdn, const Slapi_DN *parentdn )
658 {
659         Slapi_RDN rdn;
660
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 );
665
666         return sdn;
667 }
668
669 #endif /* LDAP_SLAPI */