Back to index

openldap  2.4.31
slapi_utils.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 2002-2012 The OpenLDAP Foundation.
00005  * Portions Copyright 1997,2002-2003 IBM Corporation.
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted only as authorized by the OpenLDAP
00010  * Public License.
00011  *
00012  * A copy of this license is available in the file LICENSE in the
00013  * top-level directory of the distribution or, alternatively, at
00014  * <http://www.OpenLDAP.org/license.html>.
00015  */
00016 /* ACKNOWLEDGEMENTS:
00017  * This work was initially developed by IBM Corporation for use in
00018  * IBM products and subsequently ported to OpenLDAP Software by
00019  * Steve Omrani.  Additional significant contributors include:
00020  *   Luke Howard
00021  */
00022 
00023 #include "portable.h"
00024 
00025 #include <ac/string.h>
00026 #include <ac/stdarg.h>
00027 #include <ac/ctype.h>
00028 #include <ac/unistd.h>
00029 #include <lutil.h>
00030 
00031 #include <slap.h>
00032 #include <slapi.h>
00033 
00034 #include <netdb.h>
00035 
00036 #ifdef LDAP_SLAPI
00037 
00038 /*
00039  * server start time (should we use a struct timeval also in slapd?
00040  */
00041 static struct               timeval base_time;
00042 ldap_pvt_thread_mutex_t            slapi_hn_mutex;
00043 ldap_pvt_thread_mutex_t            slapi_time_mutex;
00044 
00045 struct slapi_mutex {
00046        ldap_pvt_thread_mutex_t mutex;
00047 };
00048 
00049 struct slapi_condvar {
00050        ldap_pvt_thread_cond_t cond;
00051        ldap_pvt_thread_mutex_t mutex;
00052 };
00053 
00054 static int checkBVString(const struct berval *bv)
00055 {
00056        ber_len_t i;
00057 
00058        for ( i = 0; i < bv->bv_len; i++ ) {
00059               if ( bv->bv_val[i] == '\0' )
00060                      return 0;
00061        }
00062        if ( bv->bv_val[i] != '\0' )
00063               return 0;
00064 
00065        return 1;
00066 }
00067 
00068 /*
00069  * This function converts an array of pointers to berval objects to
00070  * an array of berval objects.
00071  */
00072 
00073 int
00074 bvptr2obj(
00075        struct berval **bvptr, 
00076        BerVarray     *bvobj,
00077        unsigned *num )
00078 {
00079        int           rc = LDAP_SUCCESS;
00080        int           i;
00081        BerVarray     tmpberval;
00082 
00083        if ( bvptr == NULL || *bvptr == NULL ) {
00084               return LDAP_OTHER;
00085        }
00086 
00087        for ( i = 0; bvptr != NULL && bvptr[i] != NULL; i++ ) {
00088               ; /* EMPTY */
00089        }
00090        if ( num )
00091               *num = i;
00092 
00093        tmpberval = (BerVarray)slapi_ch_malloc( (i + 1)*sizeof(struct berval));
00094        if ( tmpberval == NULL ) {
00095               return LDAP_NO_MEMORY;
00096        } 
00097 
00098        for ( i = 0; bvptr[i] != NULL; i++ ) {
00099               tmpberval[i].bv_val = bvptr[i]->bv_val;
00100               tmpberval[i].bv_len = bvptr[i]->bv_len;
00101        }
00102        tmpberval[i].bv_val = NULL;
00103        tmpberval[i].bv_len = 0;
00104 
00105        if ( rc == LDAP_SUCCESS ) {
00106               *bvobj = tmpberval;
00107        }
00108 
00109        return rc;
00110 }
00111 
00112 Slapi_Entry *
00113 slapi_str2entry(
00114        char          *s, 
00115        int           flags )
00116 {
00117        return str2entry( s );
00118 }
00119 
00120 char *
00121 slapi_entry2str(
00122        Slapi_Entry   *e, 
00123        int           *len ) 
00124 {
00125        char          *ret = NULL;
00126        char          *s;
00127 
00128        ldap_pvt_thread_mutex_lock( &entry2str_mutex );
00129        s = entry2str( e, len );
00130        if ( s != NULL )
00131               ret = slapi_ch_strdup( s );
00132        ldap_pvt_thread_mutex_unlock( &entry2str_mutex );
00133 
00134        return ret;
00135 }
00136 
00137 char *
00138 slapi_entry_get_dn( Slapi_Entry *e ) 
00139 {
00140        return e->e_name.bv_val;
00141 }
00142 
00143 int
00144 slapi_x_entry_get_id( Slapi_Entry *e )
00145 {
00146        return e->e_id;
00147 }
00148 
00149 static int
00150 slapi_int_dn_pretty( struct berval *in, struct berval *out )
00151 {
00152        Syntax        *syntax = slap_schema.si_syn_distinguishedName;
00153 
00154        assert( syntax != NULL );
00155 
00156        return (syntax->ssyn_pretty)( syntax, in, out, NULL );
00157 }
00158 
00159 static int
00160 slapi_int_dn_normalize( struct berval *in, struct berval *out )
00161 {
00162        MatchingRule  *mr = slap_schema.si_mr_distinguishedNameMatch;
00163        Syntax        *syntax = slap_schema.si_syn_distinguishedName;
00164 
00165        assert( mr != NULL );
00166 
00167        return (mr->smr_normalize)( 0, syntax, mr, in, out, NULL );
00168 }
00169 
00170 void 
00171 slapi_entry_set_dn(
00172        Slapi_Entry   *e, 
00173        char          *ldn )
00174 {
00175        struct berval dn = BER_BVNULL;
00176 
00177        dn.bv_val = ldn;
00178        dn.bv_len = strlen( ldn );
00179 
00180        slapi_int_dn_pretty( &dn, &e->e_name );
00181        slapi_int_dn_normalize( &dn, &e->e_nname );
00182 }
00183 
00184 Slapi_Entry *
00185 slapi_entry_dup( Slapi_Entry *e ) 
00186 {
00187        return entry_dup( e );
00188 }
00189 
00190 int 
00191 slapi_entry_attr_delete(
00192        Slapi_Entry   *e,           
00193        char          *type ) 
00194 {
00195        AttributeDescription *ad = NULL;
00196        const char           *text;
00197 
00198        if ( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
00199               return 1;     /* LDAP_NO_SUCH_ATTRIBUTE */
00200        }
00201 
00202        if ( attr_delete( &e->e_attrs, ad ) == LDAP_SUCCESS ) {
00203               return 0;     /* attribute is deleted */
00204        } else {
00205               return -1;    /* something went wrong */
00206        }
00207 }
00208 
00209 Slapi_Entry *
00210 slapi_entry_alloc( void ) 
00211 {
00212        return (Slapi_Entry *)entry_alloc();
00213 }
00214 
00215 void 
00216 slapi_entry_free( Slapi_Entry *e ) 
00217 {
00218        if ( e != NULL )
00219               entry_free( e );
00220 }
00221 
00222 int 
00223 slapi_entry_attr_merge(
00224        Slapi_Entry   *e, 
00225        char          *type, 
00226        struct berval **vals ) 
00227 {
00228        AttributeDescription *ad = NULL;
00229        const char           *text;
00230        BerVarray            bv;
00231        int                  rc;
00232 
00233        rc = slap_str2ad( type, &ad, &text );
00234        if ( rc != LDAP_SUCCESS ) {
00235               return -1;
00236        }
00237        
00238        rc = bvptr2obj( vals, &bv, NULL );
00239        if ( rc != LDAP_SUCCESS ) {
00240               return -1;
00241        }
00242        
00243        rc = attr_merge_normalize( e, ad, bv, NULL );
00244        ch_free( bv );
00245 
00246        return rc;
00247 }
00248 
00249 int
00250 slapi_entry_attr_find(
00251        Slapi_Entry   *e, 
00252        char          *type, 
00253        Slapi_Attr    **attr ) 
00254 {
00255        AttributeDescription *ad = NULL;
00256        const char           *text;
00257        int                  rc;
00258 
00259        rc = slap_str2ad( type, &ad, &text );
00260        if ( rc != LDAP_SUCCESS ) {
00261               return -1;
00262        }
00263 
00264        *attr = attr_find( e->e_attrs, ad );
00265        if ( *attr == NULL ) {
00266               return -1;
00267        }
00268 
00269        return 0;
00270 }
00271 
00272 char *
00273 slapi_entry_attr_get_charptr( const Slapi_Entry *e, const char *type )
00274 {
00275        AttributeDescription *ad = NULL;
00276        const char *text;
00277        int rc;
00278        Attribute *attr;
00279 
00280        rc = slap_str2ad( type, &ad, &text );
00281        if ( rc != LDAP_SUCCESS ) {
00282               return NULL;
00283        }
00284 
00285        attr = attr_find( e->e_attrs, ad );
00286        if ( attr == NULL ) {
00287               return NULL;
00288        }
00289 
00290        if ( attr->a_vals != NULL && attr->a_vals[0].bv_len != 0 ) {
00291               const char *p;
00292 
00293               p = slapi_value_get_string( &attr->a_vals[0] );
00294               if ( p != NULL ) {
00295                      return slapi_ch_strdup( p );
00296               }
00297        }
00298 
00299        return NULL;
00300 }
00301 
00302 int
00303 slapi_entry_attr_get_int( const Slapi_Entry *e, const char *type )
00304 {
00305        AttributeDescription *ad = NULL;
00306        const char *text;
00307        int rc;
00308        Attribute *attr;
00309 
00310        rc = slap_str2ad( type, &ad, &text );
00311        if ( rc != LDAP_SUCCESS ) {
00312               return 0;
00313        }
00314 
00315        attr = attr_find( e->e_attrs, ad );
00316        if ( attr == NULL ) {
00317               return 0;
00318        }
00319 
00320        return slapi_value_get_int( attr->a_vals );
00321 }
00322 
00323 long
00324 slapi_entry_attr_get_long( const Slapi_Entry *e, const char *type )
00325 {
00326        AttributeDescription *ad = NULL;
00327        const char *text;
00328        int rc;
00329        Attribute *attr;
00330 
00331        rc = slap_str2ad( type, &ad, &text );
00332        if ( rc != LDAP_SUCCESS ) {
00333               return 0;
00334        }
00335 
00336        attr = attr_find( e->e_attrs, ad );
00337        if ( attr == NULL ) {
00338               return 0;
00339        }
00340 
00341        return slapi_value_get_long( attr->a_vals );
00342 }
00343 
00344 unsigned int
00345 slapi_entry_attr_get_uint( const Slapi_Entry *e, const char *type )
00346 {
00347        AttributeDescription *ad = NULL;
00348        const char *text;
00349        int rc;
00350        Attribute *attr;
00351 
00352        rc = slap_str2ad( type, &ad, &text );
00353        if ( rc != LDAP_SUCCESS ) {
00354               return 0;
00355        }
00356 
00357        attr = attr_find( e->e_attrs, ad );
00358        if ( attr == NULL ) {
00359               return 0;
00360        }
00361 
00362        return slapi_value_get_uint( attr->a_vals );
00363 }
00364 
00365 unsigned long
00366 slapi_entry_attr_get_ulong( const Slapi_Entry *e, const char *type )
00367 {
00368        AttributeDescription *ad = NULL;
00369        const char *text;
00370        int rc;
00371        Attribute *attr;
00372 
00373        rc = slap_str2ad( type, &ad, &text );
00374        if ( rc != LDAP_SUCCESS ) {
00375               return 0;
00376        }
00377 
00378        attr = attr_find( e->e_attrs, ad );
00379        if ( attr == NULL ) {
00380               return 0;
00381        }
00382 
00383        return slapi_value_get_ulong( attr->a_vals );
00384 }
00385 
00386 int
00387 slapi_entry_attr_hasvalue( Slapi_Entry *e, const char *type, const char *value )
00388 {
00389        struct berval bv;
00390        AttributeDescription *ad = NULL;
00391        const char *text;
00392        int rc;
00393        Attribute *attr;
00394        
00395        rc = slap_str2ad( type, &ad, &text );
00396        if ( rc != LDAP_SUCCESS ) {
00397               return 0;
00398        }
00399 
00400        attr = attr_find( e->e_attrs, ad );
00401        if ( attr == NULL ) {
00402               return 0;
00403        }
00404 
00405        bv.bv_val = (char *)value;
00406        bv.bv_len = strlen( value );
00407 
00408        return ( slapi_attr_value_find( attr, &bv ) != -1 );
00409 }
00410 
00411 void
00412 slapi_entry_attr_set_charptr(Slapi_Entry* e, const char *type, const char *value)
00413 {
00414        AttributeDescription *ad = NULL;
00415        const char           *text;
00416        int                  rc;
00417        struct berval        bv;
00418        
00419        rc = slap_str2ad( type, &ad, &text );
00420        if ( rc != LDAP_SUCCESS ) {
00421               return;
00422        }
00423        
00424        attr_delete ( &e->e_attrs, ad );
00425        if ( value != NULL ) {
00426               bv.bv_val = (char *)value;
00427               bv.bv_len = strlen(value);
00428               attr_merge_normalize_one( e, ad, &bv, NULL );
00429        }
00430 }
00431 
00432 void
00433 slapi_entry_attr_set_int( Slapi_Entry* e, const char *type, int l)
00434 {
00435        char buf[64];
00436 
00437        snprintf( buf, sizeof( buf ), "%d", l );
00438        slapi_entry_attr_set_charptr( e, type, buf );
00439 }
00440 
00441 void
00442 slapi_entry_attr_set_uint( Slapi_Entry* e, const char *type, unsigned int l)
00443 {
00444        char buf[64];
00445 
00446        snprintf( buf, sizeof( buf ), "%u", l );
00447        slapi_entry_attr_set_charptr( e, type, buf );
00448 }
00449 
00450 void
00451 slapi_entry_attr_set_long(Slapi_Entry* e, const char *type, long l)
00452 {
00453        char buf[64];
00454 
00455        snprintf( buf, sizeof( buf ), "%ld", l );
00456        slapi_entry_attr_set_charptr( e, type, buf );
00457 }
00458 
00459 void
00460 slapi_entry_attr_set_ulong(Slapi_Entry* e, const char *type, unsigned long l)
00461 {
00462        char buf[64];
00463 
00464        snprintf( buf, sizeof( buf ), "%lu", l );
00465        slapi_entry_attr_set_charptr( e, type, buf );
00466 }
00467 
00468 int
00469 slapi_is_rootdse( const char *dn )
00470 {
00471        return ( dn == NULL || dn[0] == '\0' );
00472 }
00473 
00474 int
00475 slapi_entry_has_children( const Slapi_Entry *e )
00476 {
00477        Slapi_PBlock *pb;
00478        Backend *be = select_backend( (struct berval *)&e->e_nname, 0 );
00479        int rc, hasSubordinates = 0;
00480 
00481        if ( be == NULL || be->be_has_subordinates == 0 ) {
00482               return 0;
00483        }
00484 
00485        pb = slapi_pblock_new();
00486        if ( pb == NULL ) {
00487               return 0;
00488        }
00489        slapi_int_connection_init_pb( pb, LDAP_REQ_SEARCH );
00490 
00491        rc = slapi_pblock_set( pb, SLAPI_TARGET_DN, slapi_entry_get_dn(
00492               (Entry *) e ));
00493        if ( rc == LDAP_SUCCESS ) {
00494               pb->pb_op->o_bd = be;
00495               rc = be->be_has_subordinates( pb->pb_op, (Entry *) e,
00496                      &hasSubordinates );
00497        }
00498 
00499        slapi_pblock_destroy( pb );
00500 
00501        return ( rc == LDAP_SUCCESS && hasSubordinates == LDAP_COMPARE_TRUE );
00502 }
00503 
00504 /*
00505  * Return approximate size of the entry rounded to the nearest
00506  * 1K. Only the size of the attribute values are counted in the
00507  * Sun implementation.
00508  *
00509  * http://docs.sun.com/source/816-6701-10/funcref.html#1017388
00510  */
00511 size_t slapi_entry_size(Slapi_Entry *e)
00512 {
00513        size_t size;
00514        Attribute *a;
00515        int i;
00516 
00517        for ( size = 0, a = e->e_attrs; a != NULL; a = a->a_next ) {
00518               for ( i = 0; a->a_vals[i].bv_val != NULL; i++ ) {
00519                      size += a->a_vals[i].bv_len + 1;
00520               }
00521        }
00522 
00523        size += 1023;
00524        size -= (size % 1024);
00525 
00526        return size;
00527 }
00528 
00529 /*
00530  * Add values to entry.
00531  *
00532  * Returns:
00533  *     LDAP_SUCCESS                Values added to entry
00534  *     LDAP_TYPE_OR_VALUE_EXISTS   One or more values exist in entry already
00535  *     LDAP_CONSTRAINT_VIOLATION   Any other error (odd, but it's the spec)
00536  */
00537 int
00538 slapi_entry_add_values( Slapi_Entry *e, const char *type, struct berval **vals )
00539 {
00540        Modification         mod;
00541        const char           *text;
00542        int                  rc;
00543        char                 textbuf[SLAP_TEXT_BUFLEN];
00544 
00545        mod.sm_op = LDAP_MOD_ADD;
00546        mod.sm_flags = 0;
00547        mod.sm_desc = NULL;
00548        mod.sm_type.bv_val = (char *)type;
00549        mod.sm_type.bv_len = strlen( type );
00550 
00551        rc = slap_str2ad( type, &mod.sm_desc, &text );
00552        if ( rc != LDAP_SUCCESS ) {
00553               return rc;
00554        }
00555 
00556        if ( vals == NULL ) {
00557               /* Apparently vals can be NULL
00558                * FIXME: sm_values = NULL ? */
00559               mod.sm_values = (BerVarray)ch_malloc( sizeof(struct berval) );
00560               mod.sm_values->bv_val = NULL;
00561               mod.sm_numvals = 0;
00562 
00563        } else {
00564               rc = bvptr2obj( vals, &mod.sm_values, &mod.sm_numvals );
00565               if ( rc != LDAP_SUCCESS ) {
00566                      return LDAP_CONSTRAINT_VIOLATION;
00567               }
00568        }
00569        mod.sm_nvalues = NULL;
00570 
00571        rc = modify_add_values( e, &mod, 0, &text, textbuf, sizeof(textbuf) );
00572 
00573        slapi_ch_free( (void **)&mod.sm_values );
00574 
00575        return (rc == LDAP_SUCCESS) ? LDAP_SUCCESS : LDAP_CONSTRAINT_VIOLATION;
00576 }
00577 
00578 int
00579 slapi_entry_add_values_sv( Slapi_Entry *e, const char *type, Slapi_Value **vals )
00580 {
00581        return slapi_entry_add_values( e, type, vals );
00582 }
00583 
00584 int
00585 slapi_entry_add_valueset(Slapi_Entry *e, const char *type, Slapi_ValueSet *vs)
00586 {
00587        AttributeDescription *ad = NULL;
00588        const char           *text;
00589        int                  rc;
00590        
00591        rc = slap_str2ad( type, &ad, &text );
00592        if ( rc != LDAP_SUCCESS ) {
00593               return -1;
00594        }
00595 
00596        return attr_merge_normalize( e, ad, *vs, NULL );
00597 }
00598 
00599 int
00600 slapi_entry_delete_values( Slapi_Entry *e, const char *type, struct berval **vals )
00601 {
00602        Modification         mod;
00603        const char           *text;
00604        int                  rc;
00605        char                 textbuf[SLAP_TEXT_BUFLEN];
00606 
00607        mod.sm_op = LDAP_MOD_DELETE;
00608        mod.sm_flags = 0;
00609        mod.sm_desc = NULL;
00610        mod.sm_type.bv_val = (char *)type;
00611        mod.sm_type.bv_len = strlen( type );
00612 
00613        if ( vals == NULL ) {
00614               /* If vals is NULL, this is a NOOP. */
00615               return LDAP_SUCCESS;
00616        }
00617        
00618        rc = slap_str2ad( type, &mod.sm_desc, &text );
00619        if ( rc != LDAP_SUCCESS ) {
00620               return rc;
00621        }
00622 
00623        if ( vals[0] == NULL ) {
00624               /* SLAPI doco says LDApb_opERATIONS_ERROR but LDAP_OTHER is better */
00625               return attr_delete( &e->e_attrs, mod.sm_desc ) ? LDAP_OTHER : LDAP_SUCCESS;
00626        }
00627 
00628        rc = bvptr2obj( vals, &mod.sm_values, &mod.sm_numvals );
00629        if ( rc != LDAP_SUCCESS ) {
00630               return LDAP_CONSTRAINT_VIOLATION;
00631        }
00632        mod.sm_nvalues = NULL;
00633 
00634        rc = modify_delete_values( e, &mod, 0, &text, textbuf, sizeof(textbuf) );
00635 
00636        slapi_ch_free( (void **)&mod.sm_values );
00637 
00638        return rc;
00639 }
00640 
00641 int
00642 slapi_entry_delete_values_sv( Slapi_Entry *e, const char *type, Slapi_Value **vals )
00643 {
00644        return slapi_entry_delete_values( e, type, vals );
00645 }
00646 
00647 int
00648 slapi_entry_merge_values_sv( Slapi_Entry *e, const char *type, Slapi_Value **vals )
00649 {
00650        return slapi_entry_attr_merge( e, (char *)type, vals );
00651 }
00652 
00653 int
00654 slapi_entry_add_value(Slapi_Entry *e, const char *type, const Slapi_Value *value)
00655 {
00656        AttributeDescription *ad = NULL;
00657        int                  rc;
00658        const char           *text;
00659 
00660        rc = slap_str2ad( type, &ad, &text );
00661        if ( rc != LDAP_SUCCESS ) {
00662               return -1;
00663        }
00664 
00665        rc = attr_merge_normalize_one( e, ad, (Slapi_Value *)value, NULL );
00666        if ( rc != LDAP_SUCCESS ) {
00667               return -1;
00668        }
00669 
00670        return 0;
00671 }
00672 
00673 int
00674 slapi_entry_add_string(Slapi_Entry *e, const char *type, const char *value)
00675 {
00676        Slapi_Value val;
00677 
00678        val.bv_val = (char *)value;
00679        val.bv_len = strlen( value );
00680 
00681        return slapi_entry_add_value( e, type, &val );
00682 }
00683 
00684 int
00685 slapi_entry_delete_string(Slapi_Entry *e, const char *type, const char *value)
00686 {
00687        Slapi_Value *vals[2];
00688        Slapi_Value val;
00689 
00690        val.bv_val = (char *)value;
00691        val.bv_len = strlen( value );
00692        vals[0] = &val;
00693        vals[1] = NULL;
00694 
00695        return slapi_entry_delete_values_sv( e, type, vals );   
00696 }
00697 
00698 int
00699 slapi_entry_attr_merge_sv( Slapi_Entry *e, const char *type, Slapi_Value **vals )
00700 {
00701        return slapi_entry_attr_merge( e, (char *)type, vals );
00702 }
00703 
00704 int
00705 slapi_entry_first_attr( const Slapi_Entry *e, Slapi_Attr **attr )
00706 {
00707        if ( e == NULL ) {
00708               return -1;
00709        }
00710 
00711        *attr = e->e_attrs;
00712 
00713        return ( *attr != NULL ) ? 0 : -1;
00714 }
00715 
00716 int
00717 slapi_entry_next_attr( const Slapi_Entry *e, Slapi_Attr *prevattr, Slapi_Attr **attr )
00718 {
00719        if ( e == NULL ) {
00720               return -1;
00721        }
00722 
00723        if ( prevattr == NULL ) {
00724               return -1;
00725        }
00726 
00727        *attr = prevattr->a_next;
00728 
00729        return ( *attr != NULL ) ? 0 : -1;
00730 }
00731 
00732 int
00733 slapi_entry_attr_replace_sv( Slapi_Entry *e, const char *type, Slapi_Value **vals )
00734 {
00735        AttributeDescription *ad = NULL;
00736        const char *text;
00737        int rc;
00738        BerVarray bv;
00739        
00740        rc = slap_str2ad( type, &ad, &text );
00741        if ( rc != LDAP_SUCCESS ) {
00742               return 0;
00743        }
00744 
00745        attr_delete( &e->e_attrs, ad );
00746 
00747        rc = bvptr2obj( vals, &bv, NULL );
00748        if ( rc != LDAP_SUCCESS ) {
00749               return -1;
00750        }
00751        
00752        rc = attr_merge_normalize( e, ad, bv, NULL );
00753        slapi_ch_free( (void **)&bv );
00754        if ( rc != LDAP_SUCCESS ) {
00755               return -1;
00756        }
00757        
00758        return 0;
00759 }
00760 
00761 /* 
00762  * FIXME -- The caller must free the allocated memory. 
00763  * In Netscape they do not have to.
00764  */
00765 int 
00766 slapi_attr_get_values(
00767        Slapi_Attr    *attr, 
00768        struct berval ***vals ) 
00769 {
00770        int           i, j;
00771        struct berval **bv;
00772 
00773        if ( attr == NULL ) {
00774               return 1;
00775        }
00776 
00777        for ( i = 0; attr->a_vals[i].bv_val != NULL; i++ ) {
00778               ; /* EMPTY */
00779        }
00780 
00781        bv = (struct berval **)ch_malloc( (i + 1) * sizeof(struct berval *) );
00782        for ( j = 0; j < i; j++ ) {
00783               bv[j] = ber_dupbv( NULL, &attr->a_vals[j] );
00784        }
00785        bv[j] = NULL;
00786        
00787        *vals = (struct berval **)bv;
00788 
00789        return 0;
00790 }
00791 
00792 char *
00793 slapi_dn_normalize( char *dn ) 
00794 {
00795        struct berval bdn;
00796        struct berval pdn;
00797 
00798        assert( dn != NULL );
00799        
00800        bdn.bv_val = dn;
00801        bdn.bv_len = strlen( dn );
00802 
00803        if ( slapi_int_dn_pretty( &bdn, &pdn ) != LDAP_SUCCESS ) {
00804               return NULL;
00805        }
00806 
00807        return pdn.bv_val;
00808 }
00809 
00810 char *
00811 slapi_dn_normalize_case( char *dn ) 
00812 {
00813        struct berval bdn;
00814        struct berval ndn;
00815 
00816        assert( dn != NULL );
00817        
00818        bdn.bv_val = dn;
00819        bdn.bv_len = strlen( dn );
00820 
00821        if ( slapi_int_dn_normalize( &bdn, &ndn ) != LDAP_SUCCESS ) {
00822               return NULL;
00823        }
00824 
00825        return ndn.bv_val;
00826 }
00827 
00828 int 
00829 slapi_dn_issuffix(
00830        char          *dn, 
00831        char          *suffix )
00832 {
00833        struct berval bdn, ndn;
00834        struct berval bsuffix, nsuffix;
00835        int rc;
00836 
00837        assert( dn != NULL );
00838        assert( suffix != NULL );
00839 
00840        bdn.bv_val = dn;
00841        bdn.bv_len = strlen( dn );
00842 
00843        bsuffix.bv_val = suffix;
00844        bsuffix.bv_len = strlen( suffix );
00845 
00846        if ( dnNormalize( 0, NULL, NULL, &bdn, &ndn, NULL ) != LDAP_SUCCESS ) {
00847               return 0;
00848        }
00849 
00850        if ( dnNormalize( 0, NULL, NULL, &bsuffix, &nsuffix, NULL )
00851               != LDAP_SUCCESS )
00852        {
00853               slapi_ch_free( (void **)&ndn.bv_val );
00854               return 0;
00855        }
00856 
00857        rc = dnIsSuffix( &ndn, &nsuffix );
00858 
00859        slapi_ch_free( (void **)&ndn.bv_val );
00860        slapi_ch_free( (void **)&nsuffix.bv_val );
00861 
00862        return rc;
00863 }
00864 
00865 int
00866 slapi_dn_isparent(
00867        const char    *parentdn,
00868        const char    *childdn )
00869 {
00870        struct berval assertedParentDN, normalizedAssertedParentDN;
00871        struct berval childDN, normalizedChildDN;
00872        struct berval normalizedParentDN;
00873        int           match;
00874 
00875        assert( parentdn != NULL );
00876        assert( childdn != NULL );
00877 
00878        assertedParentDN.bv_val = (char *)parentdn;
00879        assertedParentDN.bv_len = strlen( parentdn );
00880 
00881        if ( dnNormalize( 0, NULL, NULL, &assertedParentDN,
00882               &normalizedAssertedParentDN, NULL ) != LDAP_SUCCESS )
00883        {
00884               return 0;
00885        }
00886 
00887        childDN.bv_val = (char *)childdn;
00888        childDN.bv_len = strlen( childdn );
00889 
00890        if ( dnNormalize( 0, NULL, NULL, &childDN,
00891               &normalizedChildDN, NULL ) != LDAP_SUCCESS )
00892        {
00893               slapi_ch_free( (void **)&normalizedAssertedParentDN.bv_val );
00894               return 0;
00895        }
00896 
00897        dnParent( &normalizedChildDN, &normalizedParentDN );
00898 
00899        if ( dnMatch( &match, 0, slap_schema.si_syn_distinguishedName, NULL,
00900               &normalizedParentDN, (void *)&normalizedAssertedParentDN ) != LDAP_SUCCESS )
00901        {
00902               match = -1;
00903        }
00904 
00905        slapi_ch_free( (void **)&normalizedAssertedParentDN.bv_val );
00906        slapi_ch_free( (void **)&normalizedChildDN.bv_val );
00907 
00908        return ( match == 0 );
00909 }
00910 
00911 /*
00912  * Returns DN of the parent entry, or NULL if the DN is
00913  * an empty string or NULL, or has no parent.
00914  */
00915 char *
00916 slapi_dn_parent( const char *_dn )
00917 {
00918        struct berval dn, prettyDN;
00919        struct berval parentDN;
00920        char          *ret;
00921 
00922        if ( _dn == NULL ) {
00923               return NULL;
00924        }
00925 
00926        dn.bv_val = (char *)_dn;
00927        dn.bv_len = strlen( _dn );
00928 
00929        if ( dn.bv_len == 0 ) {
00930               return NULL;
00931        }
00932 
00933        if ( dnPretty( NULL, &dn, &prettyDN, NULL ) != LDAP_SUCCESS ) {
00934               return NULL;
00935        }
00936 
00937        dnParent( &prettyDN, &parentDN ); /* in-place */
00938 
00939        if ( parentDN.bv_len == 0 ) {
00940               slapi_ch_free_string( &prettyDN.bv_val );
00941               return NULL;
00942        }
00943 
00944        ret = slapi_ch_strdup( parentDN.bv_val );
00945        slapi_ch_free_string( &prettyDN.bv_val );
00946 
00947        return ret;
00948 }
00949 
00950 int slapi_dn_isbesuffix( Slapi_PBlock *pb, char *ldn )
00951 {
00952        struct berval ndn;
00953        Backend              *be;
00954 
00955        if ( slapi_is_rootdse( ldn ) ) {
00956               return 0;
00957        }
00958 
00959        /* according to spec should already be normalized */
00960        ndn.bv_len = strlen( ldn );
00961        ndn.bv_val = ldn;
00962 
00963        be = select_backend( &pb->pb_op->o_req_ndn, 0 );
00964        if ( be == NULL ) {
00965               return 0;
00966        }
00967 
00968        return be_issuffix( be, &ndn );
00969 }
00970 
00971 /*
00972  * Returns DN of the parent entry; or NULL if the DN is
00973  * an empty string, if the DN has no parent, or if the
00974  * DN is the suffix of the backend database
00975  */
00976 char *slapi_dn_beparent( Slapi_PBlock *pb, const char *ldn )
00977 {
00978        Backend       *be;
00979        struct berval dn, prettyDN;
00980        struct berval normalizedDN, parentDN;
00981        char          *parent = NULL;
00982 
00983        if ( pb == NULL ) {
00984               return NULL;
00985        }
00986 
00987        PBLOCK_ASSERT_OP( pb, 0 );
00988 
00989        if ( slapi_is_rootdse( ldn ) ) {
00990               return NULL;
00991        }
00992 
00993        dn.bv_val = (char *)ldn;
00994        dn.bv_len = strlen( ldn );
00995 
00996        if ( dnPrettyNormal( NULL, &dn, &prettyDN, &normalizedDN, NULL ) != LDAP_SUCCESS ) {
00997               return NULL;
00998        }
00999 
01000        be = select_backend( &pb->pb_op->o_req_ndn, 0 );
01001 
01002        if ( be == NULL || be_issuffix( be, &normalizedDN ) == 0 ) {
01003               dnParent( &prettyDN, &parentDN );
01004 
01005               if ( parentDN.bv_len != 0 )
01006                      parent = slapi_ch_strdup( parentDN.bv_val );
01007        }
01008 
01009        slapi_ch_free_string( &prettyDN.bv_val );
01010        slapi_ch_free_string( &normalizedDN.bv_val );
01011 
01012        return parent;
01013 }
01014 
01015 char *
01016 slapi_dn_ignore_case( char *dn )
01017 {       
01018        return slapi_dn_normalize_case( dn );
01019 }
01020 
01021 char *
01022 slapi_ch_malloc( unsigned long size ) 
01023 {
01024        return ch_malloc( size );   
01025 }
01026 
01027 void 
01028 slapi_ch_free( void **ptr ) 
01029 {
01030        if ( ptr == NULL || *ptr == NULL )
01031               return;
01032        ch_free( *ptr );
01033        *ptr = NULL;
01034 }
01035 
01036 void 
01037 slapi_ch_free_string( char **ptr ) 
01038 {
01039        slapi_ch_free( (void **)ptr );
01040 }
01041 
01042 void
01043 slapi_ch_array_free( char **arrayp )
01044 {
01045        char **p;
01046 
01047        if ( arrayp != NULL ) {
01048               for ( p = arrayp; *p != NULL; p++ ) {
01049                      slapi_ch_free( (void **)p );
01050               }
01051               slapi_ch_free( (void **)&arrayp );
01052        }
01053 }
01054 
01055 struct berval *
01056 slapi_ch_bvdup(const struct berval *v)
01057 {
01058        return ber_dupbv(NULL, (struct berval *)v);
01059 }
01060 
01061 struct berval **
01062 slapi_ch_bvecdup(const struct berval **v)
01063 {
01064        int i;
01065        struct berval **rv;
01066 
01067        if ( v == NULL ) {
01068               return NULL;
01069        }
01070 
01071        for ( i = 0; v[i] != NULL; i++ )
01072               ;
01073 
01074        rv = (struct berval **) slapi_ch_malloc( (i + 1) * sizeof(struct berval *) );
01075 
01076        for ( i = 0; v[i] != NULL; i++ ) {
01077               rv[i] = slapi_ch_bvdup( v[i] );
01078        }
01079        rv[i] = NULL;
01080 
01081        return rv;
01082 }
01083 
01084 char *
01085 slapi_ch_calloc(
01086        unsigned long nelem, 
01087        unsigned long size ) 
01088 {
01089        return ch_calloc( nelem, size );
01090 }
01091 
01092 char *
01093 slapi_ch_realloc(
01094        char *block, 
01095        unsigned long size ) 
01096 {
01097        return ch_realloc( block, size );
01098 }
01099 
01100 char *
01101 slapi_ch_strdup( const char *s ) 
01102 {
01103        return ch_strdup( s );
01104 }
01105 
01106 size_t
01107 slapi_ch_stlen( const char *s ) 
01108 {
01109        return strlen( s );
01110 }
01111 
01112 int 
01113 slapi_control_present(
01114        LDAPControl   **controls, 
01115        char          *oid, 
01116        struct berval **val, 
01117        int           *iscritical ) 
01118 {
01119        int           i;
01120        int           rc = 0;
01121 
01122        if ( val ) {
01123               *val = NULL;
01124        }
01125        
01126        if ( iscritical ) {
01127               *iscritical = 0;
01128        }
01129        
01130        for ( i = 0; controls != NULL && controls[i] != NULL; i++ ) {
01131               if ( strcmp( controls[i]->ldctl_oid, oid ) != 0 ) {
01132                      continue;
01133               }
01134 
01135               rc = 1;
01136               if ( controls[i]->ldctl_value.bv_len != 0 ) {
01137                      if ( val ) {
01138                             *val = &controls[i]->ldctl_value;
01139                      }
01140               }
01141 
01142               if ( iscritical ) {
01143                      *iscritical = controls[i]->ldctl_iscritical;
01144               }
01145 
01146               break;
01147        }
01148 
01149        return rc;
01150 }
01151 
01152 static void
01153 slapControlMask2SlapiControlOp(slap_mask_t slap_mask,
01154        unsigned long *slapi_mask)
01155 {
01156        *slapi_mask = SLAPI_OPERATION_NONE;
01157 
01158        if ( slap_mask & SLAP_CTRL_ABANDON ) 
01159               *slapi_mask |= SLAPI_OPERATION_ABANDON;
01160 
01161        if ( slap_mask & SLAP_CTRL_ADD )
01162               *slapi_mask |= SLAPI_OPERATION_ADD;
01163 
01164        if ( slap_mask & SLAP_CTRL_BIND )
01165               *slapi_mask |= SLAPI_OPERATION_BIND;
01166 
01167        if ( slap_mask & SLAP_CTRL_COMPARE )
01168               *slapi_mask |= SLAPI_OPERATION_COMPARE;
01169 
01170        if ( slap_mask & SLAP_CTRL_DELETE )
01171               *slapi_mask |= SLAPI_OPERATION_DELETE;
01172 
01173        if ( slap_mask & SLAP_CTRL_MODIFY )
01174               *slapi_mask |= SLAPI_OPERATION_MODIFY;
01175 
01176        if ( slap_mask & SLAP_CTRL_RENAME )
01177               *slapi_mask |= SLAPI_OPERATION_MODDN;
01178 
01179        if ( slap_mask & SLAP_CTRL_SEARCH )
01180               *slapi_mask |= SLAPI_OPERATION_SEARCH;
01181 
01182        if ( slap_mask & SLAP_CTRL_UNBIND )
01183               *slapi_mask |= SLAPI_OPERATION_UNBIND;
01184 }
01185 
01186 static void
01187 slapiControlOp2SlapControlMask(unsigned long slapi_mask,
01188        slap_mask_t *slap_mask)
01189 {
01190        *slap_mask = 0;
01191 
01192        if ( slapi_mask & SLAPI_OPERATION_BIND )
01193               *slap_mask |= SLAP_CTRL_BIND;
01194 
01195        if ( slapi_mask & SLAPI_OPERATION_UNBIND )
01196               *slap_mask |= SLAP_CTRL_UNBIND;
01197 
01198        if ( slapi_mask & SLAPI_OPERATION_SEARCH )
01199               *slap_mask |= SLAP_CTRL_SEARCH;
01200 
01201        if ( slapi_mask & SLAPI_OPERATION_MODIFY )
01202               *slap_mask |= SLAP_CTRL_MODIFY;
01203 
01204        if ( slapi_mask & SLAPI_OPERATION_ADD )
01205               *slap_mask |= SLAP_CTRL_ADD;
01206 
01207        if ( slapi_mask & SLAPI_OPERATION_DELETE )
01208               *slap_mask |= SLAP_CTRL_DELETE;
01209 
01210        if ( slapi_mask & SLAPI_OPERATION_MODDN )
01211               *slap_mask |= SLAP_CTRL_RENAME;
01212 
01213        if ( slapi_mask & SLAPI_OPERATION_COMPARE )
01214               *slap_mask |= SLAP_CTRL_COMPARE;
01215 
01216        if ( slapi_mask & SLAPI_OPERATION_ABANDON )
01217               *slap_mask |= SLAP_CTRL_ABANDON;
01218 
01219        *slap_mask |= SLAP_CTRL_GLOBAL;
01220 }
01221 
01222 static int
01223 slapi_int_parse_control(
01224        Operation *op,
01225        SlapReply *rs,
01226        LDAPControl *ctrl )
01227 {
01228        /* Plugins must deal with controls themselves. */
01229 
01230        return LDAP_SUCCESS;
01231 }
01232 
01233 void 
01234 slapi_register_supported_control(
01235        char          *controloid, 
01236        unsigned long controlops )
01237 {
01238        slap_mask_t controlmask;
01239 
01240        slapiControlOp2SlapControlMask( controlops, &controlmask );
01241 
01242        register_supported_control( controloid, controlmask, NULL, slapi_int_parse_control, NULL );
01243 }
01244 
01245 int 
01246 slapi_get_supported_controls(
01247        char          ***ctrloidsp, 
01248        unsigned long **ctrlopsp ) 
01249 {
01250        int i, rc;
01251 
01252        rc = get_supported_controls( ctrloidsp, (slap_mask_t **)ctrlopsp );
01253        if ( rc != LDAP_SUCCESS ) {
01254               return rc;
01255        }
01256 
01257        for ( i = 0; (*ctrloidsp)[i] != NULL; i++ ) {
01258               /* In place, naughty. */
01259               slapControlMask2SlapiControlOp( (*ctrlopsp)[i], &((*ctrlopsp)[i]) );
01260        }
01261 
01262        return LDAP_SUCCESS;
01263 }
01264 
01265 LDAPControl *
01266 slapi_dup_control( LDAPControl *ctrl )
01267 {
01268        LDAPControl *ret;
01269 
01270        ret = (LDAPControl *)slapi_ch_malloc( sizeof(*ret) );
01271        ret->ldctl_oid = slapi_ch_strdup( ctrl->ldctl_oid );
01272        ber_dupbv( &ret->ldctl_value, &ctrl->ldctl_value );
01273        ret->ldctl_iscritical = ctrl->ldctl_iscritical;
01274 
01275        return ret;
01276 }
01277 
01278 void 
01279 slapi_register_supported_saslmechanism( char *mechanism )
01280 {
01281        /* FIXME -- can not add saslmechanism to OpenLDAP dynamically */
01282        slapi_log_error( SLAPI_LOG_FATAL, "slapi_register_supported_saslmechanism",
01283                      "OpenLDAP does not support dynamic registration of SASL mechanisms\n" );
01284 }
01285 
01286 char **
01287 slapi_get_supported_saslmechanisms( void )
01288 {
01289        /* FIXME -- can not get the saslmechanism without a connection. */
01290        slapi_log_error( SLAPI_LOG_FATAL, "slapi_get_supported_saslmechanisms",
01291                      "can not get the SASL mechanism list "
01292                      "without a connection\n" );
01293        return NULL;
01294 }
01295 
01296 char **
01297 slapi_get_supported_extended_ops( void )
01298 {
01299        int           i, j, k;
01300        char          **ppExtOpOID = NULL;
01301        int           numExtOps = 0;
01302 
01303        for ( i = 0; get_supported_extop( i ) != NULL; i++ ) {
01304               ;
01305        }
01306        
01307        for ( j = 0; slapi_int_get_supported_extop( j ) != NULL; j++ ) {
01308               ;
01309        }
01310 
01311        numExtOps = i + j;
01312        if ( numExtOps == 0 ) {
01313               return NULL;
01314        }
01315 
01316        ppExtOpOID = (char **)slapi_ch_malloc( (numExtOps + 1) * sizeof(char *) );
01317        for ( k = 0; k < i; k++ ) {
01318               struct berval *bv;
01319 
01320               bv = get_supported_extop( k );
01321               assert( bv != NULL );
01322 
01323               ppExtOpOID[ k ] = bv->bv_val;
01324        }
01325        
01326        for ( ; k < j; k++ ) {
01327               struct berval *bv;
01328 
01329               bv = slapi_int_get_supported_extop( k );
01330               assert( bv != NULL );
01331 
01332               ppExtOpOID[ i + k ] = bv->bv_val;
01333        }
01334        ppExtOpOID[ i + k ] = NULL;
01335 
01336        return ppExtOpOID;
01337 }
01338 
01339 void 
01340 slapi_send_ldap_result(
01341        Slapi_PBlock  *pb, 
01342        int           err, 
01343        char          *matched, 
01344        char          *text, 
01345        int           nentries, 
01346        struct berval **urls ) 
01347 {
01348        SlapReply     *rs;
01349 
01350        PBLOCK_ASSERT_OP( pb, 0 );
01351 
01352        rs = pb->pb_rs;
01353 
01354        rs->sr_err = err;
01355        rs->sr_matched = matched;
01356        rs->sr_text = text;
01357        rs->sr_ref = NULL;
01358 
01359        if ( err == LDAP_SASL_BIND_IN_PROGRESS ) {
01360               send_ldap_sasl( pb->pb_op, rs );
01361        } else if ( rs->sr_rspoid != NULL ) {
01362               send_ldap_extended( pb->pb_op, rs );
01363        } else {
01364               if ( pb->pb_op->o_tag == LDAP_REQ_SEARCH )
01365                      rs->sr_nentries = nentries;
01366               if ( urls != NULL )
01367                      bvptr2obj( urls, &rs->sr_ref, NULL );
01368 
01369               send_ldap_result( pb->pb_op, rs );
01370 
01371               if ( urls != NULL )
01372                      slapi_ch_free( (void **)&rs->sr_ref );
01373        }
01374 }
01375 
01376 int 
01377 slapi_send_ldap_search_entry(
01378        Slapi_PBlock  *pb, 
01379        Slapi_Entry   *e, 
01380        LDAPControl   **ectrls, 
01381        char          **attrs, 
01382        int           attrsonly )
01383 {
01384        SlapReply            rs = { REP_SEARCH };
01385        int                  i = 0, j = 0;
01386        AttributeName        *an = NULL;
01387        const char           *text;
01388        int                  rc;
01389 
01390        assert( pb->pb_op != NULL );
01391 
01392        if ( attrs != NULL ) {
01393               for ( i = 0; attrs[ i ] != NULL; i++ ) {
01394                      ; /* empty */
01395               }
01396        }
01397 
01398        if ( i ) {
01399               an = (AttributeName *) slapi_ch_calloc( i + 1, sizeof(AttributeName) );
01400               for ( i = 0; attrs[i] != NULL; i++ ) {
01401                      an[j].an_name.bv_val = attrs[i];
01402                      an[j].an_name.bv_len = strlen( attrs[i] );
01403                      an[j].an_desc = NULL;
01404                      if ( slap_bv2ad( &an[j].an_name, &an[j].an_desc, &text ) == LDAP_SUCCESS) {
01405                             j++;
01406                      }
01407               }
01408               an[j].an_name.bv_len = 0;
01409               an[j].an_name.bv_val = NULL;
01410        }
01411 
01412        rs.sr_err = LDAP_SUCCESS;
01413        rs.sr_matched = NULL;
01414        rs.sr_text = NULL;
01415        rs.sr_ref = NULL;
01416        rs.sr_ctrls = ectrls;
01417        rs.sr_attrs = an;
01418        rs.sr_operational_attrs = NULL;
01419        rs.sr_entry = e;
01420        rs.sr_v2ref = NULL;
01421        rs.sr_flags = 0;
01422 
01423        rc = send_search_entry( pb->pb_op, &rs );
01424 
01425        slapi_ch_free( (void **)&an );
01426 
01427        return rc;
01428 }
01429 
01430 int 
01431 slapi_send_ldap_search_reference(
01432        Slapi_PBlock  *pb,
01433        Slapi_Entry   *e,
01434        struct berval **references,
01435        LDAPControl   **ectrls, 
01436        struct berval **v2refs
01437        )
01438 {
01439        SlapReply     rs = { REP_SEARCHREF };
01440        int           rc;
01441 
01442        rs.sr_err = LDAP_SUCCESS;
01443        rs.sr_matched = NULL;
01444        rs.sr_text = NULL;
01445 
01446        rc = bvptr2obj( references, &rs.sr_ref, NULL );
01447        if ( rc != LDAP_SUCCESS ) {
01448               return rc;
01449        }
01450 
01451        rs.sr_ctrls = ectrls;
01452        rs.sr_attrs = NULL;
01453        rs.sr_operational_attrs = NULL;
01454        rs.sr_entry = e;
01455 
01456        if ( v2refs != NULL ) {
01457               rc = bvptr2obj( v2refs, &rs.sr_v2ref, NULL );
01458               if ( rc != LDAP_SUCCESS ) {
01459                      slapi_ch_free( (void **)&rs.sr_ref );
01460                      return rc;
01461               }
01462        } else {
01463               rs.sr_v2ref = NULL;
01464        }
01465 
01466        rc = send_search_reference( pb->pb_op, &rs );
01467 
01468        slapi_ch_free( (void **)&rs.sr_ref );
01469        slapi_ch_free( (void **)&rs.sr_v2ref );
01470 
01471        return rc;
01472 }
01473 
01474 Slapi_Filter *
01475 slapi_str2filter( char *str ) 
01476 {
01477        return str2filter( str );
01478 }
01479 
01480 void 
01481 slapi_filter_free(
01482        Slapi_Filter  *f, 
01483        int           recurse ) 
01484 {
01485        filter_free( f );
01486 }
01487 
01488 Slapi_Filter *
01489 slapi_filter_dup( Slapi_Filter *filter )
01490 {
01491        return filter_dup( filter, NULL );
01492 }
01493 
01494 int 
01495 slapi_filter_get_choice( Slapi_Filter *f )
01496 {
01497        int           rc;
01498 
01499        if ( f != NULL ) {
01500               rc = f->f_choice;
01501        } else {
01502               rc = 0;
01503        }
01504 
01505        return rc;
01506 }
01507 
01508 int 
01509 slapi_filter_get_ava(
01510        Slapi_Filter  *f, 
01511        char          **type, 
01512        struct berval **bval )
01513 {
01514        int           ftype;
01515        int           rc = LDAP_SUCCESS;
01516 
01517        assert( type != NULL );
01518        assert( bval != NULL );
01519 
01520        *type = NULL;
01521        *bval = NULL;
01522 
01523        ftype = f->f_choice;
01524        if ( ftype == LDAP_FILTER_EQUALITY 
01525                      || ftype ==  LDAP_FILTER_GE 
01526                      || ftype == LDAP_FILTER_LE 
01527                      || ftype == LDAP_FILTER_APPROX ) {
01528               /*
01529                * According to the SLAPI Reference Manual these are
01530                * not duplicated.
01531                */
01532               *type = f->f_un.f_un_ava->aa_desc->ad_cname.bv_val;
01533               *bval = &f->f_un.f_un_ava->aa_value;
01534        } else { /* filter type not supported */
01535               rc = -1;
01536        }
01537 
01538        return rc;
01539 }
01540 
01541 Slapi_Filter *
01542 slapi_filter_list_first( Slapi_Filter *f )
01543 {
01544        int           ftype;
01545 
01546        if ( f == NULL ) {
01547               return NULL;
01548        }
01549 
01550        ftype = f->f_choice;
01551        if ( ftype == LDAP_FILTER_AND
01552                      || ftype == LDAP_FILTER_OR
01553                      || ftype == LDAP_FILTER_NOT ) {
01554               return (Slapi_Filter *)f->f_list;
01555        } else {
01556               return NULL;
01557        }
01558 }
01559 
01560 Slapi_Filter *
01561 slapi_filter_list_next(
01562        Slapi_Filter  *f, 
01563        Slapi_Filter  *fprev )
01564 {
01565        int           ftype;
01566 
01567        if ( f == NULL ) {
01568               return NULL;
01569        }
01570 
01571        ftype = f->f_choice;
01572        if ( ftype == LDAP_FILTER_AND
01573                      || ftype == LDAP_FILTER_OR
01574                      || ftype == LDAP_FILTER_NOT )
01575        {
01576               return fprev->f_next;
01577        }
01578 
01579        return NULL;
01580 }
01581 
01582 int
01583 slapi_filter_get_attribute_type( Slapi_Filter *f, char **type )
01584 {
01585        if ( f == NULL ) {
01586               return -1;
01587        }
01588 
01589        switch ( f->f_choice ) {
01590        case LDAP_FILTER_GE:
01591        case LDAP_FILTER_LE:
01592        case LDAP_FILTER_EQUALITY:
01593        case LDAP_FILTER_APPROX:
01594               *type = f->f_av_desc->ad_cname.bv_val;
01595               break;
01596        case LDAP_FILTER_SUBSTRINGS:
01597               *type = f->f_sub_desc->ad_cname.bv_val;
01598               break;
01599        case LDAP_FILTER_PRESENT:
01600               *type = f->f_desc->ad_cname.bv_val;
01601               break;
01602        case LDAP_FILTER_EXT:
01603               *type = f->f_mr_desc->ad_cname.bv_val;
01604               break;
01605        default:
01606               /* Complex filters need not apply. */
01607               *type = NULL;
01608               return -1;
01609        }
01610 
01611        return 0;
01612 }
01613 
01614 int
01615 slapi_x_filter_set_attribute_type( Slapi_Filter *f, const char *type )
01616 {
01617        AttributeDescription **adp, *ad = NULL;
01618        const char *text;
01619        int rc;
01620 
01621        if ( f == NULL ) {
01622               return -1;
01623        }
01624 
01625        switch ( f->f_choice ) {
01626        case LDAP_FILTER_GE:
01627        case LDAP_FILTER_LE:
01628        case LDAP_FILTER_EQUALITY:
01629        case LDAP_FILTER_APPROX:
01630               adp = &f->f_av_desc;
01631               break;
01632        case LDAP_FILTER_SUBSTRINGS:
01633               adp = &f->f_sub_desc;
01634               break;
01635        case LDAP_FILTER_PRESENT:
01636               adp = &f->f_desc;
01637               break;
01638        case LDAP_FILTER_EXT:
01639               adp = &f->f_mr_desc;
01640               break;
01641        default:
01642               /* Complex filters need not apply. */
01643               return -1;
01644        }
01645 
01646        rc = slap_str2ad( type, &ad, &text );
01647        if ( rc == LDAP_SUCCESS )
01648               *adp = ad;
01649 
01650        return ( rc == LDAP_SUCCESS ) ? 0 : -1;
01651 }
01652 
01653 int
01654 slapi_filter_get_subfilt( Slapi_Filter *f, char **type, char **initial,
01655        char ***any, char **final )
01656 {
01657        int i;
01658 
01659        if ( f->f_choice != LDAP_FILTER_SUBSTRINGS ) {
01660               return -1;
01661        }
01662 
01663        /*
01664         * The caller shouldn't free but we can't return an
01665         * array of char *s from an array of bervals without
01666         * allocating memory, so we may as well be consistent.
01667         * XXX
01668         */
01669        *type = f->f_sub_desc->ad_cname.bv_val;
01670        *initial = f->f_sub_initial.bv_val ? slapi_ch_strdup(f->f_sub_initial.bv_val) : NULL;
01671        if ( f->f_sub_any != NULL ) {
01672               for ( i = 0; f->f_sub_any[i].bv_val != NULL; i++ )
01673                      ;
01674               *any = (char **)slapi_ch_malloc( (i + 1) * sizeof(char *) );
01675               for ( i = 0; f->f_sub_any[i].bv_val != NULL; i++ ) {
01676                      (*any)[i] = slapi_ch_strdup(f->f_sub_any[i].bv_val);
01677               }
01678               (*any)[i] = NULL;
01679        } else {
01680               *any = NULL;
01681        }
01682        *final = f->f_sub_final.bv_val ? slapi_ch_strdup(f->f_sub_final.bv_val) : NULL;
01683 
01684        return 0;
01685 }
01686 
01687 Slapi_Filter *
01688 slapi_filter_join( int ftype, Slapi_Filter *f1, Slapi_Filter *f2 )
01689 {
01690        Slapi_Filter *f = NULL;
01691 
01692        if ( ftype == LDAP_FILTER_AND ||
01693             ftype == LDAP_FILTER_OR ||
01694             ftype == LDAP_FILTER_NOT )
01695        {
01696               f = (Slapi_Filter *)slapi_ch_malloc( sizeof(*f) );
01697               f->f_choice = ftype;
01698               f->f_list = f1;
01699               f->f_list->f_next = f2;
01700               f->f_next = NULL;
01701        }
01702 
01703        return f;
01704 }
01705 
01706 int
01707 slapi_x_filter_append( int ftype,
01708        Slapi_Filter **pContainingFilter, /* NULL on first call */
01709        Slapi_Filter **pNextFilter,
01710        Slapi_Filter *filterToAppend )
01711 {
01712        if ( ftype == LDAP_FILTER_AND ||
01713             ftype == LDAP_FILTER_OR ||
01714             ftype == LDAP_FILTER_NOT )
01715        {
01716               if ( *pContainingFilter == NULL ) {
01717                      *pContainingFilter = (Slapi_Filter *)slapi_ch_malloc( sizeof(Slapi_Filter) );
01718                      (*pContainingFilter)->f_choice = ftype;
01719                      (*pContainingFilter)->f_list = filterToAppend;
01720                      (*pContainingFilter)->f_next = NULL;
01721               } else {
01722                      if ( (*pContainingFilter)->f_choice != ftype ) {
01723                             /* Sanity check */
01724                             return -1;
01725                      }
01726                      (*pNextFilter)->f_next = filterToAppend;
01727               }
01728               *pNextFilter = filterToAppend;
01729 
01730               return 0;
01731        }
01732        return -1;
01733 }
01734 
01735 int
01736 slapi_filter_test( Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Filter *f,
01737        int verify_access )
01738 {
01739        Operation *op;
01740        int rc;
01741 
01742        if ( f == NULL ) {
01743               /* spec says return zero if no filter. */
01744               return 0;
01745        }
01746 
01747        if ( verify_access ) {
01748               op = pb->pb_op;
01749               if ( op == NULL )
01750                      return LDAP_PARAM_ERROR;
01751        } else {
01752               op = NULL;
01753        }
01754 
01755        /*
01756         * According to acl.c it is safe to call test_filter() with
01757         * NULL arguments...
01758         */
01759        rc = test_filter( op, e, f );
01760        switch (rc) {
01761        case LDAP_COMPARE_TRUE:
01762               rc = 0;
01763               break;
01764        case LDAP_COMPARE_FALSE:
01765               break;
01766        case SLAPD_COMPARE_UNDEFINED:
01767               rc = LDAP_OTHER;
01768               break;
01769        case LDAP_PROTOCOL_ERROR:
01770               /* filter type unknown: spec says return -1 */
01771               rc = -1;
01772               break;
01773        }
01774 
01775        return rc;
01776 }
01777 
01778 int
01779 slapi_filter_test_simple( Slapi_Entry *e, Slapi_Filter *f)
01780 {
01781        return slapi_filter_test( NULL, e, f, 0 );
01782 }
01783 
01784 int
01785 slapi_filter_apply( Slapi_Filter *f, FILTER_APPLY_FN fn, void *arg, int *error_code )
01786 {
01787        switch ( f->f_choice ) {
01788        case LDAP_FILTER_AND:
01789        case LDAP_FILTER_NOT:
01790        case LDAP_FILTER_OR: {
01791               int rc;
01792 
01793               /*
01794                * FIXME: altering f; should we use a temporary?
01795                */
01796               for ( f = f->f_list; f != NULL; f = f->f_next ) {
01797                      rc = slapi_filter_apply( f, fn, arg, error_code );
01798                      if ( rc != 0 ) {
01799                             return rc;
01800                      }
01801                      if ( *error_code == SLAPI_FILTER_SCAN_NOMORE ) {
01802                             break;
01803                      }
01804               }
01805               break;
01806        }
01807        case LDAP_FILTER_EQUALITY:
01808        case LDAP_FILTER_SUBSTRINGS:
01809        case LDAP_FILTER_GE:
01810        case LDAP_FILTER_LE:
01811        case LDAP_FILTER_PRESENT:
01812        case LDAP_FILTER_APPROX:
01813        case LDAP_FILTER_EXT:
01814               *error_code = fn( f, arg );
01815               break;
01816        default:
01817               *error_code = SLAPI_FILTER_UNKNOWN_FILTER_TYPE;
01818        }
01819 
01820        if ( *error_code == SLAPI_FILTER_SCAN_NOMORE ||
01821             *error_code == SLAPI_FILTER_SCAN_CONTINUE ) {
01822               return 0;
01823        }
01824 
01825        return -1;
01826 }
01827 
01828 int 
01829 slapi_pw_find(
01830        struct berval **vals, 
01831        struct berval *v ) 
01832 {
01833        int i;
01834 
01835        if( ( vals == NULL ) || ( v == NULL ) )
01836               return 1;
01837 
01838        for ( i = 0; vals[i] != NULL; i++ ) {
01839               if ( !lutil_passwd( vals[i], v, NULL, NULL ) )
01840                      return 0;
01841        }
01842 
01843        return 1;
01844 }
01845 
01846 #define MAX_HOSTNAME 512
01847 
01848 char *
01849 slapi_get_hostname( void ) 
01850 {
01851        char          *hn = NULL;
01852        static int    been_here = 0;   
01853        static char   *static_hn = NULL;
01854 
01855        ldap_pvt_thread_mutex_lock( &slapi_hn_mutex );
01856        if ( !been_here ) {
01857               static_hn = (char *)slapi_ch_malloc( MAX_HOSTNAME );
01858               if ( static_hn == NULL) {
01859                      slapi_log_error( SLAPI_LOG_FATAL, "slapi_get_hostname",
01860                                    "Cannot allocate memory for hostname\n" );
01861                      static_hn = NULL;
01862                      ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
01863 
01864                      return hn;
01865                      
01866               } else { 
01867                      if ( gethostname( static_hn, MAX_HOSTNAME ) != 0 ) {
01868                             slapi_log_error( SLAPI_LOG_FATAL,
01869                                           "SLAPI",
01870                                           "can't get hostname\n" );
01871                             slapi_ch_free( (void **)&static_hn );
01872                             static_hn = NULL;
01873                             ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
01874 
01875                             return hn;
01876 
01877                      } else {
01878                             been_here = 1;
01879                      }
01880               }
01881        }
01882        ldap_pvt_thread_mutex_unlock( &slapi_hn_mutex );
01883        
01884        hn = ch_strdup( static_hn );
01885 
01886        return hn;
01887 }
01888 
01889 /*
01890  * FIXME: this should go in an appropriate header ...
01891  */
01892 extern int slapi_int_log_error( int level, char *subsystem, char *fmt, va_list arglist );
01893 
01894 int 
01895 slapi_log_error(
01896        int           severity, 
01897        char          *subsystem, 
01898        char          *fmt, 
01899        ... ) 
01900 {
01901        int           rc = LDAP_SUCCESS;
01902        va_list              arglist;
01903 
01904        va_start( arglist, fmt );
01905        rc = slapi_int_log_error( severity, subsystem, fmt, arglist );
01906        va_end( arglist );
01907 
01908        return rc;
01909 }
01910 
01911 
01912 unsigned long
01913 slapi_timer_current_time( void ) 
01914 {
01915        static int    first_time = 1;
01916 #if !defined (_WIN32)
01917        struct timeval       now;
01918        unsigned long ret;
01919 
01920        ldap_pvt_thread_mutex_lock( &slapi_time_mutex );
01921        if (first_time) {
01922               first_time = 0;
01923               gettimeofday( &base_time, NULL );
01924        }
01925        gettimeofday( &now, NULL );
01926        ret = ( now.tv_sec  - base_time.tv_sec ) * 1000000 + 
01927                      (now.tv_usec - base_time.tv_usec);
01928        ldap_pvt_thread_mutex_unlock( &slapi_time_mutex );
01929 
01930        return ret;
01931 
01932        /*
01933         * Ain't it better?
01934        return (slap_get_time() - starttime) * 1000000;
01935         */
01936 #else /* _WIN32 */
01937        LARGE_INTEGER now;
01938 
01939        if ( first_time ) {
01940               first_time = 0;
01941               performance_counter_present = QueryPerformanceCounter( &base_time );
01942               QueryPerformanceFrequency( &performance_freq );
01943        }
01944 
01945        if ( !performance_counter_present )
01946             return 0;
01947 
01948        QueryPerformanceCounter( &now );
01949        return (1000000*(now.QuadPart-base_time.QuadPart))/performance_freq.QuadPart;
01950 #endif /* _WIN32 */
01951 }
01952 
01953 /*
01954  * FIXME ?
01955  */
01956 unsigned long
01957 slapi_timer_get_time( char *label ) 
01958 {
01959        unsigned long start = slapi_timer_current_time();
01960        printf("%10ld %10d usec %s\n", start, 0, label);
01961        return start;
01962 }
01963 
01964 /*
01965  * FIXME ?
01966  */
01967 void
01968 slapi_timer_elapsed_time(
01969        char *label,
01970        unsigned long start ) 
01971 {
01972        unsigned long stop = slapi_timer_current_time();
01973        printf ("%10ld %10ld usec %s\n", stop, stop - start, label);
01974 }
01975 
01976 void
01977 slapi_free_search_results_internal( Slapi_PBlock *pb ) 
01978 {
01979        Slapi_Entry   **entries;
01980        int           k = 0, nEnt = 0;
01981 
01982        slapi_pblock_get( pb, SLAPI_NENTRIES, &nEnt );
01983        slapi_pblock_get( pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries );
01984        if ( nEnt == 0 || entries == NULL ) {
01985               return;
01986        }
01987 
01988        for ( k = 0; k < nEnt; k++ ) {
01989               slapi_entry_free( entries[k] );
01990               entries[k] = NULL;
01991        }
01992        
01993        slapi_ch_free( (void **)&entries );
01994 }
01995 
01996 int slapi_is_connection_ssl( Slapi_PBlock *pb, int *isSSL )
01997 {
01998        if ( pb == NULL )
01999               return LDAP_PARAM_ERROR;
02000 
02001        if ( pb->pb_conn == NULL )
02002               return LDAP_PARAM_ERROR;
02003 
02004 #ifdef HAVE_TLS
02005        *isSSL = pb->pb_conn->c_is_tls;
02006 #else
02007        *isSSL = 0;
02008 #endif
02009 
02010        return LDAP_SUCCESS;
02011 }
02012 
02013 /*
02014  * DS 5.x compatability API follow
02015  */
02016 
02017 int slapi_attr_get_flags( const Slapi_Attr *attr, unsigned long *flags )
02018 {
02019        AttributeType *at;
02020 
02021        if ( attr == NULL )
02022               return LDAP_PARAM_ERROR;
02023 
02024        at = attr->a_desc->ad_type;
02025 
02026        *flags = SLAPI_ATTR_FLAG_STD_ATTR;
02027 
02028        if ( is_at_single_value( at ) )
02029               *flags |= SLAPI_ATTR_FLAG_SINGLE;
02030        if ( is_at_operational( at ) )
02031               *flags |= SLAPI_ATTR_FLAG_OPATTR;
02032        if ( is_at_obsolete( at ) )
02033               *flags |= SLAPI_ATTR_FLAG_OBSOLETE;
02034        if ( is_at_collective( at ) )
02035               *flags |= SLAPI_ATTR_FLAG_COLLECTIVE;
02036        if ( is_at_no_user_mod( at ) )
02037               *flags |= SLAPI_ATTR_FLAG_NOUSERMOD;
02038 
02039        return LDAP_SUCCESS;
02040 }
02041 
02042 int slapi_attr_flag_is_set( const Slapi_Attr *attr, unsigned long flag )
02043 {
02044        unsigned long flags;
02045 
02046        if ( slapi_attr_get_flags( attr, &flags ) != 0 )
02047               return 0;
02048        return (flags & flag) ? 1 : 0;
02049 }
02050 
02051 Slapi_Attr *slapi_attr_new( void )
02052 {
02053        Attribute *ad;
02054 
02055        ad = (Attribute  *)slapi_ch_calloc( 1, sizeof(*ad) );
02056 
02057        return ad;
02058 }
02059 
02060 Slapi_Attr *slapi_attr_init( Slapi_Attr *a, const char *type )
02061 {
02062        const char *text;
02063        AttributeDescription *ad = NULL;
02064 
02065        if( slap_str2ad( type, &ad, &text ) != LDAP_SUCCESS ) {
02066               return NULL;
02067        }
02068 
02069        a->a_desc = ad;
02070        a->a_vals = NULL;
02071        a->a_nvals = NULL;
02072        a->a_next = NULL;
02073        a->a_flags = 0;
02074 
02075        return a;
02076 }
02077 
02078 void slapi_attr_free( Slapi_Attr **a )
02079 {
02080        attr_free( *a );
02081        *a = NULL;
02082 }
02083 
02084 Slapi_Attr *slapi_attr_dup( const Slapi_Attr *attr )
02085 {
02086        return attr_dup( (Slapi_Attr *)attr );
02087 }
02088 
02089 int slapi_attr_add_value( Slapi_Attr *a, const Slapi_Value *v )
02090 {
02091        struct berval nval;
02092        struct berval *nvalp;
02093        int rc;
02094        AttributeDescription *desc = a->a_desc;
02095 
02096        if ( desc->ad_type->sat_equality &&
02097             desc->ad_type->sat_equality->smr_normalize ) {
02098               rc = (*desc->ad_type->sat_equality->smr_normalize)(
02099                      SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX,
02100                      desc->ad_type->sat_syntax,
02101                      desc->ad_type->sat_equality,
02102                      (Slapi_Value *)v, &nval, NULL );
02103               if ( rc != LDAP_SUCCESS ) {
02104                      return rc;
02105               }
02106               nvalp = &nval;
02107        } else {
02108               nvalp = NULL;
02109        }
02110 
02111        rc = attr_valadd( a, (Slapi_Value *)v, nvalp, 1 );
02112 
02113        if ( nvalp != NULL ) {
02114               slapi_ch_free_string( &nval.bv_val );
02115        }
02116 
02117        return rc;
02118 }
02119 
02120 int slapi_attr_type2plugin( const char *type, void **pi )
02121 {
02122        *pi = NULL;
02123 
02124        return LDAP_OTHER;
02125 }
02126 
02127 int slapi_attr_get_type( const Slapi_Attr *attr, char **type )
02128 {
02129        if ( attr == NULL ) {
02130               return LDAP_PARAM_ERROR;
02131        }
02132 
02133        *type = attr->a_desc->ad_cname.bv_val;
02134 
02135        return LDAP_SUCCESS;
02136 }
02137 
02138 int slapi_attr_get_oid_copy( const Slapi_Attr *attr, char **oidp )
02139 {
02140        if ( attr == NULL ) {
02141               return LDAP_PARAM_ERROR;
02142        }
02143        *oidp = attr->a_desc->ad_type->sat_oid;
02144 
02145        return LDAP_SUCCESS;
02146 }
02147 
02148 int slapi_attr_value_cmp( const Slapi_Attr *a, const struct berval *v1, const struct berval *v2 )
02149 {
02150        MatchingRule *mr;
02151        int ret;
02152        int rc;
02153        const char *text;
02154 
02155        mr = a->a_desc->ad_type->sat_equality;
02156        rc = value_match( &ret, a->a_desc, mr,
02157                      SLAP_MR_VALUE_OF_ASSERTION_SYNTAX,
02158               (struct berval *)v1, (void *)v2, &text );
02159        if ( rc != LDAP_SUCCESS ) 
02160               return -1;
02161 
02162        return ( ret == 0 ) ? 0 : -1;
02163 }
02164 
02165 int slapi_attr_value_find( const Slapi_Attr *a, struct berval *v )
02166 {
02167        int rc;
02168 
02169        if ( a ->a_vals == NULL ) {
02170               return -1;
02171        }
02172        rc = attr_valfind( (Attribute *)a, SLAP_MR_VALUE_OF_ASSERTION_SYNTAX, v,
02173               NULL, NULL );
02174        return rc == 0 ? 0 : -1;
02175 }
02176 
02177 int slapi_attr_type_cmp( const char *t1, const char *t2, int opt )
02178 {
02179        AttributeDescription *a1 = NULL;
02180        AttributeDescription *a2 = NULL;
02181        const char *text;
02182        int ret;
02183 
02184        if ( slap_str2ad( t1, &a1, &text ) != LDAP_SUCCESS ) {
02185               return -1;
02186        }
02187 
02188        if ( slap_str2ad( t2, &a2, &text ) != LDAP_SUCCESS ) {
02189               return 1;
02190        }
02191 
02192 #define ad_base_cmp(l,r) (((l)->ad_type->sat_cname.bv_len < (r)->ad_type->sat_cname.bv_len) \
02193        ? -1 : (((l)->ad_type->sat_cname.bv_len > (r)->ad_type->sat_cname.bv_len) \
02194               ? 1 : strcasecmp((l)->ad_type->sat_cname.bv_val, (r)->ad_type->sat_cname.bv_val )))
02195 
02196        switch ( opt ) {
02197        case SLAPI_TYPE_CMP_EXACT:
02198               ret = ad_cmp( a1, a2 );
02199               break;
02200        case SLAPI_TYPE_CMP_BASE:
02201               ret = ad_base_cmp( a1, a2 );
02202               break;
02203        case SLAPI_TYPE_CMP_SUBTYPE:
02204               ret = is_ad_subtype( a2, a2 );
02205               break;
02206        default:
02207               ret = -1;
02208               break;
02209        }
02210 
02211        return ret;
02212 }
02213 
02214 int slapi_attr_types_equivalent( const char *t1, const char *t2 )
02215 {
02216        return ( slapi_attr_type_cmp( t1, t2, SLAPI_TYPE_CMP_EXACT ) == 0 );
02217 }
02218 
02219 int slapi_attr_first_value( Slapi_Attr *a, Slapi_Value **v )
02220 {
02221        return slapi_valueset_first_value( &a->a_vals, v );
02222 }
02223 
02224 int slapi_attr_next_value( Slapi_Attr *a, int hint, Slapi_Value **v )
02225 {
02226        return slapi_valueset_next_value( &a->a_vals, hint, v );
02227 }
02228 
02229 int slapi_attr_get_numvalues( const Slapi_Attr *a, int *numValues )
02230 {
02231        *numValues = slapi_valueset_count( &a->a_vals );
02232 
02233        return 0;
02234 }
02235 
02236 int slapi_attr_get_valueset( const Slapi_Attr *a, Slapi_ValueSet **vs )
02237 {
02238        *vs = &((Slapi_Attr *)a)->a_vals;
02239 
02240        return 0;
02241 }
02242 
02243 int slapi_attr_get_bervals_copy( Slapi_Attr *a, struct berval ***vals )
02244 {
02245        return slapi_attr_get_values( a, vals );
02246 }
02247 
02248 char *slapi_attr_syntax_normalize( const char *s )
02249 {
02250        AttributeDescription *ad = NULL;
02251        const char *text;
02252 
02253        if ( slap_str2ad( s, &ad, &text ) != LDAP_SUCCESS ) {
02254               return NULL;
02255        }
02256 
02257        return ad->ad_cname.bv_val;
02258 }
02259 
02260 Slapi_Value *slapi_value_new( void )
02261 {
02262        struct berval *bv;
02263 
02264        bv = (struct berval *)slapi_ch_malloc( sizeof(*bv) );
02265 
02266        return bv;
02267 }
02268 
02269 Slapi_Value *slapi_value_new_berval(const struct berval *bval)
02270 {
02271        return ber_dupbv( NULL, (struct berval *)bval );
02272 }
02273 
02274 Slapi_Value *slapi_value_new_value(const Slapi_Value *v)
02275 {
02276        return slapi_value_new_berval( v );
02277 }
02278 
02279 Slapi_Value *slapi_value_new_string(const char *s)
02280 {
02281        struct berval bv;
02282 
02283        bv.bv_val = (char *)s;
02284        bv.bv_len = strlen( s );
02285 
02286        return slapi_value_new_berval( &bv );
02287 }
02288 
02289 Slapi_Value *slapi_value_init(Slapi_Value *val)
02290 {
02291        val->bv_val = NULL;
02292        val->bv_len = 0;
02293 
02294        return val;
02295 }
02296 
02297 Slapi_Value *slapi_value_init_berval(Slapi_Value *v, struct berval *bval)
02298 {
02299        return ber_dupbv( v, bval );
02300 }
02301 
02302 Slapi_Value *slapi_value_init_string(Slapi_Value *v, const char *s)
02303 {
02304        v->bv_val = slapi_ch_strdup( s );
02305        v->bv_len = strlen( s );
02306 
02307        return v;
02308 }
02309 
02310 Slapi_Value *slapi_value_dup(const Slapi_Value *v)
02311 {
02312        return slapi_value_new_value( v );
02313 }
02314 
02315 void slapi_value_free(Slapi_Value **value)
02316 {
02317        if ( value == NULL ) {
02318               return;
02319        }
02320 
02321        if ( (*value) != NULL ) {
02322               slapi_ch_free( (void **)&(*value)->bv_val );
02323               slapi_ch_free( (void **)value );
02324        }
02325 }
02326 
02327 const struct berval *slapi_value_get_berval( const Slapi_Value *value )
02328 {
02329        return value;
02330 }
02331 
02332 Slapi_Value *slapi_value_set_berval( Slapi_Value *value, const struct berval *bval )
02333 {
02334        if ( value == NULL ) {
02335               return NULL;
02336        }
02337        if ( value->bv_val != NULL ) {
02338               slapi_ch_free( (void **)&value->bv_val );
02339        }
02340        slapi_value_init_berval( value, (struct berval *)bval );
02341 
02342        return value;
02343 }
02344 
02345 Slapi_Value *slapi_value_set_value( Slapi_Value *value, const Slapi_Value *vfrom)
02346 {
02347        if ( value == NULL ) {
02348               return NULL;
02349        }
02350        return slapi_value_set_berval( value, vfrom );
02351 }
02352 
02353 Slapi_Value *slapi_value_set( Slapi_Value *value, void *val, unsigned long len)
02354 {
02355        if ( value == NULL ) {
02356               return NULL;
02357        }
02358        if ( value->bv_val != NULL ) {
02359               slapi_ch_free( (void **)&value->bv_val );
02360        }
02361        value->bv_val = slapi_ch_malloc( len );
02362        value->bv_len = len;
02363        AC_MEMCPY( value->bv_val, val, len );
02364 
02365        return value;
02366 }
02367 
02368 int slapi_value_set_string(Slapi_Value *value, const char *strVal)
02369 {
02370        if ( value == NULL ) {
02371               return -1;
02372        }
02373        slapi_value_set( value, (void *)strVal, strlen( strVal ) );
02374        return 0;
02375 }
02376 
02377 int slapi_value_set_int(Slapi_Value *value, int intVal)
02378 {
02379        char buf[64];
02380 
02381        snprintf( buf, sizeof( buf ), "%d", intVal );
02382 
02383        return slapi_value_set_string( value, buf );
02384 }
02385 
02386 const char *slapi_value_get_string(const Slapi_Value *value)
02387 {
02388        if ( value == NULL ) return NULL;
02389        if ( value->bv_val == NULL ) return NULL;
02390        if ( !checkBVString( value ) ) return NULL;
02391 
02392        return value->bv_val;
02393 }
02394 
02395 int slapi_value_get_int(const Slapi_Value *value)
02396 {
02397        if ( value == NULL ) return 0;
02398        if ( value->bv_val == NULL ) return 0;
02399        if ( !checkBVString( value ) ) return 0;
02400 
02401        return (int)strtol( value->bv_val, NULL, 10 );
02402 }
02403 
02404 unsigned int slapi_value_get_uint(const Slapi_Value *value)
02405 {
02406        if ( value == NULL ) return 0;
02407        if ( value->bv_val == NULL ) return 0;
02408        if ( !checkBVString( value ) ) return 0;
02409 
02410        return (unsigned int)strtoul( value->bv_val, NULL, 10 );
02411 }
02412 
02413 long slapi_value_get_long(const Slapi_Value *value)
02414 {
02415        if ( value == NULL ) return 0;
02416        if ( value->bv_val == NULL ) return 0;
02417        if ( !checkBVString( value ) ) return 0;
02418 
02419        return strtol( value->bv_val, NULL, 10 );
02420 }
02421 
02422 unsigned long slapi_value_get_ulong(const Slapi_Value *value)
02423 {
02424        if ( value == NULL ) return 0;
02425        if ( value->bv_val == NULL ) return 0;
02426        if ( !checkBVString( value ) ) return 0;
02427 
02428        return strtoul( value->bv_val, NULL, 10 );
02429 }
02430 
02431 size_t slapi_value_get_length(const Slapi_Value *value)
02432 {
02433        if ( value == NULL )
02434               return 0;
02435 
02436        return (size_t) value->bv_len;
02437 }
02438 
02439 int slapi_value_compare(const Slapi_Attr *a, const Slapi_Value *v1, const Slapi_Value *v2)
02440 {
02441        return slapi_attr_value_cmp( a, v1, v2 );
02442 }
02443 
02444 /* A ValueSet is a container for a BerVarray. */
02445 Slapi_ValueSet *slapi_valueset_new( void )
02446 {
02447        Slapi_ValueSet *vs;
02448 
02449        vs = (Slapi_ValueSet *)slapi_ch_malloc( sizeof( *vs ) );
02450        *vs = NULL;
02451 
02452        return vs;
02453 }
02454 
02455 void slapi_valueset_free(Slapi_ValueSet *vs)
02456 {
02457        if ( vs != NULL ) {
02458               BerVarray vp = *vs;
02459 
02460               ber_bvarray_free( vp );
02461               vp = NULL;
02462 
02463               slapi_ch_free( (void **)&vp );
02464        }
02465 }
02466 
02467 void slapi_valueset_init(Slapi_ValueSet *vs)
02468 {
02469        if ( vs != NULL && *vs == NULL ) {
02470               *vs = (Slapi_ValueSet)slapi_ch_calloc( 1, sizeof(struct berval) );
02471               (*vs)->bv_val = NULL;
02472               (*vs)->bv_len = 0;
02473        }
02474 }
02475 
02476 void slapi_valueset_done(Slapi_ValueSet *vs)
02477 {
02478        BerVarray vp;
02479 
02480        if ( vs == NULL )
02481               return;
02482 
02483        for ( vp = *vs; vp->bv_val != NULL; vp++ ) {
02484               vp->bv_len = 0;
02485               slapi_ch_free( (void **)&vp->bv_val );
02486        }
02487        /* but don't free *vs or vs */
02488 }
02489 
02490 void slapi_valueset_add_value(Slapi_ValueSet *vs, const Slapi_Value *addval)
02491 {
02492        struct berval bv;
02493 
02494        ber_dupbv( &bv, (Slapi_Value *)addval );
02495        ber_bvarray_add( vs, &bv );
02496 }
02497 
02498 int slapi_valueset_first_value( Slapi_ValueSet *vs, Slapi_Value **v )
02499 {
02500        return slapi_valueset_next_value( vs, 0, v );
02501 }
02502 
02503 int slapi_valueset_next_value( Slapi_ValueSet *vs, int index, Slapi_Value **v)
02504 {
02505        int i;
02506        BerVarray vp;
02507 
02508        if ( vs == NULL )
02509               return -1;
02510 
02511        vp = *vs;
02512 
02513        for ( i = 0; vp[i].bv_val != NULL; i++ ) {
02514               if ( i == index ) {
02515                      *v = &vp[i];
02516                      return index + 1;
02517               }
02518        }
02519 
02520        return -1;
02521 }
02522 
02523 int slapi_valueset_count( const Slapi_ValueSet *vs )
02524 {
02525        int i;
02526        BerVarray vp;
02527 
02528        if ( vs == NULL )
02529               return 0;
02530 
02531        vp = *vs;
02532 
02533        if ( vp == NULL )
02534               return 0;
02535 
02536        for ( i = 0; vp[i].bv_val != NULL; i++ )
02537               ;
02538 
02539        return i;
02540 
02541 }
02542 
02543 void slapi_valueset_set_valueset(Slapi_ValueSet *vs1, const Slapi_ValueSet *vs2)
02544 {
02545        BerVarray vp;
02546 
02547        for ( vp = *vs2; vp->bv_val != NULL; vp++ ) {
02548               slapi_valueset_add_value( vs1, vp );
02549        }
02550 }
02551 
02552 int slapi_access_allowed( Slapi_PBlock *pb, Slapi_Entry *e, char *attr,
02553        struct berval *val, int access )
02554 {
02555        int rc;
02556        slap_access_t slap_access;
02557        AttributeDescription *ad = NULL;
02558        const char *text;
02559 
02560        rc = slap_str2ad( attr, &ad, &text );
02561        if ( rc != LDAP_SUCCESS ) {
02562               return rc;
02563        }
02564 
02565        /*
02566         * Whilst the SLAPI access types are arranged as a bitmask, the
02567         * documentation indicates that they are to be used separately.
02568         */
02569        switch ( access & SLAPI_ACL_ALL ) {
02570        case SLAPI_ACL_COMPARE:
02571               slap_access = ACL_COMPARE;
02572               break;
02573        case SLAPI_ACL_SEARCH:
02574               slap_access = ACL_SEARCH;
02575               break;
02576        case SLAPI_ACL_READ:
02577               slap_access = ACL_READ;
02578               break;
02579        case SLAPI_ACL_WRITE:
02580               slap_access = ACL_WRITE;
02581               break;
02582        case SLAPI_ACL_DELETE:
02583               slap_access = ACL_WDEL;
02584               break;
02585        case SLAPI_ACL_ADD:
02586               slap_access = ACL_WADD;
02587               break;
02588        case SLAPI_ACL_SELF:  /* not documented */
02589        case SLAPI_ACL_PROXY: /* not documented */
02590        default:
02591               return LDAP_INSUFFICIENT_ACCESS;
02592               break;
02593        }
02594 
02595        assert( pb->pb_op != NULL );
02596 
02597        if ( access_allowed( pb->pb_op, e, ad, val, slap_access, NULL ) ) {
02598               return LDAP_SUCCESS;
02599        }
02600 
02601        return LDAP_INSUFFICIENT_ACCESS;
02602 }
02603 
02604 int slapi_acl_check_mods(Slapi_PBlock *pb, Slapi_Entry *e, LDAPMod **mods, char **errbuf)
02605 {
02606        int rc = LDAP_SUCCESS;
02607        Modifications *ml;
02608 
02609        if ( pb == NULL || pb->pb_op == NULL )
02610               return LDAP_PARAM_ERROR;
02611 
02612        ml = slapi_int_ldapmods2modifications( pb->pb_op, mods );
02613        if ( ml == NULL ) {
02614               return LDAP_OTHER;
02615        }
02616 
02617        if ( rc == LDAP_SUCCESS ) {
02618               rc = acl_check_modlist( pb->pb_op, e, ml ) ? LDAP_SUCCESS : LDAP_INSUFFICIENT_ACCESS;
02619        }
02620 
02621        slap_mods_free( ml, 1 );
02622 
02623        return rc;
02624 }
02625 
02626 /*
02627  * Synthesise an LDAPMod array from a Modifications list to pass
02628  * to SLAPI.
02629  */
02630 LDAPMod **slapi_int_modifications2ldapmods( Modifications *modlist )
02631 {
02632        Modifications *ml;
02633        LDAPMod **mods, *modp;
02634        int i, j;
02635 
02636        for( i = 0, ml = modlist; ml != NULL; i++, ml = ml->sml_next )
02637               ;
02638 
02639        mods = (LDAPMod **)slapi_ch_malloc( (i + 1) * sizeof(LDAPMod *) );
02640 
02641        for( i = 0, ml = modlist; ml != NULL; ml = ml->sml_next ) {
02642               mods[i] = (LDAPMod *)slapi_ch_malloc( sizeof(LDAPMod) );
02643               modp = mods[i];
02644               modp->mod_op = ml->sml_op | LDAP_MOD_BVALUES;
02645               if ( BER_BVISNULL( &ml->sml_type ) ) {
02646                      /* may happen for internally generated mods */
02647                      assert( ml->sml_desc != NULL );
02648                      modp->mod_type = slapi_ch_strdup( ml->sml_desc->ad_cname.bv_val );
02649               } else {
02650                      modp->mod_type = slapi_ch_strdup( ml->sml_type.bv_val );
02651               }
02652 
02653               if ( ml->sml_values != NULL ) {
02654                      for( j = 0; ml->sml_values[j].bv_val != NULL; j++ )
02655                             ;
02656                      modp->mod_bvalues = (struct berval **)slapi_ch_malloc( (j + 1) *
02657                             sizeof(struct berval *) );
02658                      for( j = 0; ml->sml_values[j].bv_val != NULL; j++ ) {
02659                             modp->mod_bvalues[j] = (struct berval *)slapi_ch_malloc(
02660                                           sizeof(struct berval) );
02661                             ber_dupbv( modp->mod_bvalues[j], &ml->sml_values[j] );
02662                      }
02663                      modp->mod_bvalues[j] = NULL;
02664               } else {
02665                      modp->mod_bvalues = NULL;
02666               }
02667               i++;
02668        }
02669 
02670        mods[i] = NULL;
02671 
02672        return mods;
02673 }
02674 
02675 /*
02676  * Convert a potentially modified array of LDAPMods back to a
02677  * Modification list. Unfortunately the values need to be
02678  * duplicated because slap_mods_check() will try to free them
02679  * before prettying (and we can't easily get out of calling
02680  * slap_mods_check() because we need normalized values).
02681  */
02682 Modifications *slapi_int_ldapmods2modifications ( Operation *op, LDAPMod **mods )
02683 {
02684        Modifications *modlist = NULL, **modtail;
02685        LDAPMod **modp;
02686        char textbuf[SLAP_TEXT_BUFLEN];
02687        const char *text;
02688 
02689        if ( mods == NULL ) {
02690               return NULL;
02691        }
02692 
02693        modtail = &modlist;
02694 
02695        for ( modp = mods; *modp != NULL; modp++ ) {
02696               Modifications *mod;
02697               LDAPMod *lmod = *modp;
02698               int i;
02699               const char *text;
02700               AttributeDescription *ad = NULL;
02701 
02702               if ( slap_str2ad( lmod->mod_type, &ad, &text ) != LDAP_SUCCESS ) {
02703                      continue;
02704               }
02705 
02706               mod = (Modifications *) slapi_ch_malloc( sizeof(Modifications) );
02707               mod->sml_op = lmod->mod_op & ~(LDAP_MOD_BVALUES);
02708               mod->sml_flags = 0;
02709               mod->sml_type = ad->ad_cname;
02710               mod->sml_desc = ad;
02711               mod->sml_next = NULL;
02712 
02713               i = 0;
02714               if ( lmod->mod_op & LDAP_MOD_BVALUES ) {
02715                      if ( lmod->mod_bvalues != NULL ) {
02716                             while ( lmod->mod_bvalues[i] != NULL )
02717                                    i++;
02718                      }
02719               } else {
02720                      if ( lmod->mod_values != NULL ) {
02721                             while ( lmod->mod_values[i] != NULL )
02722                                    i++;
02723                      }
02724               }
02725               mod->sml_numvals = i;
02726 
02727               if ( i == 0 ) {
02728                      mod->sml_values = NULL;
02729               } else {
02730                      mod->sml_values = (BerVarray) slapi_ch_malloc( (i + 1) * sizeof(struct berval) );
02731 
02732                      /* NB: This implicitly trusts a plugin to return valid modifications. */
02733                      if ( lmod->mod_op & LDAP_MOD_BVALUES ) {
02734                             for ( i = 0; lmod->mod_bvalues[i] != NULL; i++ ) {
02735                                    ber_dupbv( &mod->sml_values[i], lmod->mod_bvalues[i] );
02736                             }
02737                      } else {
02738                             for ( i = 0; lmod->mod_values[i] != NULL; i++ ) {
02739                                    mod->sml_values[i].bv_val = slapi_ch_strdup( lmod->mod_values[i] );
02740                                    mod->sml_values[i].bv_len = strlen( lmod->mod_values[i] );
02741                             }
02742                      }
02743                      mod->sml_values[i].bv_val = NULL;
02744                      mod->sml_values[i].bv_len = 0;
02745               }
02746               mod->sml_nvalues = NULL;
02747 
02748               *modtail = mod;
02749               modtail = &mod->sml_next;
02750        }
02751 
02752        if ( slap_mods_check( op, modlist, &text, textbuf, sizeof( textbuf ), NULL ) != LDAP_SUCCESS ) {
02753               slap_mods_free( modlist, 1 );
02754               modlist = NULL;
02755        }
02756 
02757        return modlist;
02758 }
02759 
02760 /*
02761  * Sun ONE DS 5.x computed attribute support. Computed attributes
02762  * allow for dynamically generated operational attributes, a very
02763  * useful thing indeed.
02764  */
02765 
02766 /*
02767  * For some reason Sun don't use the normal plugin mechanism
02768  * registration path to register an "evaluator" function (an
02769  * "evaluator" is responsible for adding computed attributes;
02770  * the nomenclature is somewhat confusing).
02771  *
02772  * As such slapi_compute_add_evaluator() registers the 
02773  * function directly.
02774  */
02775 int slapi_compute_add_evaluator(slapi_compute_callback_t function)
02776 {
02777        Slapi_PBlock *pPlugin = NULL;
02778        int rc;
02779        int type = SLAPI_PLUGIN_OBJECT;
02780 
02781        pPlugin = slapi_pblock_new();
02782        if ( pPlugin == NULL ) {
02783               rc = LDAP_NO_MEMORY;
02784               goto done;
02785        }
02786 
02787        rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)&type );
02788        if ( rc != LDAP_SUCCESS ) {
02789               goto done;
02790        }
02791 
02792        rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_COMPUTE_EVALUATOR_FN, (void *)function );
02793        if ( rc != LDAP_SUCCESS ) {
02794               goto done;
02795        }
02796 
02797        rc = slapi_int_register_plugin( frontendDB, pPlugin );
02798        if ( rc != 0 ) {
02799               rc = LDAP_OTHER;
02800               goto done;
02801        }
02802 
02803 done:
02804        if ( rc != LDAP_SUCCESS ) {
02805               if ( pPlugin != NULL ) {
02806                      slapi_pblock_destroy( pPlugin );
02807               }
02808               return -1;
02809        }
02810 
02811        return 0;
02812 }
02813 
02814 /*
02815  * See notes above regarding slapi_compute_add_evaluator().
02816  */
02817 int slapi_compute_add_search_rewriter(slapi_search_rewrite_callback_t function)
02818 {
02819        Slapi_PBlock *pPlugin = NULL;
02820        int rc;
02821        int type = SLAPI_PLUGIN_OBJECT;
02822 
02823        pPlugin = slapi_pblock_new();
02824        if ( pPlugin == NULL ) {
02825               rc = LDAP_NO_MEMORY;
02826               goto done;
02827        }
02828 
02829        rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_TYPE, (void *)&type );
02830        if ( rc != LDAP_SUCCESS ) {
02831               goto done;
02832        }
02833 
02834        rc = slapi_pblock_set( pPlugin, SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN, (void *)function );
02835        if ( rc != LDAP_SUCCESS ) {
02836               goto done;
02837        }
02838 
02839        rc = slapi_int_register_plugin( frontendDB, pPlugin );
02840        if ( rc != 0 ) {
02841               rc = LDAP_OTHER;
02842               goto done;
02843        }
02844 
02845 done:
02846        if ( rc != LDAP_SUCCESS ) {
02847               if ( pPlugin != NULL ) {
02848                      slapi_pblock_destroy( pPlugin );
02849               }
02850               return -1;
02851        }
02852 
02853        return 0;
02854 }
02855 
02856 /*
02857  * Call compute evaluators
02858  */
02859 int compute_evaluator(computed_attr_context *c, char *type, Slapi_Entry *e, slapi_compute_output_t outputfn)
02860 {
02861        int rc = 0;
02862        slapi_compute_callback_t *pGetPlugin, *tmpPlugin;
02863 
02864        rc = slapi_int_get_plugins( frontendDB, SLAPI_PLUGIN_COMPUTE_EVALUATOR_FN, (SLAPI_FUNC **)&tmpPlugin );
02865        if ( rc != LDAP_SUCCESS || tmpPlugin == NULL ) {
02866               /* Nothing to do; front-end should ignore. */
02867               return 0;
02868        }
02869 
02870        for ( pGetPlugin = tmpPlugin; *pGetPlugin != NULL; pGetPlugin++ ) {
02871               /*
02872                * -1: no attribute matched requested type
02873                *  0: one attribute matched
02874                * >0: error happened
02875                */
02876               rc = (*pGetPlugin)( c, type, e, outputfn );
02877               if ( rc > 0 ) {
02878                      break;
02879               }
02880        }
02881 
02882        slapi_ch_free( (void **)&tmpPlugin );
02883 
02884        return rc;
02885 }
02886 
02887 int
02888 compute_rewrite_search_filter( Slapi_PBlock *pb )
02889 {
02890        if ( pb == NULL || pb->pb_op == NULL )
02891               return LDAP_PARAM_ERROR;
02892 
02893        return slapi_int_call_plugins( pb->pb_op->o_bd, SLAPI_PLUGIN_COMPUTE_SEARCH_REWRITER_FN, pb );
02894 }
02895 
02896 /*
02897  * New API to provide the plugin with access to the search
02898  * pblock. Have informed Sun DS team.
02899  */
02900 int
02901 slapi_x_compute_get_pblock(computed_attr_context *c, Slapi_PBlock **pb)
02902 {
02903        if ( c == NULL )
02904               return -1;
02905 
02906        if ( c->cac_pb == NULL )
02907               return -1;
02908 
02909        *pb = c->cac_pb;
02910 
02911        return 0;
02912 }
02913 
02914 Slapi_Mutex *slapi_new_mutex( void )
02915 {
02916        Slapi_Mutex *m;
02917 
02918        m = (Slapi_Mutex *)slapi_ch_malloc( sizeof(*m) );
02919        if ( ldap_pvt_thread_mutex_init( &m->mutex ) != 0 ) {
02920               slapi_ch_free( (void **)&m );
02921               return NULL;
02922        }
02923 
02924        return m;
02925 }
02926 
02927 void slapi_destroy_mutex( Slapi_Mutex *mutex )
02928 {
02929        if ( mutex != NULL ) {
02930               ldap_pvt_thread_mutex_destroy( &mutex->mutex );
02931               slapi_ch_free( (void **)&mutex);
02932        }
02933 }
02934 
02935 void slapi_lock_mutex( Slapi_Mutex *mutex )
02936 {
02937        ldap_pvt_thread_mutex_lock( &mutex->mutex );
02938 }
02939 
02940 int slapi_unlock_mutex( Slapi_Mutex *mutex )
02941 {
02942        return ldap_pvt_thread_mutex_unlock( &mutex->mutex );
02943 }
02944 
02945 Slapi_CondVar *slapi_new_condvar( Slapi_Mutex *mutex )
02946 {
02947        Slapi_CondVar *cv;
02948 
02949        if ( mutex == NULL ) {
02950               return NULL;
02951        }
02952 
02953        cv = (Slapi_CondVar *)slapi_ch_malloc( sizeof(*cv) );
02954        if ( ldap_pvt_thread_cond_init( &cv->cond ) != 0 ) {
02955               slapi_ch_free( (void **)&cv );
02956               return NULL;
02957        }
02958 
02959        cv->mutex = mutex->mutex;
02960 
02961        return cv;
02962 }
02963 
02964 void slapi_destroy_condvar( Slapi_CondVar *cvar )
02965 {
02966        if ( cvar != NULL ) {
02967               ldap_pvt_thread_cond_destroy( &cvar->cond );
02968               slapi_ch_free( (void **)&cvar );
02969        }
02970 }
02971 
02972 int slapi_wait_condvar( Slapi_CondVar *cvar, struct timeval *timeout )
02973 {
02974        if ( cvar == NULL ) {
02975               return -1;
02976        }
02977 
02978        return ldap_pvt_thread_cond_wait( &cvar->cond, &cvar->mutex );
02979 }
02980 
02981 int slapi_notify_condvar( Slapi_CondVar *cvar, int notify_all )
02982 {
02983        if ( cvar == NULL ) {
02984               return -1;
02985        }
02986 
02987        if ( notify_all ) {
02988               return ldap_pvt_thread_cond_broadcast( &cvar->cond );
02989        }
02990 
02991        return ldap_pvt_thread_cond_signal( &cvar->cond );
02992 }
02993 
02994 int slapi_int_access_allowed( Operation *op,
02995        Entry *entry,
02996        AttributeDescription *desc,
02997        struct berval *val,
02998        slap_access_t access,
02999        AccessControlState *state )
03000 {
03001        int rc, slap_access = 0;
03002        slapi_acl_callback_t *pGetPlugin, *tmpPlugin;
03003        Slapi_PBlock *pb;
03004 
03005        pb = SLAPI_OPERATION_PBLOCK( op );
03006        if ( pb == NULL ) {
03007               /* internal operation */
03008               return 1;
03009        }
03010 
03011        switch ( access ) {
03012        case ACL_COMPARE:
03013                 slap_access |= SLAPI_ACL_COMPARE;
03014               break;
03015        case ACL_SEARCH:
03016               slap_access |= SLAPI_ACL_SEARCH;
03017               break;
03018        case ACL_READ:
03019               slap_access |= SLAPI_ACL_READ;
03020               break;
03021        case ACL_WRITE:
03022               slap_access |= SLAPI_ACL_WRITE;
03023               break;
03024        case ACL_WDEL:
03025               slap_access |= SLAPI_ACL_DELETE;
03026               break;
03027        case ACL_WADD:
03028               slap_access |= SLAPI_ACL_ADD;
03029               break;
03030        default:
03031               break;
03032         }
03033 
03034        rc = slapi_int_get_plugins( frontendDB, SLAPI_PLUGIN_ACL_ALLOW_ACCESS, (SLAPI_FUNC **)&tmpPlugin );
03035        if ( rc != LDAP_SUCCESS || tmpPlugin == NULL ) {
03036               /* nothing to do; allowed access */
03037               return 1;
03038        }
03039 
03040        rc = 1; /* default allow policy */
03041 
03042        for ( pGetPlugin = tmpPlugin; *pGetPlugin != NULL; pGetPlugin++ ) {
03043               /*
03044                * 0   access denied
03045                * 1   access granted
03046                */
03047               rc = (*pGetPlugin)( pb, entry, desc->ad_cname.bv_val,
03048                                 val, slap_access, (void *)state );
03049               if ( rc == 0 ) {
03050                      break;
03051               }
03052        }
03053 
03054        slapi_ch_free( (void **)&tmpPlugin );
03055 
03056        return rc;
03057 }
03058 
03059 /*
03060  * There is no documentation for this.
03061  */
03062 int slapi_rdn2typeval( char *rdn, char **type, struct berval *bv )
03063 {
03064        LDAPRDN lrdn;
03065        LDAPAVA *ava;
03066        int rc;
03067        char *p;
03068 
03069        *type = NULL;
03070 
03071        bv->bv_len = 0;
03072        bv->bv_val = NULL;
03073 
03074        rc = ldap_str2rdn( rdn, &lrdn, &p, LDAP_DN_FORMAT_LDAPV3 );
03075        if ( rc != LDAP_SUCCESS ) {
03076               return -1;
03077        }
03078 
03079        if ( lrdn[1] != NULL ) {
03080               return -1; /* not single valued */
03081        }
03082 
03083        ava = lrdn[0];
03084 
03085        *type = slapi_ch_strdup( ava->la_attr.bv_val );
03086        ber_dupbv( bv, &ava->la_value );
03087 
03088        ldap_rdnfree(lrdn);
03089 
03090        return 0;
03091 }
03092 
03093 char *slapi_dn_plus_rdn( const char *dn, const char *rdn )
03094 {
03095        struct berval new_dn, parent_dn, newrdn;
03096 
03097        new_dn.bv_val = NULL;
03098 
03099        parent_dn.bv_val = (char *)dn;
03100        parent_dn.bv_len = strlen( dn );
03101 
03102        newrdn.bv_val = (char *)rdn;
03103        newrdn.bv_len = strlen( rdn );
03104 
03105        build_new_dn( &new_dn, &parent_dn, &newrdn, NULL );
03106 
03107        return new_dn.bv_val;
03108 }
03109 
03110 int slapi_entry_schema_check( Slapi_PBlock *pb, Slapi_Entry *e )
03111 {
03112        Backend *be_orig;
03113        const char *text;
03114        char textbuf[SLAP_TEXT_BUFLEN] = { '\0' };
03115        size_t textlen = sizeof textbuf;
03116        int rc = LDAP_SUCCESS;
03117 
03118        PBLOCK_ASSERT_OP( pb, 0 );
03119 
03120        be_orig = pb->pb_op->o_bd;
03121 
03122        pb->pb_op->o_bd = select_backend( &e->e_nname, 0 );
03123        if ( pb->pb_op->o_bd != NULL ) {
03124               rc = entry_schema_check( pb->pb_op, e, NULL, 0, 0, NULL,
03125                      &text, textbuf, textlen );
03126        }
03127        pb->pb_op->o_bd = be_orig;
03128 
03129        return ( rc == LDAP_SUCCESS ) ? 0 : 1;
03130 }
03131 
03132 int slapi_entry_rdn_values_present( const Slapi_Entry *e )
03133 {
03134        LDAPDN dn;
03135        int rc;
03136        int i = 0, match = 0;
03137 
03138        rc = ldap_bv2dn( &((Entry *)e)->e_name, &dn, LDAP_DN_FORMAT_LDAPV3 );
03139        if ( rc != LDAP_SUCCESS ) {
03140               return 0;
03141        }
03142 
03143        if ( dn[0] != NULL ) {
03144               LDAPRDN rdn = dn[0];
03145 
03146               for ( i = 0; rdn[i] != NULL; i++ ) {
03147                      LDAPAVA *ava = &rdn[0][i];
03148                      Slapi_Attr *a = NULL;
03149 
03150                      if ( slapi_entry_attr_find( (Slapi_Entry *)e, ava->la_attr.bv_val, &a ) == 0 &&
03151                           slapi_attr_value_find( a, &ava->la_value ) == 0 )
03152                             match++;
03153               }
03154        }
03155 
03156        ldap_dnfree( dn );
03157 
03158        return ( i == match );
03159 }
03160 
03161 int slapi_entry_add_rdn_values( Slapi_Entry *e )
03162 {
03163        LDAPDN dn;
03164        int i, rc;
03165 
03166        rc = ldap_bv2dn( &e->e_name, &dn, LDAP_DN_FORMAT_LDAPV3 );
03167        if ( rc != LDAP_SUCCESS ) {
03168               return rc;
03169        }
03170 
03171        if ( dn[0] != NULL ) {
03172               LDAPRDN rdn = dn[0];
03173               struct berval *vals[2];
03174 
03175               for ( i = 0; rdn[i] != NULL; i++ ) {
03176                      LDAPAVA *ava = &rdn[0][i];
03177                      Slapi_Attr *a = NULL;
03178 
03179                      if ( slapi_entry_attr_find( e, ava->la_attr.bv_val, &a ) == 0 &&
03180                           slapi_attr_value_find( a, &ava->la_value ) == 0 )
03181                             continue;
03182 
03183                      vals[0] = &ava->la_value;
03184                      vals[1] = NULL;
03185 
03186                      slapi_entry_attr_merge( e, ava->la_attr.bv_val, vals );
03187               }
03188        }
03189 
03190        ldap_dnfree( dn );
03191 
03192        return LDAP_SUCCESS;
03193 }
03194 
03195 const char *slapi_entry_get_uniqueid( const Slapi_Entry *e )
03196 {
03197        Attribute *attr;
03198 
03199        attr = attr_find( e->e_attrs, slap_schema.si_ad_entryUUID );
03200        if ( attr == NULL ) {
03201               return NULL;
03202        }
03203 
03204        if ( attr->a_vals != NULL && attr->a_vals[0].bv_len != 0 ) {
03205               return slapi_value_get_string( &attr->a_vals[0] );
03206        }
03207 
03208        return NULL;
03209 }
03210 
03211 void slapi_entry_set_uniqueid( Slapi_Entry *e, char *uniqueid )
03212 {
03213        struct berval bv;
03214 
03215        attr_delete ( &e->e_attrs, slap_schema.si_ad_entryUUID );
03216 
03217        bv.bv_val = uniqueid;
03218        bv.bv_len = strlen( uniqueid );
03219        attr_merge_normalize_one( e, slap_schema.si_ad_entryUUID, &bv, NULL );
03220 }
03221 
03222 LDAP *slapi_ldap_init( char *ldaphost, int ldapport, int secure, int shared )
03223 {
03224        LDAP *ld;
03225        char *url;
03226        size_t size;
03227        int rc;
03228 
03229        size = sizeof("ldap:///");
03230        if ( secure ) {
03231               size++;
03232        }
03233        size += strlen( ldaphost );
03234        if ( ldapport != 0 ) {
03235               size += 32;
03236        }
03237 
03238        url = slapi_ch_malloc( size );
03239 
03240        if ( ldapport != 0 ) {
03241               rc = snprintf( url, size, "ldap%s://%s:%d/", ( secure ? "s" : "" ), ldaphost, ldapport );
03242        } else {
03243               rc = snprintf( url, size, "ldap%s://%s/", ( secure ? "s" : "" ), ldaphost );
03244        }
03245 
03246        if ( rc > 0 && (size_t) rc < size ) {
03247               rc = ldap_initialize( &ld, url );
03248        } else {
03249               ld = NULL;
03250        }
03251 
03252        slapi_ch_free_string( &url );
03253 
03254        return ( rc == LDAP_SUCCESS ) ? ld : NULL;
03255 }
03256 
03257 void slapi_ldap_unbind( LDAP *ld )
03258 {
03259        ldap_unbind_ext_s( ld, NULL, NULL );
03260 }
03261 
03262 int slapi_x_backend_get_flags( const Slapi_Backend *be, unsigned long *flags )
03263 {
03264        if ( be == NULL )
03265               return LDAP_PARAM_ERROR;
03266 
03267        *flags = SLAP_DBFLAGS(be);
03268 
03269        return LDAP_SUCCESS;
03270 }
03271 
03272 int
03273 slapi_int_count_controls( LDAPControl **ctrls )
03274 {
03275        size_t i;
03276 
03277        if ( ctrls == NULL )
03278               return 0;
03279 
03280        for ( i = 0; ctrls[i] != NULL; i++ )
03281               ;
03282 
03283        return i;
03284 }
03285 
03286 int
03287 slapi_op_abandoned( Slapi_PBlock *pb )
03288 {
03289        if ( pb->pb_op == NULL )
03290               return 0;
03291 
03292        return ( pb->pb_op->o_abandon );
03293 }
03294 
03295 char *
03296 slapi_op_type_to_string(unsigned long type)
03297 {
03298        char *str;
03299 
03300        switch (type) {
03301        case SLAPI_OPERATION_BIND:
03302               str = "bind";
03303               break;
03304        case SLAPI_OPERATION_UNBIND:
03305               str = "unbind";
03306               break;
03307        case SLAPI_OPERATION_SEARCH:
03308               str = "search";
03309               break;
03310        case SLAPI_OPERATION_MODIFY:
03311               str = "modify";
03312               break;
03313        case SLAPI_OPERATION_ADD:
03314               str = "add";
03315               break;
03316        case SLAPI_OPERATION_DELETE:
03317               str = "delete";
03318               break;
03319        case SLAPI_OPERATION_MODDN:
03320               str = "modrdn";
03321               break;
03322        case SLAPI_OPERATION_COMPARE:
03323               str = "compare";
03324               break;
03325        case SLAPI_OPERATION_ABANDON:
03326               str = "abandon";
03327               break;
03328        case SLAPI_OPERATION_EXTENDED:
03329               str = "extended";
03330               break;
03331        default:
03332               str = "unknown operation type";
03333               break;
03334        }
03335        return str;
03336 }
03337 
03338 unsigned long
03339 slapi_op_get_type(Slapi_Operation * op)
03340 {
03341        unsigned long type;
03342 
03343        switch ( op->o_tag ) {
03344        case LDAP_REQ_BIND:
03345               type = SLAPI_OPERATION_BIND;
03346               break;
03347        case LDAP_REQ_UNBIND:
03348               type = SLAPI_OPERATION_UNBIND;
03349               break;
03350        case LDAP_REQ_SEARCH:
03351               type = SLAPI_OPERATION_SEARCH;
03352               break;
03353        case LDAP_REQ_MODIFY:
03354               type = SLAPI_OPERATION_MODIFY;
03355               break;
03356        case LDAP_REQ_ADD:
03357               type = SLAPI_OPERATION_ADD;
03358               break;
03359        case LDAP_REQ_DELETE:
03360               type = SLAPI_OPERATION_DELETE;
03361               break;
03362        case LDAP_REQ_MODRDN:
03363               type = SLAPI_OPERATION_MODDN;
03364               break;
03365        case LDAP_REQ_COMPARE:
03366               type = SLAPI_OPERATION_COMPARE;
03367               break;
03368        case LDAP_REQ_ABANDON:
03369               type = SLAPI_OPERATION_ABANDON;
03370               break;
03371        case LDAP_REQ_EXTENDED:
03372               type = SLAPI_OPERATION_EXTENDED;
03373               break;
03374        default:
03375               type = SLAPI_OPERATION_NONE;
03376               break;
03377        }
03378        return type;
03379 }
03380 
03381 void slapi_be_set_readonly( Slapi_Backend *be, int readonly )
03382 {
03383        if ( be == NULL )
03384               return;
03385 
03386        if ( readonly )
03387               be->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
03388        else
03389               be->be_restrictops &= ~(SLAP_RESTRICT_OP_WRITES);
03390 }
03391 
03392 int slapi_be_get_readonly( Slapi_Backend *be )
03393 {
03394        if ( be == NULL )
03395               return 0;
03396 
03397        return ( (be->be_restrictops & SLAP_RESTRICT_OP_WRITES) == SLAP_RESTRICT_OP_WRITES );
03398 }
03399 
03400 const char *slapi_x_be_get_updatedn( Slapi_Backend *be )
03401 {
03402        if ( be == NULL )
03403               return NULL;
03404 
03405        return be->be_update_ndn.bv_val;
03406 }
03407 
03408 Slapi_Backend *slapi_be_select( const Slapi_DN *sdn )
03409 {
03410        Slapi_Backend *be;
03411 
03412        slapi_sdn_get_ndn( sdn );
03413 
03414        be = select_backend( (struct berval *)&sdn->ndn, 0 );
03415 
03416        return be;
03417 }
03418 
03419 #if 0
03420 void
03421 slapi_operation_set_flag(Slapi_Operation *op, unsigned long flag)
03422 {
03423 }
03424 
03425 void
03426 slapi_operation_clear_flag(Slapi_Operation *op, unsigned long flag)
03427 {
03428 }
03429 
03430 int
03431 slapi_operation_is_flag_set(Slapi_Operation *op, unsigned long flag)
03432 {
03433 }
03434 #endif
03435 
03436 #endif /* LDAP_SLAPI */
03437