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