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