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