Home | History | Annotate | Line # | Download | only in allop
allop.c revision 1.1
      1 /* allop.c - returns all operational attributes when appropriate */
      2 /* $OpenLDAP: pkg/ldap/contrib/slapd-modules/allop/allop.c,v 1.3.2.3 2008/02/11 23:26:38 kurt Exp $ */
      3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      4  *
      5  * Copyright 2005-2008 The OpenLDAP Foundation.
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted only as authorized by the OpenLDAP
     10  * Public License.
     11  *
     12  * A copy of this license is available in the file LICENSE in the
     13  * top-level directory of the distribution or, alternatively, at
     14  * <http://www.OpenLDAP.org/license.html>.
     15  */
     16 /* ACKNOWLEDGEMENTS:
     17  * This work was initially developed by Pierangelo Masarati for inclusion in
     18  * OpenLDAP Software.
     19  */
     20 
     21 /*
     22  * The intended usage is as a global overlay for use with those clients
     23  * that do not make use of the RFC3673 allOp ("+") in the requested
     24  * attribute list, but expect all operational attributes to be returned.
     25  * Usage: add
     26  *
     27 
     28 overlay		allop
     29 allop-URI	<ldapURI>
     30 
     31  *
     32  * if the allop-URI is not given, the rootDSE, i.e. "ldap:///??base",
     33  * is assumed.
     34  */
     35 
     36 #include "portable.h"
     37 
     38 #include <stdio.h>
     39 #include <ac/string.h>
     40 
     41 #include "slap.h"
     42 #include "config.h"
     43 
     44 #define	SLAP_OVER_VERSION_REQUIRE(major,minor,patch) \
     45 	( \
     46 		( LDAP_VENDOR_VERSION_MAJOR == X || LDAP_VENDOR_VERSION_MAJOR >= (major) ) \
     47 		&& ( LDAP_VENDOR_VERSION_MINOR == X || LDAP_VENDOR_VERSION_MINOR >= (minor) ) \
     48 		&& ( LDAP_VENDOR_VERSION_PATCH == X || LDAP_VENDOR_VERSION_PATCH >= (patch) ) \
     49 	)
     50 
     51 #if !SLAP_OVER_VERSION_REQUIRE(2,3,0)
     52 #error "version mismatch"
     53 #endif
     54 
     55 typedef struct allop_t {
     56 	struct berval	ao_ndn;
     57 	int		ao_scope;
     58 } allop_t;
     59 
     60 static int
     61 allop_db_config(
     62 	BackendDB	*be,
     63 	const char	*fname,
     64 	int		lineno,
     65 	int		argc,
     66 	char		**argv )
     67 {
     68 	slap_overinst	*on = (slap_overinst *)be->bd_info;
     69 	allop_t		*ao = (allop_t *)on->on_bi.bi_private;
     70 
     71 	if ( strcasecmp( argv[ 0 ], "allop-uri" ) == 0 ) {
     72 		LDAPURLDesc	*lud;
     73 		struct berval	dn,
     74 				ndn;
     75 		int		scope,
     76 				rc = LDAP_SUCCESS;
     77 
     78 		if ( argc != 2 ) {
     79 			fprintf( stderr, "%s line %d: "
     80 				"need exactly 1 arg "
     81 				"in \"allop-uri <ldapURI>\" "
     82 				"directive.\n",
     83 				fname, lineno );
     84 			return 1;
     85 		}
     86 
     87 		if ( ldap_url_parse( argv[ 1 ], &lud ) != LDAP_URL_SUCCESS ) {
     88 			return -1;
     89 		}
     90 
     91 		scope = lud->lud_scope;
     92 		if ( scope == LDAP_SCOPE_DEFAULT ) {
     93 			scope = LDAP_SCOPE_BASE;
     94 		}
     95 
     96 		if ( lud->lud_dn == NULL || lud->lud_dn[ 0 ] == '\0' ) {
     97 			if ( scope == LDAP_SCOPE_BASE ) {
     98 				BER_BVZERO( &ndn );
     99 
    100 			} else {
    101 				ber_str2bv( "", 0, 1, &ndn );
    102 			}
    103 
    104 		} else {
    105 
    106 			ber_str2bv( lud->lud_dn, 0, 0, &dn );
    107 			rc = dnNormalize( 0, NULL, NULL, &dn, &ndn, NULL );
    108 		}
    109 
    110 		ldap_free_urldesc( lud );
    111 		if ( rc != LDAP_SUCCESS ) {
    112 			return -1;
    113 		}
    114 
    115 		if ( BER_BVISNULL( &ndn ) ) {
    116 			/* rootDSE */
    117 			if ( ao != NULL ) {
    118 				ch_free( ao->ao_ndn.bv_val );
    119 				ch_free( ao );
    120 				on->on_bi.bi_private = NULL;
    121 			}
    122 
    123 		} else {
    124 			if ( ao == NULL ) {
    125 				ao = ch_calloc( 1, sizeof( allop_t ) );
    126 				on->on_bi.bi_private = (void *)ao;
    127 
    128 			} else {
    129 				ch_free( ao->ao_ndn.bv_val );
    130 			}
    131 
    132 			ao->ao_ndn = ndn;
    133 			ao->ao_scope = scope;
    134 		}
    135 
    136 	} else {
    137 		return SLAP_CONF_UNKNOWN;
    138 	}
    139 
    140 	return 0;
    141 }
    142 
    143 static int
    144 allop_db_destroy( BackendDB *be, ConfigReply *cr )
    145 {
    146 	slap_overinst	*on = (slap_overinst *)be->bd_info;
    147 	allop_t		*ao = (allop_t *)on->on_bi.bi_private;
    148 
    149 	if ( ao != NULL ) {
    150 		assert( !BER_BVISNULL( &ao->ao_ndn ) );
    151 
    152 		ch_free( ao->ao_ndn.bv_val );
    153 		ch_free( ao );
    154 		on->on_bi.bi_private = NULL;
    155 	}
    156 
    157 	return 0;
    158 }
    159 
    160 static int
    161 allop_op_search( Operation *op, SlapReply *rs )
    162 {
    163 	slap_overinst	*on = (slap_overinst *)op->o_bd->bd_info;
    164 	allop_t		*ao = (allop_t *)on->on_bi.bi_private;
    165 
    166 	slap_mask_t	mask;
    167 	int		i,
    168 			add_allUser = 0;
    169 
    170 	if ( ao == NULL ) {
    171 		if ( !BER_BVISEMPTY( &op->o_req_ndn )
    172 			|| op->ors_scope != LDAP_SCOPE_BASE )
    173 		{
    174 			return SLAP_CB_CONTINUE;
    175 		}
    176 
    177 	} else {
    178 		if ( !dnIsSuffix( &op->o_req_ndn, &ao->ao_ndn ) ) {
    179 			return SLAP_CB_CONTINUE;
    180 		}
    181 
    182 		switch ( ao->ao_scope ) {
    183 		case LDAP_SCOPE_BASE:
    184 			if ( op->o_req_ndn.bv_len != ao->ao_ndn.bv_len ) {
    185 				return SLAP_CB_CONTINUE;
    186 			}
    187 			break;
    188 
    189 		case LDAP_SCOPE_ONELEVEL:
    190 			if ( op->ors_scope == LDAP_SCOPE_BASE ) {
    191 				struct berval	rdn = op->o_req_ndn;
    192 
    193 				rdn.bv_len -= ao->ao_ndn.bv_len + STRLENOF( "," );
    194 				if ( !dnIsOneLevelRDN( &rdn ) ) {
    195 					return SLAP_CB_CONTINUE;
    196 				}
    197 
    198 				break;
    199 			}
    200 			return SLAP_CB_CONTINUE;
    201 
    202 		case LDAP_SCOPE_SUBTREE:
    203 			break;
    204 		}
    205 	}
    206 
    207 	mask = slap_attr_flags( op->ors_attrs );
    208 	if ( SLAP_OPATTRS( mask ) ) {
    209 		return SLAP_CB_CONTINUE;
    210 	}
    211 
    212 	if ( !SLAP_USERATTRS( mask ) ) {
    213 		return SLAP_CB_CONTINUE;
    214 	}
    215 
    216 	i = 0;
    217 	if ( op->ors_attrs == NULL ) {
    218 		add_allUser = 1;
    219 
    220 	} else {
    221 		for ( ; !BER_BVISNULL( &op->ors_attrs[ i ].an_name ); i++ )
    222 			;
    223 	}
    224 
    225 	op->ors_attrs = op->o_tmprealloc( op->ors_attrs,
    226 		sizeof( AttributeName ) * ( i + add_allUser + 2 ),
    227 		op->o_tmpmemctx );
    228 
    229 	if ( add_allUser ) {
    230 		op->ors_attrs[ i ] = slap_anlist_all_user_attributes[ 0 ];
    231 		i++;
    232 	}
    233 
    234 	op->ors_attrs[ i ] = slap_anlist_all_operational_attributes[ 0 ];
    235 
    236 	BER_BVZERO( &op->ors_attrs[ i + 1 ].an_name );
    237 
    238 	return SLAP_CB_CONTINUE;
    239 }
    240 
    241 static slap_overinst 		allop;
    242 
    243 int
    244 allop_init()
    245 {
    246 	allop.on_bi.bi_type = "allop";
    247 
    248 	allop.on_bi.bi_db_config = allop_db_config;
    249 	allop.on_bi.bi_db_destroy = allop_db_destroy;
    250 
    251 	allop.on_bi.bi_op_search = allop_op_search;
    252 
    253 	return overlay_register( &allop );
    254 }
    255 
    256 int
    257 init_module( int argc, char *argv[] )
    258 {
    259 	return allop_init();
    260 }
    261 
    262