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