Back to index

openldap  2.4.31
slapi_dn.c
Go to the documentation of this file.
00001 /* $OpenLDAP$ */
00002 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00003  *
00004  * Copyright 2005-2012 The OpenLDAP Foundation.
00005  * All rights reserved.
00006  *
00007  * Redistribution and use in source and binary forms, with or without
00008  * modification, are permitted only as authorized by the OpenLDAP
00009  * Public License.
00010  *
00011  * A copy of this license is available in the file LICENSE in the
00012  * top-level directory of the distribution or, alternatively, at
00013  * <http://www.OpenLDAP.org/license.html>.
00014  */
00015 /* ACKNOWLEDGEMENTS:
00016  * This work was initially developed by Luke Howard for inclusion
00017  * in OpenLDAP Software.
00018  */
00019 
00020 #include "portable.h"
00021 
00022 #include <ac/string.h>
00023 #include <ac/stdarg.h>
00024 #include <ac/ctype.h>
00025 #include <ac/unistd.h>
00026 #include <ldap_pvt.h>
00027 
00028 #include <slap.h>
00029 #include <slapi.h>
00030 
00031 #ifdef LDAP_SLAPI
00032 #define FLAG_DN 0x1
00033 #define FLAG_NDN 0x2
00034 
00035 void slapi_sdn_init( Slapi_DN *sdn )
00036 {
00037        sdn->flag = 0;
00038        BER_BVZERO( &sdn->dn );
00039        BER_BVZERO( &sdn->ndn );
00040 }
00041 
00042 Slapi_DN *slapi_sdn_new( void )
00043 {
00044        Slapi_DN *sdn;
00045 
00046        sdn = (Slapi_DN *)slapi_ch_malloc( sizeof(*sdn ));
00047        slapi_sdn_init( sdn );
00048 
00049        return sdn;
00050 }
00051 
00052 void slapi_sdn_done( Slapi_DN *sdn )
00053 {
00054        if ( sdn == NULL )
00055               return;
00056 
00057        if ( sdn->flag & FLAG_DN ) {
00058               slapi_ch_free_string( &sdn->dn.bv_val );
00059        }
00060        if ( sdn->flag & FLAG_NDN ) {
00061               slapi_ch_free_string( &sdn->ndn.bv_val );
00062        }
00063 
00064        slapi_sdn_init( sdn );
00065 }
00066 
00067 void slapi_sdn_free( Slapi_DN **sdn )
00068 {
00069        slapi_sdn_done( *sdn );
00070        slapi_ch_free( (void **)sdn );
00071 }
00072 
00073 const char *slapi_sdn_get_dn( const Slapi_DN *sdn )
00074 {
00075        if ( !BER_BVISNULL( &sdn->dn ) )
00076               return sdn->dn.bv_val;
00077        else
00078               return sdn->ndn.bv_val;
00079 }
00080 
00081 const char *slapi_sdn_get_ndn( const Slapi_DN *sdn )
00082 {
00083        if ( BER_BVISNULL( &sdn->ndn ) ) {
00084               dnNormalize( 0, NULL, NULL,
00085                      (struct berval *)&sdn->dn, (struct berval *)&sdn->ndn, NULL );
00086               ((Slapi_DN *)sdn)->flag |= FLAG_NDN;
00087        }
00088 
00089        return sdn->ndn.bv_val;
00090 }
00091 
00092 Slapi_DN *slapi_sdn_new_dn_byval( const char *dn )
00093 {
00094        Slapi_DN *sdn;
00095 
00096        sdn = slapi_sdn_new();
00097        return slapi_sdn_set_dn_byval( sdn, dn );
00098 }
00099 
00100 Slapi_DN *slapi_sdn_new_ndn_byval( const char *ndn )
00101 {
00102        Slapi_DN *sdn;
00103 
00104        sdn = slapi_sdn_new();
00105        return slapi_sdn_set_ndn_byval( sdn, ndn );
00106 }
00107 
00108 Slapi_DN *slapi_sdn_new_dn_byref( const char *dn )
00109 {
00110        Slapi_DN *sdn;
00111 
00112        sdn = slapi_sdn_new();
00113        return slapi_sdn_set_dn_byref( sdn, dn );
00114 }
00115 
00116 Slapi_DN *slapi_sdn_new_ndn_byref( const char *ndn )
00117 {
00118        Slapi_DN *sdn;
00119 
00120        sdn = slapi_sdn_new();
00121        return slapi_sdn_set_ndn_byref( sdn, ndn );
00122 }
00123 
00124 Slapi_DN *slapi_sdn_new_dn_passin( const char *dn )
00125 {
00126        Slapi_DN *sdn;
00127 
00128        sdn = slapi_sdn_new();
00129        return slapi_sdn_set_dn_passin( sdn, dn );
00130 }
00131 
00132 Slapi_DN *slapi_sdn_set_dn_byval( Slapi_DN *sdn, const char *dn )
00133 {
00134        if ( sdn == NULL ) {
00135               return NULL;
00136        }
00137 
00138        slapi_sdn_done( sdn );
00139        if ( dn != NULL ) {
00140               sdn->dn.bv_val = slapi_ch_strdup( dn );
00141               sdn->dn.bv_len = strlen( dn );
00142        }
00143        sdn->flag |= FLAG_DN;
00144 
00145        return sdn;
00146 }
00147 
00148 Slapi_DN *slapi_sdn_set_dn_byref( Slapi_DN *sdn, const char *dn )
00149 {
00150        if ( sdn == NULL )
00151               return NULL;
00152 
00153        slapi_sdn_done( sdn );
00154        if ( dn != NULL ) {
00155               sdn->dn.bv_val = (char *)dn;
00156               sdn->dn.bv_len = strlen( dn );
00157        }
00158 
00159        return sdn;
00160 }
00161 
00162 Slapi_DN *slapi_sdn_set_dn_passin( Slapi_DN *sdn, const char *dn )
00163 {
00164        if ( sdn == NULL )
00165               return NULL;
00166 
00167        slapi_sdn_set_dn_byref( sdn, dn );
00168        sdn->flag |= FLAG_DN;
00169 
00170        return sdn;
00171 }
00172 
00173 Slapi_DN *slapi_sdn_set_ndn_byval( Slapi_DN *sdn, const char *ndn )
00174 {
00175        if ( sdn == NULL ) {
00176               return NULL;
00177        }
00178 
00179        slapi_sdn_done( sdn );
00180        if ( ndn != NULL ) {
00181               sdn->ndn.bv_val = slapi_ch_strdup( ndn );
00182               sdn->ndn.bv_len = strlen( ndn );
00183        }
00184        sdn->flag |= FLAG_NDN;
00185 
00186        return sdn;
00187 }
00188 
00189 Slapi_DN *slapi_sdn_set_ndn_byref( Slapi_DN *sdn, const char *ndn )
00190 {
00191        if ( sdn == NULL )
00192               return NULL;
00193 
00194        slapi_sdn_done( sdn );
00195        if ( ndn != NULL ) {
00196               sdn->ndn.bv_val = (char *)ndn;
00197               sdn->ndn.bv_len = strlen( ndn );
00198        }
00199 
00200        return sdn;
00201 }
00202 
00203 Slapi_DN *slapi_sdn_set_ndn_passin( Slapi_DN *sdn, const char *ndn )
00204 {
00205        if ( sdn == NULL )
00206               return NULL;
00207 
00208        slapi_sdn_set_ndn_byref( sdn, ndn );
00209        sdn->flag |= FLAG_NDN;
00210 
00211        return sdn;
00212 }
00213 
00214 void slapi_sdn_get_parent( const Slapi_DN *sdn, Slapi_DN *sdn_parent )
00215 {
00216        struct berval parent_dn;
00217 
00218        if ( !(sdn->flag & FLAG_DN) ) {
00219               dnParent( (struct berval *)&sdn->ndn, &parent_dn );
00220               slapi_sdn_set_ndn_byval( sdn_parent, parent_dn.bv_val );
00221        } else {
00222               dnParent( (struct berval *)&sdn->dn, &parent_dn );
00223               slapi_sdn_set_dn_byval( sdn_parent, parent_dn.bv_val );
00224        }
00225 }
00226 
00227 void slapi_sdn_get_backend_parent( const Slapi_DN *sdn,
00228        Slapi_DN *sdn_parent,
00229        const Slapi_Backend *backend )
00230 {
00231        slapi_sdn_get_ndn( sdn );
00232 
00233        if ( backend == NULL ||
00234             be_issuffix( (Slapi_Backend *)backend, (struct berval *)&sdn->ndn ) == 0 ) {
00235               slapi_sdn_get_parent( sdn, sdn_parent );
00236        }
00237 
00238 }
00239 
00240 Slapi_DN * slapi_sdn_dup( const Slapi_DN *sdn )
00241 {
00242        Slapi_DN *new_sdn;
00243 
00244        new_sdn = slapi_sdn_new();
00245        slapi_sdn_copy( sdn, new_sdn );
00246 
00247        return new_sdn;
00248 }
00249 
00250 void slapi_sdn_copy( const Slapi_DN *from, Slapi_DN *to )
00251 {
00252        slapi_sdn_set_dn_byval( to, from->dn.bv_val );
00253 }
00254 
00255 int slapi_sdn_compare( const Slapi_DN *sdn1, const Slapi_DN *sdn2 )
00256 {
00257        int match = -1;
00258 
00259        slapi_sdn_get_ndn( sdn1 );
00260        slapi_sdn_get_ndn( sdn2 );
00261 
00262        dnMatch( &match, 0, slap_schema.si_syn_distinguishedName, NULL,
00263               (struct berval *)&sdn1->ndn, (void *)&sdn2->ndn );
00264 
00265        return match;
00266 }
00267 
00268 int slapi_sdn_isempty( const Slapi_DN *sdn)
00269 {
00270        return ( BER_BVISEMPTY( &sdn->dn ) && BER_BVISEMPTY( &sdn->ndn ) );
00271 }
00272 
00273 int slapi_sdn_issuffix( const Slapi_DN *sdn, const Slapi_DN *suffix_sdn )
00274 {
00275        slapi_sdn_get_ndn( sdn );
00276        slapi_sdn_get_ndn( suffix_sdn );
00277 
00278        return dnIsSuffix( &sdn->ndn, &suffix_sdn->ndn );
00279 }
00280 
00281 int slapi_sdn_isparent( const Slapi_DN *parent, const Slapi_DN *child )
00282 {
00283        Slapi_DN child_parent;
00284 
00285        slapi_sdn_get_ndn( child );
00286 
00287        slapi_sdn_init( &child_parent );
00288        dnParent( (struct berval *)&child->ndn, &child_parent.ndn );
00289 
00290        return ( slapi_sdn_compare( parent, &child_parent ) == 0 );
00291 }
00292 
00293 int slapi_sdn_isgrandparent( const Slapi_DN *parent, const Slapi_DN *child )
00294 {
00295        Slapi_DN child_grandparent;
00296 
00297        slapi_sdn_get_ndn( child );
00298 
00299        slapi_sdn_init( &child_grandparent );
00300        dnParent( (struct berval *)&child->ndn, &child_grandparent.ndn );
00301        if ( child_grandparent.ndn.bv_len == 0 ) {
00302               return 0;
00303        }
00304 
00305        dnParent( &child_grandparent.ndn, &child_grandparent.ndn );
00306 
00307        return ( slapi_sdn_compare( parent, &child_grandparent ) == 0 );
00308 }
00309 
00310 int slapi_sdn_get_ndn_len( const Slapi_DN *sdn )
00311 {
00312        slapi_sdn_get_ndn( sdn );
00313 
00314        return sdn->ndn.bv_len;
00315 }
00316 
00317 int slapi_sdn_scope_test( const Slapi_DN *dn, const Slapi_DN *base, int scope )
00318 {
00319        int rc;
00320 
00321        switch ( scope ) {
00322        case LDAP_SCOPE_BASE:
00323               rc = ( slapi_sdn_compare( dn, base ) == 0 );
00324               break;
00325        case LDAP_SCOPE_ONELEVEL:
00326               rc = slapi_sdn_isparent( base, dn );
00327               break;
00328        case LDAP_SCOPE_SUBTREE:
00329               rc = slapi_sdn_issuffix( dn, base );
00330               break;
00331        default:
00332               rc = 0;
00333               break;
00334        }
00335 
00336        return rc;
00337 }
00338 
00339 void slapi_rdn_init( Slapi_RDN *rdn )
00340 {
00341        rdn->flag = 0;
00342        BER_BVZERO( &rdn->bv );
00343        rdn->rdn = NULL;
00344 }
00345 
00346 Slapi_RDN *slapi_rdn_new( void )
00347 {
00348        Slapi_RDN *rdn;
00349 
00350        rdn = (Slapi_RDN *)slapi_ch_malloc( sizeof(*rdn ));
00351        slapi_rdn_init( rdn );
00352 
00353        return rdn;
00354 }
00355 
00356 Slapi_RDN *slapi_rdn_new_dn( const char *dn )
00357 {
00358        Slapi_RDN *rdn;
00359 
00360        rdn = slapi_rdn_new();
00361        slapi_rdn_init_dn( rdn, dn );
00362        return rdn;
00363 }
00364 
00365 Slapi_RDN *slapi_rdn_new_sdn( const Slapi_DN *sdn )
00366 {
00367        return slapi_rdn_new_dn( slapi_sdn_get_dn( sdn ) );
00368 }
00369 
00370 Slapi_RDN *slapi_rdn_new_rdn( const Slapi_RDN *fromrdn )
00371 {
00372        return slapi_rdn_new_dn( fromrdn->bv.bv_val );
00373 }
00374 
00375 void slapi_rdn_init_dn( Slapi_RDN *rdn, const char *dn )
00376 {
00377        slapi_rdn_init( rdn );
00378        slapi_rdn_set_dn( rdn, dn );
00379 }
00380 
00381 void slapi_rdn_init_sdn( Slapi_RDN *rdn, const Slapi_DN *sdn )
00382 {
00383        slapi_rdn_init( rdn );
00384        slapi_rdn_set_sdn( rdn, sdn );
00385 }
00386 
00387 void slapi_rdn_init_rdn( Slapi_RDN *rdn, const Slapi_RDN *fromrdn )
00388 {
00389        slapi_rdn_init( rdn );
00390        slapi_rdn_set_rdn( rdn, fromrdn );
00391 }
00392 
00393 void slapi_rdn_set_dn( Slapi_RDN *rdn, const char *dn )
00394 {
00395        struct berval bv;
00396 
00397        slapi_rdn_done( rdn );
00398 
00399        BER_BVZERO( &bv );
00400 
00401        if ( dn != NULL ) {
00402               bv.bv_val = (char *)dn;
00403               bv.bv_len = strlen( dn );
00404        }
00405 
00406        dnExtractRdn( &bv, &rdn->bv, NULL );
00407        rdn->flag |= FLAG_DN;
00408 }
00409 
00410 void slapi_rdn_set_sdn( Slapi_RDN *rdn, const Slapi_DN *sdn )
00411 {
00412        slapi_rdn_set_dn( rdn, slapi_sdn_get_dn( sdn ) );
00413 }
00414 
00415 void slapi_rdn_set_rdn( Slapi_RDN *rdn, const Slapi_RDN *fromrdn )
00416 {
00417        slapi_rdn_set_dn( rdn, fromrdn->bv.bv_val );
00418 }
00419 
00420 void slapi_rdn_free( Slapi_RDN **rdn )
00421 {
00422        slapi_rdn_done( *rdn );
00423        slapi_ch_free( (void **)rdn );
00424 }
00425 
00426 void slapi_rdn_done( Slapi_RDN *rdn )
00427 {
00428        if ( rdn->rdn != NULL ) {
00429               ldap_rdnfree( rdn->rdn );
00430               rdn->rdn = NULL;
00431        }
00432        slapi_ch_free_string( &rdn->bv.bv_val );
00433        slapi_rdn_init( rdn );
00434 }
00435 
00436 const char *slapi_rdn_get_rdn( const Slapi_RDN *rdn )
00437 {
00438        return rdn->bv.bv_val;
00439 }
00440 
00441 static int slapi_int_rdn_explode( Slapi_RDN *rdn )
00442 {
00443        char *next;
00444 
00445        if ( rdn->rdn != NULL ) {
00446               return LDAP_SUCCESS;
00447        }
00448 
00449        return ldap_bv2rdn( &rdn->bv, &rdn->rdn, &next, LDAP_DN_FORMAT_LDAP );
00450 }
00451 
00452 static int slapi_int_rdn_implode( Slapi_RDN *rdn )
00453 {
00454        struct berval bv;
00455        int rc;
00456 
00457        if ( rdn->rdn == NULL ) {
00458               return LDAP_SUCCESS;
00459        }
00460 
00461        rc = ldap_rdn2bv( rdn->rdn, &bv, LDAP_DN_FORMAT_LDAPV3 | LDAP_DN_PRETTY );
00462        if ( rc != LDAP_SUCCESS ) {
00463               return rc;
00464        }
00465 
00466        slapi_ch_free_string( &rdn->bv.bv_val );
00467        rdn->bv = bv;
00468 
00469        return 0;
00470 }
00471 
00472 int slapi_rdn_get_num_components( Slapi_RDN *rdn )
00473 {
00474        int i;
00475 
00476        if ( slapi_int_rdn_explode( rdn ) != LDAP_SUCCESS )
00477               return 0;
00478 
00479        for ( i = 0; rdn->rdn[i] != NULL; i++ )
00480               ;
00481 
00482        return i;
00483 }
00484 
00485 int slapi_rdn_get_first( Slapi_RDN *rdn, char **type, char **value )
00486 {
00487        return slapi_rdn_get_next( rdn, 0, type, value );
00488 }
00489 
00490 int slapi_rdn_get_next( Slapi_RDN *rdn, int index, char **type, char **value )
00491 {
00492        slapi_int_rdn_explode( rdn );
00493 
00494        if ( rdn->rdn == NULL || rdn->rdn[index] == NULL )
00495               return -1;
00496 
00497        *type = rdn->rdn[index]->la_attr.bv_val;
00498        *value = rdn->rdn[index]->la_value.bv_val;
00499 
00500        return index + 1;
00501 }
00502 
00503 int slapi_rdn_get_index( Slapi_RDN *rdn, const char *type, const char *value, size_t length )
00504 {
00505        int i, match;
00506        struct berval bv;
00507        AttributeDescription *ad = NULL;
00508        const char *text;
00509 
00510        slapi_int_rdn_explode( rdn );
00511 
00512        if ( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
00513               return -1;
00514        }
00515 
00516        bv.bv_val = (char *)value;
00517        bv.bv_len = length;
00518 
00519        for ( i = 0; rdn->rdn[i] != NULL; i++ ) {
00520               if ( !slapi_attr_types_equivalent( ad->ad_cname.bv_val, type ))
00521                      continue;
00522 
00523               if ( value_match( &match, ad, ad->ad_type->sat_equality, 0,
00524                      &rdn->rdn[i]->la_value, (void *)&bv, &text ) != LDAP_SUCCESS )
00525                      match = -1;
00526 
00527               if ( match == 0 )
00528                      return i;
00529        }
00530 
00531        return -1;
00532 }
00533 
00534 int slapi_rdn_get_index_attr( Slapi_RDN *rdn, const char *type, char **value )
00535 {
00536        int i;
00537 
00538        for ( i = 0; rdn->rdn[i] != NULL; i++ ) {
00539               if ( slapi_attr_types_equivalent( rdn->rdn[i]->la_attr.bv_val, type ) ) {
00540                      *value = rdn->rdn[i]->la_value.bv_val;
00541                      return i;
00542               }
00543        }
00544 
00545        return -1;
00546 }
00547 
00548 int slapi_rdn_contains( Slapi_RDN *rdn, const char *type, const char *value, size_t length )
00549 {
00550        return ( slapi_rdn_get_index( rdn, type, value, length ) != -1 );
00551 }
00552 
00553 int slapi_rdn_contains_attr( Slapi_RDN *rdn, const char *type, char **value )
00554 {
00555        return ( slapi_rdn_get_index_attr( rdn, type, value ) != -1 );
00556 }
00557 
00558 int slapi_rdn_compare( Slapi_RDN *rdn1, Slapi_RDN *rdn2 )
00559 {
00560        struct berval nrdn1 = BER_BVNULL;
00561        struct berval nrdn2 = BER_BVNULL;
00562        int match;
00563 
00564        rdnNormalize( 0, NULL, NULL, (struct berval *)&rdn1->bv, &nrdn1, NULL );
00565        rdnNormalize( 0, NULL, NULL, (struct berval *)&rdn2->bv, &nrdn2, NULL );
00566 
00567        if ( rdnMatch( &match, 0, NULL, NULL, &nrdn1, (void *)&nrdn2 ) != LDAP_SUCCESS) {
00568               match = -1;
00569        }
00570 
00571        return match;
00572 }
00573 
00574 int slapi_rdn_isempty( const Slapi_RDN *rdn )
00575 {
00576        return ( BER_BVISEMPTY( &rdn->bv ) ); 
00577 }
00578 
00579 int slapi_rdn_add( Slapi_RDN *rdn, const char *type, const char *value )
00580 {
00581        char *s;
00582        size_t len;
00583 
00584        len = strlen(type) + 1 + strlen( value );
00585        if ( !BER_BVISEMPTY( &rdn->bv ) ) {
00586               len += 1 + rdn->bv.bv_len;
00587        }
00588 
00589        s = slapi_ch_malloc( len + 1 );
00590 
00591        if ( BER_BVISEMPTY( &rdn->bv ) ) {
00592               snprintf( s, len + 1, "%s=%s", type, value );
00593        } else {
00594               snprintf( s, len + 1, "%s=%s+%s", type, value, rdn->bv.bv_val );
00595        }
00596 
00597        slapi_rdn_done( rdn );
00598 
00599        rdn->bv.bv_len = len;
00600        rdn->bv.bv_val = s;
00601 
00602        return 1;
00603 }
00604 
00605 int slapi_rdn_remove_index( Slapi_RDN *rdn, int atindex )
00606 {
00607        int count, i;
00608 
00609        count = slapi_rdn_get_num_components( rdn );
00610 
00611        if ( atindex < 0 || atindex >= count )
00612               return 0;
00613 
00614        if ( rdn->rdn == NULL )
00615               return 0;
00616 
00617        slapi_ch_free_string( &rdn->rdn[atindex]->la_attr.bv_val );
00618        slapi_ch_free_string( &rdn->rdn[atindex]->la_value.bv_val );
00619 
00620        for ( i = atindex; i < count; i++ ) {
00621               rdn->rdn[i] = rdn->rdn[i + 1];
00622        }
00623 
00624        if ( slapi_int_rdn_implode( rdn ) != LDAP_SUCCESS )
00625               return 0;
00626 
00627        return 1;
00628 }
00629 
00630 int slapi_rdn_remove( Slapi_RDN *rdn, const char *type, const char *value, size_t length )
00631 {
00632        int index = slapi_rdn_get_index( rdn, type, value, length );
00633 
00634        return slapi_rdn_remove_index( rdn, index );
00635 }
00636 
00637 int slapi_rdn_remove_attr( Slapi_RDN *rdn, const char *type )
00638 {
00639        char *value;
00640        int index = slapi_rdn_get_index_attr( rdn, type, &value );
00641 
00642        return slapi_rdn_remove_index( rdn, index );
00643 }
00644 
00645 Slapi_DN *slapi_sdn_add_rdn( Slapi_DN *sdn, const Slapi_RDN *rdn )
00646 {
00647        struct berval bv;
00648 
00649        build_new_dn( &bv, &sdn->dn, (struct berval *)&rdn->bv, NULL );
00650 
00651        slapi_sdn_done( sdn );
00652        sdn->dn = bv;
00653 
00654        return sdn;
00655 }
00656 
00657 Slapi_DN *slapi_sdn_set_parent( Slapi_DN *sdn, const Slapi_DN *parentdn )
00658 {
00659        Slapi_RDN rdn;
00660 
00661        slapi_rdn_init_sdn( &rdn, sdn );
00662        slapi_sdn_set_dn_byref( sdn, slapi_sdn_get_dn( parentdn ) );
00663        slapi_sdn_add_rdn( sdn, &rdn );
00664        slapi_rdn_done( &rdn );
00665 
00666        return sdn;
00667 }
00668 
00669 #endif /* LDAP_SLAPI */