Back to index

openldap  2.4.31
allop.c
Go to the documentation of this file.
00001 /* allop.c - returns all operational attributes when appropriate */
00002 /* $OpenLDAP$ */
00003 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
00004  *
00005  * Copyright 2005-2012 The OpenLDAP Foundation.
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 Pierangelo Masarati for inclusion in
00018  * OpenLDAP Software.
00019  */
00020 
00021 /*
00022  * The intended usage is as a global overlay for use with those clients
00023  * that do not make use of the RFC3673 allOp ("+") in the requested 
00024  * attribute list, but expect all operational attributes to be returned.
00025  * Usage: add
00026  *
00027 
00028 overlay              allop
00029 allop-URI     <ldapURI>
00030 
00031  *
00032  * if the allop-URI is not given, the rootDSE, i.e. "ldap:///??base",
00033  * is assumed.
00034  */
00035 
00036 #include "portable.h"
00037 
00038 #include <stdio.h>
00039 #include <ac/string.h>
00040 
00041 #include "slap.h"
00042 #include "config.h"
00043 
00044 #define       SLAP_OVER_VERSION_REQUIRE(major,minor,patch) \
00045        ( \
00046               ( LDAP_VENDOR_VERSION_MAJOR == X || LDAP_VENDOR_VERSION_MAJOR >= (major) ) \
00047               && ( LDAP_VENDOR_VERSION_MINOR == X || LDAP_VENDOR_VERSION_MINOR >= (minor) ) \
00048               && ( LDAP_VENDOR_VERSION_PATCH == X || LDAP_VENDOR_VERSION_PATCH >= (patch) ) \
00049        )
00050 
00051 #if !SLAP_OVER_VERSION_REQUIRE(2,3,0)
00052 #error "version mismatch"
00053 #endif
00054 
00055 typedef struct allop_t {
00056        struct berval ao_ndn;
00057        int           ao_scope;
00058 } allop_t;
00059 
00060 static int
00061 allop_db_config(
00062        BackendDB     *be,
00063        const char    *fname,
00064        int           lineno,
00065        int           argc,
00066        char          **argv )
00067 {
00068        slap_overinst *on = (slap_overinst *)be->bd_info;
00069        allop_t              *ao = (allop_t *)on->on_bi.bi_private;
00070 
00071        if ( strcasecmp( argv[ 0 ], "allop-uri" ) == 0 ) {
00072               LDAPURLDesc   *lud;
00073               struct berval dn,
00074                             ndn;
00075               int           scope,
00076                             rc = LDAP_SUCCESS;
00077 
00078               if ( argc != 2 ) {
00079                      fprintf( stderr, "%s line %d: "
00080                             "need exactly 1 arg "
00081                             "in \"allop-uri <ldapURI>\" "
00082                             "directive.\n",
00083                             fname, lineno );
00084                      return 1;
00085               }
00086 
00087               if ( ldap_url_parse( argv[ 1 ], &lud ) != LDAP_URL_SUCCESS ) {
00088                      return -1;
00089               }
00090 
00091               scope = lud->lud_scope;
00092               if ( scope == LDAP_SCOPE_DEFAULT ) {
00093                      scope = LDAP_SCOPE_BASE;
00094               }
00095 
00096               if ( lud->lud_dn == NULL || lud->lud_dn[ 0 ] == '\0' ) {
00097                      if ( scope == LDAP_SCOPE_BASE ) {
00098                             BER_BVZERO( &ndn );
00099 
00100                      } else {
00101                             ber_str2bv( "", 0, 1, &ndn );
00102                      }
00103 
00104               } else {
00105 
00106                      ber_str2bv( lud->lud_dn, 0, 0, &dn );
00107                      rc = dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL );
00108               }
00109 
00110               ldap_free_urldesc( lud );
00111               if ( rc != LDAP_SUCCESS ) {
00112                      return -1;
00113               }
00114 
00115               if ( BER_BVISNULL( &ndn ) ) {
00116                      /* rootDSE */
00117                      if ( ao != NULL ) {
00118                             ch_free( ao->ao_ndn.bv_val );
00119                             ch_free( ao );
00120                             on->on_bi.bi_private = NULL;
00121                      }
00122 
00123               } else {
00124                      if ( ao == NULL ) {
00125                             ao = ch_calloc( 1, sizeof( allop_t ) );
00126                             on->on_bi.bi_private = (void *)ao;
00127 
00128                      } else {
00129                             ch_free( ao->ao_ndn.bv_val );
00130                      }
00131 
00132                      ao->ao_ndn = ndn;
00133                      ao->ao_scope = scope;
00134               }
00135 
00136        } else {
00137               return SLAP_CONF_UNKNOWN;
00138        }
00139 
00140        return 0;
00141 }
00142 
00143 static int
00144 allop_db_destroy( BackendDB *be, ConfigReply *cr )
00145 {
00146        slap_overinst *on = (slap_overinst *)be->bd_info;
00147        allop_t              *ao = (allop_t *)on->on_bi.bi_private;
00148 
00149        if ( ao != NULL ) {
00150               assert( !BER_BVISNULL( &ao->ao_ndn ) );
00151 
00152               ch_free( ao->ao_ndn.bv_val );
00153               ch_free( ao );
00154               on->on_bi.bi_private = NULL;
00155        }
00156 
00157        return 0;
00158 }
00159 
00160 static int
00161 allop_op_search( Operation *op, SlapReply *rs )
00162 {
00163        slap_overinst *on = (slap_overinst *)op->o_bd->bd_info;
00164        allop_t              *ao = (allop_t *)on->on_bi.bi_private;
00165 
00166        slap_mask_t   mask;
00167        int           i,
00168                      add_allUser = 0;
00169 
00170        if ( ao == NULL ) {
00171               if ( !BER_BVISEMPTY( &op->o_req_ndn )
00172                      || op->ors_scope != LDAP_SCOPE_BASE )
00173               {
00174                      return SLAP_CB_CONTINUE;
00175               }
00176 
00177        } else {
00178               if ( !dnIsSuffix( &op->o_req_ndn, &ao->ao_ndn ) ) {
00179                      return SLAP_CB_CONTINUE;
00180               }
00181 
00182               switch ( ao->ao_scope ) {
00183               case LDAP_SCOPE_BASE:
00184                      if ( op->o_req_ndn.bv_len != ao->ao_ndn.bv_len ) {
00185                             return SLAP_CB_CONTINUE;
00186                      }
00187                      break;
00188 
00189               case LDAP_SCOPE_ONELEVEL:
00190                      if ( op->ors_scope == LDAP_SCOPE_BASE ) {
00191                             struct berval rdn = op->o_req_ndn;
00192 
00193                             rdn.bv_len -= ao->ao_ndn.bv_len + STRLENOF( "," );
00194                             if ( !dnIsOneLevelRDN( &rdn ) ) {
00195                                    return SLAP_CB_CONTINUE;
00196                             }
00197 
00198                             break;
00199                      }
00200                      return SLAP_CB_CONTINUE;
00201 
00202               case LDAP_SCOPE_SUBTREE:
00203                      break;
00204               }
00205        }
00206 
00207        mask = slap_attr_flags( op->ors_attrs );
00208        if ( SLAP_OPATTRS( mask ) ) {
00209               return SLAP_CB_CONTINUE;
00210        }
00211 
00212        if ( !SLAP_USERATTRS( mask ) ) {
00213               return SLAP_CB_CONTINUE;
00214        }
00215 
00216        i = 0;
00217        if ( op->ors_attrs == NULL ) {
00218               add_allUser = 1;
00219 
00220        } else {
00221               for ( ; !BER_BVISNULL( &op->ors_attrs[ i ].an_name ); i++ )
00222                      ;
00223        }
00224 
00225        op->ors_attrs = op->o_tmprealloc( op->ors_attrs,
00226               sizeof( AttributeName ) * ( i + add_allUser + 2 ),
00227               op->o_tmpmemctx );
00228 
00229        if ( add_allUser ) {
00230               op->ors_attrs[ i ] = slap_anlist_all_user_attributes[ 0 ];
00231               i++;
00232        }
00233 
00234        op->ors_attrs[ i ] = slap_anlist_all_operational_attributes[ 0 ];
00235 
00236        BER_BVZERO( &op->ors_attrs[ i + 1 ].an_name );
00237 
00238        return SLAP_CB_CONTINUE;
00239 }
00240 
00241 static slap_overinst               allop;
00242 
00243 int
00244 allop_init()
00245 {
00246        allop.on_bi.bi_type = "allop";
00247 
00248        allop.on_bi.bi_db_config = allop_db_config;
00249        allop.on_bi.bi_db_destroy = allop_db_destroy;
00250 
00251        allop.on_bi.bi_op_search = allop_op_search;
00252 
00253        return overlay_register( &allop );
00254 }
00255 
00256 int
00257 init_module( int argc, char *argv[] )
00258 {
00259        return allop_init();
00260 }
00261