1 1.3 christos /* $NetBSD: init.c,v 1.4 2025/09/05 21:16:28 christos Exp $ */ 2 1.2 christos 3 1.1 lukem /* init.c - initialize monitor backend */ 4 1.2 christos /* $OpenLDAP$ */ 5 1.1 lukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 6 1.1 lukem * 7 1.4 christos * Copyright 2001-2024 The OpenLDAP Foundation. 8 1.1 lukem * Portions Copyright 2001-2003 Pierangelo Masarati. 9 1.1 lukem * All rights reserved. 10 1.1 lukem * 11 1.1 lukem * Redistribution and use in source and binary forms, with or without 12 1.1 lukem * modification, are permitted only as authorized by the OpenLDAP 13 1.1 lukem * Public License. 14 1.1 lukem * 15 1.1 lukem * A copy of this license is available in file LICENSE in the 16 1.1 lukem * top-level directory of the distribution or, alternatively, at 17 1.1 lukem * <http://www.OpenLDAP.org/license.html>. 18 1.1 lukem */ 19 1.1 lukem /* ACKNOWLEDGEMENTS: 20 1.1 lukem * This work was initially developed by Pierangelo Masarati for inclusion 21 1.1 lukem * in OpenLDAP Software. 22 1.1 lukem */ 23 1.1 lukem 24 1.2 christos #include <sys/cdefs.h> 25 1.3 christos __RCSID("$NetBSD: init.c,v 1.4 2025/09/05 21:16:28 christos Exp $"); 26 1.2 christos 27 1.1 lukem #include "portable.h" 28 1.1 lukem 29 1.1 lukem #include <stdio.h> 30 1.1 lukem #include <ac/string.h> 31 1.1 lukem 32 1.1 lukem #include <lutil.h> 33 1.1 lukem #include "slap.h" 34 1.3 christos #include "slap-config.h" 35 1.1 lukem #include "lber_pvt.h" 36 1.1 lukem #include "back-monitor.h" 37 1.1 lukem 38 1.3 christos #include "slap-config.h" 39 1.1 lukem 40 1.1 lukem #undef INTEGRATE_CORE_SCHEMA 41 1.1 lukem 42 1.1 lukem /* 43 1.1 lukem * used by many functions to add description to entries 44 1.1 lukem * 45 1.1 lukem * WARNING: be_monitor may change as new databases are added, 46 1.1 lukem * so it should not be used outside monitor_back_db_init() 47 1.1 lukem * until monitor_back_db_open is called. 48 1.1 lukem */ 49 1.1 lukem BackendDB *be_monitor; 50 1.1 lukem 51 1.1 lukem static struct monitor_subsys_t **monitor_subsys; 52 1.1 lukem static int monitor_subsys_opened; 53 1.1 lukem static monitor_info_t monitor_info; 54 1.1 lukem static const monitor_extra_t monitor_extra = { 55 1.1 lukem monitor_back_is_configured, 56 1.1 lukem monitor_back_get_subsys, 57 1.1 lukem monitor_back_get_subsys_by_dn, 58 1.1 lukem 59 1.1 lukem monitor_back_register_subsys, 60 1.1 lukem monitor_back_register_backend, 61 1.1 lukem monitor_back_register_database, 62 1.1 lukem monitor_back_register_overlay_info, 63 1.1 lukem monitor_back_register_overlay, 64 1.1 lukem monitor_back_register_entry, 65 1.1 lukem monitor_back_register_entry_parent, 66 1.1 lukem monitor_back_register_entry_attrs, 67 1.1 lukem monitor_back_register_entry_callback, 68 1.1 lukem 69 1.1 lukem monitor_back_unregister_entry, 70 1.1 lukem monitor_back_unregister_entry_parent, 71 1.1 lukem monitor_back_unregister_entry_attrs, 72 1.2 christos monitor_back_unregister_entry_callback, 73 1.2 christos 74 1.2 christos monitor_back_entry_stub, 75 1.2 christos monitor_back_entrypriv_create, 76 1.3 christos monitor_back_register_subsys_late, 77 1.3 christos monitor_back_entry_get_unlocked 78 1.1 lukem }; 79 1.1 lukem 80 1.1 lukem 81 1.1 lukem /* 82 1.1 lukem * subsystem data 83 1.1 lukem * 84 1.1 lukem * the known subsystems are added to the subsystems 85 1.1 lukem * array at backend initialization; other subsystems 86 1.1 lukem * may be added by calling monitor_back_register_subsys() 87 1.1 lukem * before the database is opened (e.g. by other backends 88 1.1 lukem * or by overlays or modules). 89 1.1 lukem */ 90 1.1 lukem static struct monitor_subsys_t known_monitor_subsys[] = { 91 1.1 lukem { 92 1.1 lukem SLAPD_MONITOR_BACKEND_NAME, 93 1.1 lukem BER_BVNULL, BER_BVNULL, BER_BVNULL, 94 1.1 lukem { BER_BVC( "This subsystem contains information about available backends." ), 95 1.1 lukem BER_BVNULL }, 96 1.1 lukem MONITOR_F_PERSISTENT_CH, 97 1.1 lukem monitor_subsys_backend_init, 98 1.1 lukem NULL, /* destroy */ 99 1.1 lukem NULL, /* update */ 100 1.1 lukem NULL, /* create */ 101 1.1 lukem NULL /* modify */ 102 1.1 lukem }, { 103 1.1 lukem SLAPD_MONITOR_CONN_NAME, 104 1.1 lukem BER_BVNULL, BER_BVNULL, BER_BVNULL, 105 1.1 lukem { BER_BVC( "This subsystem contains information about connections." ), 106 1.1 lukem BER_BVNULL }, 107 1.1 lukem MONITOR_F_VOLATILE_CH, 108 1.1 lukem monitor_subsys_conn_init, 109 1.1 lukem NULL, /* destroy */ 110 1.1 lukem NULL, /* update */ 111 1.1 lukem NULL, /* create */ 112 1.1 lukem NULL /* modify */ 113 1.1 lukem }, { 114 1.1 lukem SLAPD_MONITOR_DATABASE_NAME, 115 1.1 lukem BER_BVNULL, BER_BVNULL, BER_BVNULL, 116 1.1 lukem { BER_BVC( "This subsystem contains information about configured databases." ), 117 1.1 lukem BER_BVNULL }, 118 1.1 lukem MONITOR_F_PERSISTENT_CH, 119 1.1 lukem monitor_subsys_database_init, 120 1.1 lukem NULL, /* destroy */ 121 1.1 lukem NULL, /* update */ 122 1.1 lukem NULL, /* create */ 123 1.1 lukem NULL /* modify */ 124 1.1 lukem }, { 125 1.1 lukem SLAPD_MONITOR_LISTENER_NAME, 126 1.1 lukem BER_BVNULL, BER_BVNULL, BER_BVNULL, 127 1.1 lukem { BER_BVC( "This subsystem contains information about active listeners." ), 128 1.1 lukem BER_BVNULL }, 129 1.1 lukem MONITOR_F_PERSISTENT_CH, 130 1.1 lukem monitor_subsys_listener_init, 131 1.1 lukem NULL, /* destroy */ 132 1.1 lukem NULL, /* update */ 133 1.1 lukem NULL, /* create */ 134 1.1 lukem NULL /* modify */ 135 1.1 lukem }, { 136 1.1 lukem SLAPD_MONITOR_LOG_NAME, 137 1.1 lukem BER_BVNULL, BER_BVNULL, BER_BVNULL, 138 1.1 lukem { BER_BVC( "This subsystem contains information about logging." ), 139 1.4 christos BER_BVC( "Set the \"monitorLogLevel\" or \"monitorDebugLevel\" attributes to the desired levels." ), 140 1.1 lukem BER_BVNULL }, 141 1.1 lukem MONITOR_F_NONE, 142 1.1 lukem monitor_subsys_log_init, 143 1.1 lukem NULL, /* destroy */ 144 1.1 lukem NULL, /* update */ 145 1.1 lukem NULL, /* create */ 146 1.1 lukem NULL, /* modify */ 147 1.1 lukem }, { 148 1.1 lukem SLAPD_MONITOR_OPS_NAME, 149 1.1 lukem BER_BVNULL, BER_BVNULL, BER_BVNULL, 150 1.1 lukem { BER_BVC( "This subsystem contains information about performed operations." ), 151 1.1 lukem BER_BVNULL }, 152 1.1 lukem MONITOR_F_PERSISTENT_CH, 153 1.1 lukem monitor_subsys_ops_init, 154 1.1 lukem NULL, /* destroy */ 155 1.1 lukem NULL, /* update */ 156 1.1 lukem NULL, /* create */ 157 1.1 lukem NULL, /* modify */ 158 1.1 lukem }, { 159 1.1 lukem SLAPD_MONITOR_OVERLAY_NAME, 160 1.1 lukem BER_BVNULL, BER_BVNULL, BER_BVNULL, 161 1.1 lukem { BER_BVC( "This subsystem contains information about available overlays." ), 162 1.1 lukem BER_BVNULL }, 163 1.1 lukem MONITOR_F_PERSISTENT_CH, 164 1.1 lukem monitor_subsys_overlay_init, 165 1.1 lukem NULL, /* destroy */ 166 1.1 lukem NULL, /* update */ 167 1.1 lukem NULL, /* create */ 168 1.1 lukem NULL, /* modify */ 169 1.1 lukem }, { 170 1.1 lukem SLAPD_MONITOR_SASL_NAME, 171 1.1 lukem BER_BVNULL, BER_BVNULL, BER_BVNULL, 172 1.1 lukem { BER_BVC( "This subsystem contains information about SASL." ), 173 1.1 lukem BER_BVNULL }, 174 1.1 lukem MONITOR_F_NONE, 175 1.1 lukem NULL, /* init */ 176 1.1 lukem NULL, /* destroy */ 177 1.1 lukem NULL, /* update */ 178 1.1 lukem NULL, /* create */ 179 1.1 lukem NULL /* modify */ 180 1.1 lukem }, { 181 1.1 lukem SLAPD_MONITOR_SENT_NAME, 182 1.1 lukem BER_BVNULL, BER_BVNULL, BER_BVNULL, 183 1.1 lukem { BER_BVC( "This subsystem contains statistics." ), 184 1.1 lukem BER_BVNULL }, 185 1.1 lukem MONITOR_F_PERSISTENT_CH, 186 1.1 lukem monitor_subsys_sent_init, 187 1.1 lukem NULL, /* destroy */ 188 1.1 lukem NULL, /* update */ 189 1.1 lukem NULL, /* create */ 190 1.1 lukem NULL, /* modify */ 191 1.1 lukem }, { 192 1.1 lukem SLAPD_MONITOR_THREAD_NAME, 193 1.1 lukem BER_BVNULL, BER_BVNULL, BER_BVNULL, 194 1.1 lukem { BER_BVC( "This subsystem contains information about threads." ), 195 1.1 lukem BER_BVNULL }, 196 1.1 lukem MONITOR_F_PERSISTENT_CH, 197 1.1 lukem monitor_subsys_thread_init, 198 1.1 lukem NULL, /* destroy */ 199 1.1 lukem NULL, /* update */ 200 1.1 lukem NULL, /* create */ 201 1.1 lukem NULL /* modify */ 202 1.1 lukem }, { 203 1.1 lukem SLAPD_MONITOR_TIME_NAME, 204 1.1 lukem BER_BVNULL, BER_BVNULL, BER_BVNULL, 205 1.1 lukem { BER_BVC( "This subsystem contains information about time." ), 206 1.1 lukem BER_BVNULL }, 207 1.1 lukem MONITOR_F_PERSISTENT_CH, 208 1.1 lukem monitor_subsys_time_init, 209 1.1 lukem NULL, /* destroy */ 210 1.1 lukem NULL, /* update */ 211 1.1 lukem NULL, /* create */ 212 1.1 lukem NULL, /* modify */ 213 1.1 lukem }, { 214 1.1 lukem SLAPD_MONITOR_TLS_NAME, 215 1.1 lukem BER_BVNULL, BER_BVNULL, BER_BVNULL, 216 1.1 lukem { BER_BVC( "This subsystem contains information about TLS." ), 217 1.1 lukem BER_BVNULL }, 218 1.1 lukem MONITOR_F_NONE, 219 1.1 lukem NULL, /* init */ 220 1.1 lukem NULL, /* destroy */ 221 1.1 lukem NULL, /* update */ 222 1.1 lukem NULL, /* create */ 223 1.1 lukem NULL /* modify */ 224 1.1 lukem }, { 225 1.1 lukem SLAPD_MONITOR_RWW_NAME, 226 1.1 lukem BER_BVNULL, BER_BVNULL, BER_BVNULL, 227 1.1 lukem { BER_BVC( "This subsystem contains information about read/write waiters." ), 228 1.1 lukem BER_BVNULL }, 229 1.1 lukem MONITOR_F_PERSISTENT_CH, 230 1.1 lukem monitor_subsys_rww_init, 231 1.1 lukem NULL, /* destroy */ 232 1.1 lukem NULL, /* update */ 233 1.1 lukem NULL, /* create */ 234 1.1 lukem NULL /* modify */ 235 1.1 lukem }, { NULL } 236 1.1 lukem }; 237 1.1 lukem 238 1.1 lukem int 239 1.1 lukem monitor_subsys_is_opened( void ) 240 1.1 lukem { 241 1.1 lukem return monitor_subsys_opened; 242 1.1 lukem } 243 1.1 lukem 244 1.1 lukem int 245 1.1 lukem monitor_back_register_subsys( 246 1.1 lukem monitor_subsys_t *ms ) 247 1.1 lukem { 248 1.1 lukem int i = 0; 249 1.1 lukem 250 1.1 lukem if ( monitor_subsys ) { 251 1.1 lukem for ( ; monitor_subsys[ i ] != NULL; i++ ) 252 1.1 lukem /* just count'em */ ; 253 1.1 lukem } 254 1.1 lukem 255 1.1 lukem monitor_subsys = ch_realloc( monitor_subsys, 256 1.1 lukem ( 2 + i ) * sizeof( monitor_subsys_t * ) ); 257 1.1 lukem 258 1.1 lukem if ( monitor_subsys == NULL ) { 259 1.1 lukem return -1; 260 1.1 lukem } 261 1.1 lukem 262 1.1 lukem monitor_subsys[ i ] = ms; 263 1.1 lukem monitor_subsys[ i + 1 ] = NULL; 264 1.1 lukem 265 1.1 lukem /* if a subsystem is registered __AFTER__ subsystem 266 1.1 lukem * initialization (depending on the sequence the databases 267 1.1 lukem * are listed in slapd.conf), init it */ 268 1.1 lukem if ( monitor_subsys_is_opened() ) { 269 1.1 lukem 270 1.1 lukem /* FIXME: this should only be possible 271 1.1 lukem * if be_monitor is already initialized */ 272 1.1 lukem assert( be_monitor != NULL ); 273 1.1 lukem 274 1.1 lukem if ( ms->mss_open && ( *ms->mss_open )( be_monitor, ms ) ) { 275 1.1 lukem return -1; 276 1.1 lukem } 277 1.1 lukem 278 1.1 lukem ms->mss_flags |= MONITOR_F_OPENED; 279 1.1 lukem } 280 1.1 lukem 281 1.1 lukem return 0; 282 1.1 lukem } 283 1.1 lukem 284 1.1 lukem enum { 285 1.1 lukem LIMBO_ENTRY, 286 1.1 lukem LIMBO_ENTRY_PARENT, 287 1.1 lukem LIMBO_ATTRS, 288 1.1 lukem LIMBO_CB, 289 1.1 lukem LIMBO_BACKEND, 290 1.1 lukem LIMBO_DATABASE, 291 1.1 lukem LIMBO_OVERLAY_INFO, 292 1.1 lukem LIMBO_OVERLAY, 293 1.2 christos LIMBO_SUBSYS, 294 1.1 lukem 295 1.1 lukem LIMBO_LAST 296 1.1 lukem }; 297 1.1 lukem 298 1.1 lukem typedef struct entry_limbo_t { 299 1.1 lukem int el_type; 300 1.1 lukem BackendInfo *el_bi; 301 1.1 lukem BackendDB *el_be; 302 1.1 lukem slap_overinst *el_on; 303 1.1 lukem Entry *el_e; 304 1.1 lukem Attribute *el_a; 305 1.1 lukem struct berval *el_ndn; 306 1.1 lukem struct berval el_nbase; 307 1.1 lukem int el_scope; 308 1.1 lukem struct berval el_filter; 309 1.1 lukem monitor_callback_t *el_cb; 310 1.1 lukem monitor_subsys_t *el_mss; 311 1.1 lukem unsigned long el_flags; 312 1.1 lukem struct entry_limbo_t *el_next; 313 1.1 lukem } entry_limbo_t; 314 1.1 lukem 315 1.1 lukem int 316 1.1 lukem monitor_back_is_configured( void ) 317 1.1 lukem { 318 1.1 lukem return be_monitor != NULL; 319 1.1 lukem } 320 1.1 lukem 321 1.1 lukem int 322 1.2 christos monitor_back_register_subsys_late( 323 1.2 christos monitor_subsys_t *ms ) 324 1.2 christos { 325 1.2 christos entry_limbo_t **elpp, el = { 0 }; 326 1.2 christos monitor_info_t *mi; 327 1.2 christos 328 1.2 christos if ( be_monitor == NULL ) { 329 1.2 christos Debug( LDAP_DEBUG_ANY, 330 1.2 christos "monitor_back_register_subsys_late: " 331 1.3 christos "monitor database not configured.\n" ); 332 1.2 christos return -1; 333 1.2 christos } 334 1.2 christos 335 1.3 christos /* everything is ready, can register already */ 336 1.2 christos if ( monitor_subsys_is_opened() ) { 337 1.2 christos return monitor_back_register_subsys( ms ); 338 1.2 christos } 339 1.2 christos 340 1.2 christos mi = ( monitor_info_t * )be_monitor->be_private; 341 1.2 christos 342 1.2 christos 343 1.2 christos el.el_type = LIMBO_SUBSYS; 344 1.2 christos 345 1.2 christos el.el_mss = ms; 346 1.2 christos 347 1.2 christos for ( elpp = &mi->mi_entry_limbo; 348 1.2 christos *elpp; 349 1.2 christos elpp = &(*elpp)->el_next ) 350 1.2 christos /* go to last */; 351 1.2 christos 352 1.2 christos *elpp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) ); 353 1.2 christos 354 1.2 christos el.el_next = NULL; 355 1.2 christos **elpp = el; 356 1.2 christos 357 1.2 christos return 0; 358 1.2 christos } 359 1.2 christos 360 1.2 christos int 361 1.1 lukem monitor_back_register_backend( 362 1.1 lukem BackendInfo *bi ) 363 1.1 lukem { 364 1.1 lukem return -1; 365 1.1 lukem } 366 1.1 lukem 367 1.1 lukem int 368 1.1 lukem monitor_back_register_overlay_info( 369 1.1 lukem slap_overinst *on ) 370 1.1 lukem { 371 1.1 lukem return -1; 372 1.1 lukem } 373 1.1 lukem 374 1.1 lukem int 375 1.1 lukem monitor_back_register_backend_limbo( 376 1.1 lukem BackendInfo *bi ) 377 1.1 lukem { 378 1.1 lukem return -1; 379 1.1 lukem } 380 1.1 lukem 381 1.1 lukem int 382 1.1 lukem monitor_back_register_database_limbo( 383 1.1 lukem BackendDB *be, 384 1.2 christos struct berval *ndn_out ) 385 1.1 lukem { 386 1.1 lukem entry_limbo_t **elpp, el = { 0 }; 387 1.1 lukem monitor_info_t *mi; 388 1.1 lukem 389 1.1 lukem if ( be_monitor == NULL ) { 390 1.1 lukem Debug( LDAP_DEBUG_ANY, 391 1.1 lukem "monitor_back_register_database_limbo: " 392 1.3 christos "monitor database not configured.\n" ); 393 1.1 lukem return -1; 394 1.1 lukem } 395 1.1 lukem 396 1.1 lukem mi = ( monitor_info_t * )be_monitor->be_private; 397 1.1 lukem 398 1.1 lukem 399 1.1 lukem el.el_type = LIMBO_DATABASE; 400 1.1 lukem 401 1.1 lukem el.el_be = be->bd_self; 402 1.2 christos el.el_ndn = ndn_out; 403 1.1 lukem 404 1.1 lukem for ( elpp = &mi->mi_entry_limbo; 405 1.1 lukem *elpp; 406 1.1 lukem elpp = &(*elpp)->el_next ) 407 1.1 lukem /* go to last */; 408 1.1 lukem 409 1.1 lukem *elpp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) ); 410 1.1 lukem 411 1.1 lukem el.el_next = NULL; 412 1.1 lukem **elpp = el; 413 1.1 lukem 414 1.1 lukem return 0; 415 1.1 lukem } 416 1.1 lukem 417 1.1 lukem int 418 1.1 lukem monitor_back_register_overlay_info_limbo( 419 1.1 lukem slap_overinst *on ) 420 1.1 lukem { 421 1.1 lukem return -1; 422 1.1 lukem } 423 1.1 lukem 424 1.1 lukem int 425 1.1 lukem monitor_back_register_overlay_limbo( 426 1.2 christos BackendDB *be, 427 1.2 christos struct slap_overinst *on, 428 1.2 christos struct berval *ndn_out ) 429 1.1 lukem { 430 1.2 christos entry_limbo_t **elpp, el = { 0 }; 431 1.2 christos monitor_info_t *mi; 432 1.2 christos 433 1.2 christos if ( be_monitor == NULL ) { 434 1.2 christos Debug( LDAP_DEBUG_ANY, 435 1.2 christos "monitor_back_register_overlay_limbo: " 436 1.3 christos "monitor database not configured.\n" ); 437 1.2 christos return -1; 438 1.2 christos } 439 1.2 christos 440 1.2 christos mi = ( monitor_info_t * )be_monitor->be_private; 441 1.2 christos 442 1.2 christos 443 1.2 christos el.el_type = LIMBO_OVERLAY; 444 1.2 christos 445 1.2 christos el.el_be = be->bd_self; 446 1.2 christos el.el_on = on; 447 1.2 christos el.el_ndn = ndn_out; 448 1.2 christos 449 1.2 christos for ( elpp = &mi->mi_entry_limbo; 450 1.2 christos *elpp; 451 1.2 christos elpp = &(*elpp)->el_next ) 452 1.2 christos /* go to last */; 453 1.2 christos 454 1.2 christos *elpp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) ); 455 1.2 christos 456 1.2 christos el.el_next = NULL; 457 1.2 christos **elpp = el; 458 1.2 christos 459 1.2 christos return 0; 460 1.1 lukem } 461 1.1 lukem 462 1.1 lukem int 463 1.1 lukem monitor_back_register_entry( 464 1.1 lukem Entry *e, 465 1.1 lukem monitor_callback_t *cb, 466 1.1 lukem monitor_subsys_t *mss, 467 1.1 lukem unsigned long flags ) 468 1.1 lukem { 469 1.1 lukem monitor_info_t *mi; 470 1.3 christos int rc = 0; 471 1.1 lukem 472 1.1 lukem if ( be_monitor == NULL ) { 473 1.1 lukem Debug( LDAP_DEBUG_ANY, 474 1.1 lukem "monitor_back_register_entry(\"%s\"): " 475 1.1 lukem "monitor database not configured.\n", 476 1.3 christos e->e_name.bv_val ); 477 1.1 lukem return -1; 478 1.1 lukem } 479 1.1 lukem 480 1.1 lukem mi = ( monitor_info_t * )be_monitor->be_private; 481 1.1 lukem 482 1.1 lukem assert( mi != NULL ); 483 1.1 lukem assert( e != NULL ); 484 1.1 lukem assert( e->e_private == NULL ); 485 1.1 lukem 486 1.1 lukem if ( monitor_subsys_is_opened() ) { 487 1.4 christos Entry *e_parent = NULL, *e_new = NULL; 488 1.1 lukem struct berval pdn = BER_BVNULL; 489 1.1 lukem monitor_entry_t *mp = NULL, 490 1.1 lukem *mp_parent = NULL; 491 1.1 lukem 492 1.1 lukem if ( monitor_cache_get( mi, &e->e_nname, &e_parent ) == 0 ) { 493 1.1 lukem /* entry exists */ 494 1.1 lukem Debug( LDAP_DEBUG_ANY, 495 1.1 lukem "monitor_back_register_entry(\"%s\"): " 496 1.1 lukem "entry exists\n", 497 1.3 christos e->e_name.bv_val ); 498 1.1 lukem monitor_cache_release( mi, e_parent ); 499 1.1 lukem return -1; 500 1.1 lukem } 501 1.1 lukem 502 1.1 lukem dnParent( &e->e_nname, &pdn ); 503 1.1 lukem if ( monitor_cache_get( mi, &pdn, &e_parent ) != 0 ) { 504 1.1 lukem /* parent does not exist */ 505 1.1 lukem Debug( LDAP_DEBUG_ANY, 506 1.1 lukem "monitor_back_register_entry(\"%s\"): " 507 1.1 lukem "parent \"%s\" not found\n", 508 1.3 christos e->e_name.bv_val, pdn.bv_val ); 509 1.1 lukem return -1; 510 1.1 lukem } 511 1.1 lukem 512 1.1 lukem assert( e_parent->e_private != NULL ); 513 1.1 lukem mp_parent = ( monitor_entry_t * )e_parent->e_private; 514 1.1 lukem 515 1.1 lukem if ( mp_parent->mp_flags & MONITOR_F_VOLATILE ) { 516 1.1 lukem /* entry is volatile; cannot append children */ 517 1.1 lukem Debug( LDAP_DEBUG_ANY, 518 1.1 lukem "monitor_back_register_entry(\"%s\"): " 519 1.1 lukem "parent \"%s\" is volatile\n", 520 1.3 christos e->e_name.bv_val, e_parent->e_name.bv_val ); 521 1.1 lukem rc = -1; 522 1.1 lukem goto done; 523 1.1 lukem } 524 1.1 lukem 525 1.1 lukem mp = monitor_entrypriv_create(); 526 1.1 lukem if ( mp == NULL ) { 527 1.1 lukem Debug( LDAP_DEBUG_ANY, 528 1.1 lukem "monitor_back_register_entry(\"%s\"): " 529 1.1 lukem "monitor_entrypriv_create() failed\n", 530 1.3 christos e->e_name.bv_val ); 531 1.1 lukem rc = -1; 532 1.1 lukem goto done; 533 1.1 lukem } 534 1.1 lukem 535 1.1 lukem e_new = entry_dup( e ); 536 1.1 lukem if ( e_new == NULL ) { 537 1.1 lukem Debug( LDAP_DEBUG_ANY, 538 1.1 lukem "monitor_back_register_entry(\"%s\"): " 539 1.1 lukem "entry_dup() failed\n", 540 1.3 christos e->e_name.bv_val ); 541 1.1 lukem rc = -1; 542 1.1 lukem goto done; 543 1.1 lukem } 544 1.1 lukem 545 1.1 lukem e_new->e_private = ( void * )mp; 546 1.1 lukem if ( mss != NULL ) { 547 1.1 lukem mp->mp_info = mss; 548 1.1 lukem mp->mp_flags = flags; 549 1.1 lukem 550 1.1 lukem } else { 551 1.1 lukem mp->mp_info = mp_parent->mp_info; 552 1.1 lukem mp->mp_flags = mp_parent->mp_flags | MONITOR_F_SUB; 553 1.1 lukem } 554 1.1 lukem mp->mp_cb = cb; 555 1.1 lukem 556 1.4 christos if ( monitor_cache_add( mi, e_new, e_parent ) ) { 557 1.1 lukem Debug( LDAP_DEBUG_ANY, 558 1.1 lukem "monitor_back_register_entry(\"%s\"): " 559 1.1 lukem "unable to add entry\n", 560 1.3 christos e->e_name.bv_val ); 561 1.1 lukem rc = -1; 562 1.1 lukem goto done; 563 1.1 lukem } 564 1.1 lukem 565 1.1 lukem done:; 566 1.1 lukem if ( rc ) { 567 1.1 lukem if ( mp ) { 568 1.1 lukem ch_free( mp ); 569 1.1 lukem } 570 1.1 lukem if ( e_new ) { 571 1.1 lukem e_new->e_private = NULL; 572 1.1 lukem entry_free( e_new ); 573 1.1 lukem } 574 1.1 lukem } 575 1.1 lukem 576 1.1 lukem if ( e_parent ) { 577 1.1 lukem monitor_cache_release( mi, e_parent ); 578 1.1 lukem } 579 1.1 lukem 580 1.1 lukem } else { 581 1.1 lukem entry_limbo_t **elpp, el = { 0 }; 582 1.1 lukem 583 1.1 lukem el.el_type = LIMBO_ENTRY; 584 1.1 lukem 585 1.1 lukem el.el_e = entry_dup( e ); 586 1.1 lukem if ( el.el_e == NULL ) { 587 1.1 lukem Debug( LDAP_DEBUG_ANY, 588 1.1 lukem "monitor_back_register_entry(\"%s\"): " 589 1.1 lukem "entry_dup() failed\n", 590 1.3 christos e->e_name.bv_val ); 591 1.1 lukem return -1; 592 1.1 lukem } 593 1.1 lukem 594 1.1 lukem el.el_cb = cb; 595 1.1 lukem el.el_mss = mss; 596 1.1 lukem el.el_flags = flags; 597 1.1 lukem 598 1.1 lukem for ( elpp = &mi->mi_entry_limbo; 599 1.1 lukem *elpp; 600 1.1 lukem elpp = &(*elpp)->el_next ) 601 1.1 lukem /* go to last */; 602 1.1 lukem 603 1.1 lukem *elpp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) ); 604 1.1 lukem if ( *elpp == NULL ) { 605 1.1 lukem el.el_e->e_private = NULL; 606 1.1 lukem entry_free( el.el_e ); 607 1.1 lukem return -1; 608 1.1 lukem } 609 1.1 lukem 610 1.1 lukem el.el_next = NULL; 611 1.1 lukem **elpp = el; 612 1.1 lukem } 613 1.1 lukem 614 1.3 christos return rc; 615 1.1 lukem } 616 1.1 lukem 617 1.1 lukem int 618 1.1 lukem monitor_back_register_entry_parent( 619 1.1 lukem Entry *e, 620 1.1 lukem monitor_callback_t *cb, 621 1.1 lukem monitor_subsys_t *mss, 622 1.1 lukem unsigned long flags, 623 1.1 lukem struct berval *nbase, 624 1.1 lukem int scope, 625 1.1 lukem struct berval *filter ) 626 1.1 lukem { 627 1.1 lukem monitor_info_t *mi; 628 1.1 lukem struct berval ndn = BER_BVNULL; 629 1.1 lukem 630 1.1 lukem if ( be_monitor == NULL ) { 631 1.1 lukem Debug( LDAP_DEBUG_ANY, 632 1.1 lukem "monitor_back_register_entry_parent(base=\"%s\" scope=%s filter=\"%s\"): " 633 1.1 lukem "monitor database not configured.\n", 634 1.1 lukem BER_BVISNULL( nbase ) ? "" : nbase->bv_val, 635 1.1 lukem ldap_pvt_scope2str( scope ), 636 1.1 lukem BER_BVISNULL( filter ) ? "" : filter->bv_val ); 637 1.1 lukem return -1; 638 1.1 lukem } 639 1.1 lukem 640 1.1 lukem mi = ( monitor_info_t * )be_monitor->be_private; 641 1.1 lukem 642 1.1 lukem assert( mi != NULL ); 643 1.1 lukem assert( e != NULL ); 644 1.1 lukem assert( e->e_private == NULL ); 645 1.1 lukem 646 1.1 lukem if ( BER_BVISNULL( filter ) ) { 647 1.1 lukem /* need a filter */ 648 1.1 lukem Debug( LDAP_DEBUG_ANY, 649 1.1 lukem "monitor_back_register_entry_parent(\"\"): " 650 1.3 christos "need a valid filter\n" ); 651 1.1 lukem return -1; 652 1.1 lukem } 653 1.1 lukem 654 1.1 lukem if ( monitor_subsys_is_opened() ) { 655 1.4 christos Entry *e_parent = NULL, *e_new = NULL; 656 1.1 lukem struct berval e_name = BER_BVNULL, 657 1.1 lukem e_nname = BER_BVNULL; 658 1.1 lukem monitor_entry_t *mp = NULL, 659 1.1 lukem *mp_parent = NULL; 660 1.1 lukem int rc = 0; 661 1.1 lukem 662 1.1 lukem if ( monitor_search2ndn( nbase, scope, filter, &ndn ) ) { 663 1.1 lukem /* entry does not exist */ 664 1.1 lukem Debug( LDAP_DEBUG_ANY, 665 1.1 lukem "monitor_back_register_entry_parent(\"\"): " 666 1.1 lukem "base=\"%s\" scope=%s filter=\"%s\": " 667 1.1 lukem "unable to find entry\n", 668 1.1 lukem nbase->bv_val ? nbase->bv_val : "\"\"", 669 1.1 lukem ldap_pvt_scope2str( scope ), 670 1.1 lukem filter->bv_val ); 671 1.1 lukem return -1; 672 1.1 lukem } 673 1.1 lukem 674 1.1 lukem if ( monitor_cache_get( mi, &ndn, &e_parent ) != 0 ) { 675 1.1 lukem /* entry does not exist */ 676 1.1 lukem Debug( LDAP_DEBUG_ANY, 677 1.1 lukem "monitor_back_register_entry_parent(\"%s\"): " 678 1.1 lukem "parent entry does not exist\n", 679 1.3 christos ndn.bv_val ); 680 1.1 lukem rc = -1; 681 1.1 lukem goto done; 682 1.1 lukem } 683 1.1 lukem 684 1.1 lukem assert( e_parent->e_private != NULL ); 685 1.1 lukem mp_parent = ( monitor_entry_t * )e_parent->e_private; 686 1.1 lukem 687 1.1 lukem if ( mp_parent->mp_flags & MONITOR_F_VOLATILE ) { 688 1.1 lukem /* entry is volatile; cannot append callback */ 689 1.1 lukem Debug( LDAP_DEBUG_ANY, 690 1.1 lukem "monitor_back_register_entry_parent(\"%s\"): " 691 1.1 lukem "entry is volatile\n", 692 1.3 christos e_parent->e_name.bv_val ); 693 1.1 lukem rc = -1; 694 1.1 lukem goto done; 695 1.1 lukem } 696 1.1 lukem 697 1.1 lukem build_new_dn( &e_name, &e_parent->e_name, &e->e_name, NULL ); 698 1.1 lukem build_new_dn( &e_nname, &e_parent->e_nname, &e->e_nname, NULL ); 699 1.1 lukem 700 1.1 lukem if ( monitor_cache_get( mi, &e_nname, &e_new ) == 0 ) { 701 1.1 lukem /* entry already exists */ 702 1.1 lukem Debug( LDAP_DEBUG_ANY, 703 1.1 lukem "monitor_back_register_entry_parent(\"%s\"): " 704 1.1 lukem "entry already exists\n", 705 1.3 christos e_name.bv_val ); 706 1.1 lukem monitor_cache_release( mi, e_new ); 707 1.1 lukem e_new = NULL; 708 1.1 lukem rc = -1; 709 1.1 lukem goto done; 710 1.1 lukem } 711 1.1 lukem 712 1.1 lukem mp = monitor_entrypriv_create(); 713 1.1 lukem if ( mp == NULL ) { 714 1.1 lukem Debug( LDAP_DEBUG_ANY, 715 1.1 lukem "monitor_back_register_entry_parent(\"%s\"): " 716 1.1 lukem "monitor_entrypriv_create() failed\n", 717 1.3 christos e->e_name.bv_val ); 718 1.1 lukem rc = -1; 719 1.1 lukem goto done; 720 1.1 lukem } 721 1.1 lukem 722 1.1 lukem e_new = entry_dup( e ); 723 1.1 lukem if ( e_new == NULL ) { 724 1.1 lukem Debug( LDAP_DEBUG_ANY, 725 1.1 lukem "monitor_back_register_entry(\"%s\"): " 726 1.1 lukem "entry_dup() failed\n", 727 1.3 christos e->e_name.bv_val ); 728 1.1 lukem rc = -1; 729 1.1 lukem goto done; 730 1.1 lukem } 731 1.1 lukem ch_free( e_new->e_name.bv_val ); 732 1.1 lukem ch_free( e_new->e_nname.bv_val ); 733 1.1 lukem e_new->e_name = e_name; 734 1.1 lukem e_new->e_nname = e_nname; 735 1.1 lukem 736 1.1 lukem e_new->e_private = ( void * )mp; 737 1.1 lukem if ( mss != NULL ) { 738 1.1 lukem mp->mp_info = mss; 739 1.1 lukem mp->mp_flags = flags; 740 1.1 lukem 741 1.1 lukem } else { 742 1.1 lukem mp->mp_info = mp_parent->mp_info; 743 1.1 lukem mp->mp_flags = mp_parent->mp_flags | MONITOR_F_SUB; 744 1.1 lukem } 745 1.1 lukem mp->mp_cb = cb; 746 1.1 lukem 747 1.4 christos if ( monitor_cache_add( mi, e_new, e_parent ) ) { 748 1.1 lukem Debug( LDAP_DEBUG_ANY, 749 1.1 lukem "monitor_back_register_entry(\"%s\"): " 750 1.1 lukem "unable to add entry\n", 751 1.3 christos e->e_name.bv_val ); 752 1.1 lukem rc = -1; 753 1.1 lukem goto done; 754 1.1 lukem } 755 1.1 lukem 756 1.1 lukem done:; 757 1.1 lukem if ( !BER_BVISNULL( &ndn ) ) { 758 1.1 lukem ch_free( ndn.bv_val ); 759 1.1 lukem } 760 1.1 lukem 761 1.1 lukem if ( rc ) { 762 1.1 lukem if ( mp ) { 763 1.1 lukem ch_free( mp ); 764 1.1 lukem } 765 1.1 lukem if ( e_new ) { 766 1.1 lukem e_new->e_private = NULL; 767 1.1 lukem entry_free( e_new ); 768 1.1 lukem } 769 1.1 lukem } 770 1.1 lukem 771 1.1 lukem if ( e_parent ) { 772 1.1 lukem monitor_cache_release( mi, e_parent ); 773 1.1 lukem } 774 1.1 lukem 775 1.1 lukem } else { 776 1.1 lukem entry_limbo_t **elpp = NULL, el = { 0 }; 777 1.1 lukem 778 1.1 lukem el.el_type = LIMBO_ENTRY_PARENT; 779 1.1 lukem 780 1.1 lukem el.el_e = entry_dup( e ); 781 1.1 lukem if ( el.el_e == NULL ) { 782 1.1 lukem Debug( LDAP_DEBUG_ANY, 783 1.1 lukem "monitor_back_register_entry(\"%s\"): " 784 1.1 lukem "entry_dup() failed\n", 785 1.3 christos e->e_name.bv_val ); 786 1.1 lukem goto done_limbo; 787 1.1 lukem } 788 1.1 lukem 789 1.1 lukem if ( !BER_BVISNULL( nbase ) ) { 790 1.1 lukem ber_dupbv( &el.el_nbase, nbase ); 791 1.1 lukem } 792 1.1 lukem 793 1.1 lukem el.el_scope = scope; 794 1.1 lukem if ( !BER_BVISNULL( filter ) ) { 795 1.1 lukem ber_dupbv( &el.el_filter, filter ); 796 1.1 lukem } 797 1.1 lukem 798 1.1 lukem el.el_cb = cb; 799 1.1 lukem el.el_mss = mss; 800 1.1 lukem el.el_flags = flags; 801 1.1 lukem 802 1.1 lukem for ( elpp = &mi->mi_entry_limbo; 803 1.1 lukem *elpp; 804 1.1 lukem elpp = &(*elpp)->el_next ) 805 1.1 lukem /* go to last */; 806 1.1 lukem 807 1.1 lukem *elpp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) ); 808 1.1 lukem if ( *elpp == NULL ) { 809 1.1 lukem goto done_limbo; 810 1.1 lukem } 811 1.1 lukem 812 1.1 lukem done_limbo:; 813 1.1 lukem if ( *elpp != NULL ) { 814 1.1 lukem el.el_next = NULL; 815 1.1 lukem **elpp = el; 816 1.1 lukem 817 1.1 lukem } else { 818 1.1 lukem if ( !BER_BVISNULL( &el.el_filter ) ) { 819 1.1 lukem ch_free( el.el_filter.bv_val ); 820 1.1 lukem } 821 1.1 lukem if ( !BER_BVISNULL( &el.el_nbase ) ) { 822 1.1 lukem ch_free( el.el_nbase.bv_val ); 823 1.1 lukem } 824 1.1 lukem entry_free( el.el_e ); 825 1.1 lukem return -1; 826 1.1 lukem } 827 1.1 lukem } 828 1.1 lukem 829 1.1 lukem return 0; 830 1.1 lukem } 831 1.1 lukem 832 1.1 lukem static int 833 1.1 lukem monitor_search2ndn_cb( Operation *op, SlapReply *rs ) 834 1.1 lukem { 835 1.1 lukem if ( rs->sr_type == REP_SEARCH ) { 836 1.1 lukem struct berval *ndn = op->o_callback->sc_private; 837 1.1 lukem 838 1.1 lukem if ( !BER_BVISNULL( ndn ) ) { 839 1.1 lukem rs->sr_err = LDAP_SIZELIMIT_EXCEEDED; 840 1.1 lukem ch_free( ndn->bv_val ); 841 1.1 lukem BER_BVZERO( ndn ); 842 1.1 lukem return rs->sr_err; 843 1.1 lukem } 844 1.1 lukem 845 1.1 lukem ber_dupbv( ndn, &rs->sr_entry->e_nname ); 846 1.1 lukem } 847 1.1 lukem 848 1.1 lukem return 0; 849 1.1 lukem } 850 1.1 lukem 851 1.1 lukem int 852 1.1 lukem monitor_search2ndn( 853 1.1 lukem struct berval *nbase, 854 1.1 lukem int scope, 855 1.1 lukem struct berval *filter, 856 1.1 lukem struct berval *ndn ) 857 1.1 lukem { 858 1.1 lukem Connection conn = { 0 }; 859 1.1 lukem OperationBuffer opbuf; 860 1.1 lukem Operation *op; 861 1.1 lukem void *thrctx; 862 1.2 christos SlapReply rs = { REP_RESULT }; 863 1.1 lukem slap_callback cb = { NULL, monitor_search2ndn_cb, NULL, NULL }; 864 1.1 lukem int rc; 865 1.1 lukem 866 1.1 lukem BER_BVZERO( ndn ); 867 1.1 lukem 868 1.1 lukem if ( be_monitor == NULL ) { 869 1.1 lukem return -1; 870 1.1 lukem } 871 1.1 lukem 872 1.1 lukem thrctx = ldap_pvt_thread_pool_context(); 873 1.2 christos connection_fake_init2( &conn, &opbuf, thrctx, 0 ); 874 1.1 lukem op = &opbuf.ob_op; 875 1.1 lukem 876 1.1 lukem op->o_tag = LDAP_REQ_SEARCH; 877 1.1 lukem 878 1.1 lukem /* use global malloc for now */ 879 1.1 lukem if ( op->o_tmpmemctx ) { 880 1.1 lukem op->o_tmpmemctx = NULL; 881 1.1 lukem } 882 1.1 lukem op->o_tmpmfuncs = &ch_mfuncs; 883 1.1 lukem 884 1.1 lukem op->o_bd = be_monitor; 885 1.1 lukem if ( nbase == NULL || BER_BVISNULL( nbase ) ) { 886 1.1 lukem ber_dupbv_x( &op->o_req_dn, &op->o_bd->be_suffix[ 0 ], 887 1.1 lukem op->o_tmpmemctx ); 888 1.1 lukem ber_dupbv_x( &op->o_req_ndn, &op->o_bd->be_nsuffix[ 0 ], 889 1.1 lukem op->o_tmpmemctx ); 890 1.1 lukem 891 1.1 lukem } else { 892 1.1 lukem if ( dnPrettyNormal( NULL, nbase, &op->o_req_dn, &op->o_req_ndn, 893 1.1 lukem op->o_tmpmemctx ) ) { 894 1.1 lukem return -1; 895 1.1 lukem } 896 1.1 lukem } 897 1.1 lukem 898 1.1 lukem op->o_callback = &cb; 899 1.1 lukem cb.sc_private = (void *)ndn; 900 1.1 lukem 901 1.1 lukem op->ors_scope = scope; 902 1.1 lukem op->ors_filter = str2filter_x( op, filter->bv_val ); 903 1.1 lukem if ( op->ors_filter == NULL ) { 904 1.1 lukem rc = LDAP_OTHER; 905 1.1 lukem goto cleanup; 906 1.1 lukem } 907 1.1 lukem ber_dupbv_x( &op->ors_filterstr, filter, op->o_tmpmemctx ); 908 1.1 lukem op->ors_attrs = slap_anlist_no_attrs; 909 1.1 lukem op->ors_attrsonly = 0; 910 1.1 lukem op->ors_tlimit = SLAP_NO_LIMIT; 911 1.1 lukem op->ors_slimit = 1; 912 1.1 lukem op->ors_limit = NULL; 913 1.1 lukem op->ors_deref = LDAP_DEREF_NEVER; 914 1.1 lukem 915 1.1 lukem op->o_nocaching = 1; 916 1.1 lukem op->o_managedsait = SLAP_CONTROL_NONCRITICAL; 917 1.1 lukem 918 1.1 lukem op->o_dn = be_monitor->be_rootdn; 919 1.1 lukem op->o_ndn = be_monitor->be_rootndn; 920 1.1 lukem 921 1.1 lukem rc = op->o_bd->be_search( op, &rs ); 922 1.1 lukem 923 1.1 lukem cleanup:; 924 1.1 lukem if ( op->ors_filter != NULL ) { 925 1.2 christos filter_free_x( op, op->ors_filter, 1 ); 926 1.1 lukem } 927 1.1 lukem if ( !BER_BVISNULL( &op->ors_filterstr ) ) { 928 1.1 lukem op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx ); 929 1.1 lukem } 930 1.1 lukem if ( !BER_BVISNULL( &op->o_req_dn ) ) { 931 1.1 lukem op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx ); 932 1.1 lukem } 933 1.1 lukem if ( !BER_BVISNULL( &op->o_req_ndn ) ) { 934 1.1 lukem op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx ); 935 1.1 lukem } 936 1.1 lukem 937 1.1 lukem if ( rc != 0 ) { 938 1.1 lukem return rc; 939 1.1 lukem } 940 1.1 lukem 941 1.1 lukem switch ( rs.sr_err ) { 942 1.1 lukem case LDAP_SUCCESS: 943 1.1 lukem if ( BER_BVISNULL( ndn ) ) { 944 1.1 lukem rc = -1; 945 1.1 lukem } 946 1.1 lukem break; 947 1.1 lukem 948 1.1 lukem case LDAP_SIZELIMIT_EXCEEDED: 949 1.1 lukem default: 950 1.1 lukem if ( !BER_BVISNULL( ndn ) ) { 951 1.1 lukem ber_memfree( ndn->bv_val ); 952 1.1 lukem BER_BVZERO( ndn ); 953 1.1 lukem } 954 1.1 lukem rc = -1; 955 1.1 lukem break; 956 1.1 lukem } 957 1.1 lukem 958 1.1 lukem return rc; 959 1.1 lukem } 960 1.1 lukem 961 1.1 lukem int 962 1.1 lukem monitor_back_register_entry_attrs( 963 1.1 lukem struct berval *ndn_in, 964 1.1 lukem Attribute *a, 965 1.1 lukem monitor_callback_t *cb, 966 1.1 lukem struct berval *nbase, 967 1.1 lukem int scope, 968 1.1 lukem struct berval *filter ) 969 1.1 lukem { 970 1.1 lukem monitor_info_t *mi; 971 1.1 lukem struct berval ndn = BER_BVNULL; 972 1.1 lukem char *fname = ( a == NULL ? "callback" : "attrs" ); 973 1.2 christos struct berval empty_bv = BER_BVC(""); 974 1.2 christos 975 1.2 christos if ( nbase == NULL ) nbase = &empty_bv; 976 1.2 christos if ( filter == NULL ) filter = &empty_bv; 977 1.1 lukem 978 1.1 lukem if ( be_monitor == NULL ) { 979 1.3 christos Debug(LDAP_DEBUG_ANY, 980 1.3 christos "monitor_back_register_entry_%s(base=\"%s\" scope=%s filter=\"%s\"): " "monitor database not configured.\n\n", 981 1.3 christos fname, BER_BVISNULL(nbase) ? "" : nbase->bv_val, 982 1.3 christos ldap_pvt_scope2str(scope), 983 1.3 christos BER_BVISNULL(filter) ? "" : filter->bv_val ); 984 1.1 lukem 985 1.1 lukem return -1; 986 1.1 lukem } 987 1.1 lukem 988 1.1 lukem mi = ( monitor_info_t * )be_monitor->be_private; 989 1.1 lukem 990 1.1 lukem assert( mi != NULL ); 991 1.1 lukem 992 1.1 lukem if ( ndn_in != NULL ) { 993 1.1 lukem ndn = *ndn_in; 994 1.1 lukem } 995 1.1 lukem 996 1.1 lukem if ( a == NULL && cb == NULL ) { 997 1.1 lukem /* nothing to do */ 998 1.1 lukem return -1; 999 1.1 lukem } 1000 1.1 lukem 1001 1.1 lukem if ( ( ndn_in == NULL || BER_BVISNULL( &ndn ) ) 1002 1.1 lukem && BER_BVISNULL( filter ) ) 1003 1.1 lukem { 1004 1.1 lukem /* need a filter */ 1005 1.1 lukem Debug( LDAP_DEBUG_ANY, 1006 1.1 lukem "monitor_back_register_entry_%s(\"\"): " 1007 1.1 lukem "need a valid filter\n", 1008 1.3 christos fname ); 1009 1.1 lukem return -1; 1010 1.1 lukem } 1011 1.1 lukem 1012 1.1 lukem if ( monitor_subsys_is_opened() ) { 1013 1.1 lukem Entry *e = NULL; 1014 1.1 lukem Attribute **atp = NULL; 1015 1.1 lukem monitor_entry_t *mp = NULL; 1016 1.1 lukem monitor_callback_t **mcp = NULL; 1017 1.1 lukem int rc = 0; 1018 1.1 lukem int freeit = 0; 1019 1.1 lukem 1020 1.1 lukem if ( BER_BVISNULL( &ndn ) ) { 1021 1.1 lukem if ( monitor_search2ndn( nbase, scope, filter, &ndn ) ) { 1022 1.3 christos Debug(LDAP_DEBUG_ANY, 1023 1.3 christos "monitor_back_register_entry_%s(\"\"): " "base=\"%s\" scope=%s filter=\"%s\": " "unable to find entry\n\n", 1024 1.3 christos fname, 1025 1.3 christos nbase->bv_val ? nbase->bv_val : "\"\"", 1026 1.3 christos ldap_pvt_scope2str(scope), 1027 1.3 christos filter->bv_val ); 1028 1.1 lukem return -1; 1029 1.1 lukem } 1030 1.1 lukem 1031 1.1 lukem freeit = 1; 1032 1.1 lukem } 1033 1.1 lukem 1034 1.1 lukem if ( monitor_cache_get( mi, &ndn, &e ) != 0 ) { 1035 1.1 lukem /* entry does not exist */ 1036 1.1 lukem Debug( LDAP_DEBUG_ANY, 1037 1.1 lukem "monitor_back_register_entry_%s(\"%s\"): " 1038 1.1 lukem "entry does not exist\n", 1039 1.3 christos fname, ndn.bv_val ); 1040 1.1 lukem rc = -1; 1041 1.1 lukem goto done; 1042 1.1 lukem } 1043 1.1 lukem 1044 1.1 lukem assert( e->e_private != NULL ); 1045 1.1 lukem mp = ( monitor_entry_t * )e->e_private; 1046 1.1 lukem 1047 1.1 lukem if ( mp->mp_flags & MONITOR_F_VOLATILE ) { 1048 1.1 lukem /* entry is volatile; cannot append callback */ 1049 1.1 lukem Debug( LDAP_DEBUG_ANY, 1050 1.1 lukem "monitor_back_register_entry_%s(\"%s\"): " 1051 1.1 lukem "entry is volatile\n", 1052 1.3 christos fname, e->e_name.bv_val ); 1053 1.1 lukem rc = -1; 1054 1.1 lukem goto done; 1055 1.1 lukem } 1056 1.1 lukem 1057 1.1 lukem if ( a ) { 1058 1.1 lukem for ( atp = &e->e_attrs; *atp; atp = &(*atp)->a_next ) 1059 1.1 lukem /* just get to last */ ; 1060 1.1 lukem 1061 1.1 lukem for ( ; a != NULL; a = a->a_next ) { 1062 1.1 lukem assert( a->a_desc != NULL ); 1063 1.1 lukem assert( a->a_vals != NULL ); 1064 1.1 lukem 1065 1.1 lukem if ( attr_find( e->e_attrs, a->a_desc ) ) { 1066 1.1 lukem attr_merge( e, a->a_desc, a->a_vals, 1067 1.1 lukem a->a_nvals == a->a_vals ? NULL : a->a_nvals ); 1068 1.1 lukem 1069 1.1 lukem } else { 1070 1.1 lukem *atp = attr_dup( a ); 1071 1.1 lukem if ( *atp == NULL ) { 1072 1.1 lukem Debug( LDAP_DEBUG_ANY, 1073 1.1 lukem "monitor_back_register_entry_%s(\"%s\"): " 1074 1.1 lukem "attr_dup() failed\n", 1075 1.3 christos fname, e->e_name.bv_val ); 1076 1.1 lukem rc = -1; 1077 1.1 lukem goto done; 1078 1.1 lukem } 1079 1.1 lukem atp = &(*atp)->a_next; 1080 1.1 lukem } 1081 1.1 lukem } 1082 1.1 lukem } 1083 1.1 lukem 1084 1.1 lukem if ( cb ) { 1085 1.1 lukem for ( mcp = &mp->mp_cb; *mcp; mcp = &(*mcp)->mc_next ) 1086 1.1 lukem /* go to tail */ ; 1087 1.1 lukem 1088 1.1 lukem /* NOTE: we do not clear cb->mc_next, so this function 1089 1.1 lukem * can be used to append a list of callbacks */ 1090 1.1 lukem (*mcp) = cb; 1091 1.1 lukem } 1092 1.1 lukem 1093 1.1 lukem done:; 1094 1.1 lukem if ( rc ) { 1095 1.1 lukem if ( atp && *atp ) { 1096 1.1 lukem attrs_free( *atp ); 1097 1.1 lukem *atp = NULL; 1098 1.1 lukem } 1099 1.1 lukem } 1100 1.1 lukem 1101 1.1 lukem if ( freeit ) { 1102 1.1 lukem ber_memfree( ndn.bv_val ); 1103 1.1 lukem } 1104 1.1 lukem 1105 1.1 lukem if ( e ) { 1106 1.1 lukem monitor_cache_release( mi, e ); 1107 1.1 lukem } 1108 1.1 lukem 1109 1.1 lukem } else { 1110 1.1 lukem entry_limbo_t **elpp, el = { 0 }; 1111 1.1 lukem 1112 1.1 lukem el.el_type = LIMBO_ATTRS; 1113 1.1 lukem el.el_ndn = ndn_in; 1114 1.1 lukem if ( !BER_BVISNULL( nbase ) ) { 1115 1.1 lukem ber_dupbv( &el.el_nbase, nbase); 1116 1.1 lukem } 1117 1.1 lukem el.el_scope = scope; 1118 1.1 lukem if ( !BER_BVISNULL( filter ) ) { 1119 1.1 lukem ber_dupbv( &el.el_filter, filter ); 1120 1.1 lukem } 1121 1.1 lukem 1122 1.1 lukem el.el_a = attrs_dup( a ); 1123 1.1 lukem el.el_cb = cb; 1124 1.1 lukem 1125 1.1 lukem for ( elpp = &mi->mi_entry_limbo; 1126 1.1 lukem *elpp; 1127 1.1 lukem elpp = &(*elpp)->el_next ) 1128 1.1 lukem /* go to last */; 1129 1.1 lukem 1130 1.1 lukem *elpp = (entry_limbo_t *)ch_malloc( sizeof( entry_limbo_t ) ); 1131 1.1 lukem if ( *elpp == NULL ) { 1132 1.1 lukem if ( !BER_BVISNULL( &el.el_filter ) ) { 1133 1.1 lukem ch_free( el.el_filter.bv_val ); 1134 1.1 lukem } 1135 1.1 lukem if ( el.el_a != NULL ) { 1136 1.1 lukem attrs_free( el.el_a ); 1137 1.1 lukem } 1138 1.1 lukem if ( !BER_BVISNULL( &el.el_nbase ) ) { 1139 1.1 lukem ch_free( &el.el_nbase.bv_val ); 1140 1.1 lukem } 1141 1.1 lukem return -1; 1142 1.1 lukem } 1143 1.2 christos 1144 1.2 christos el.el_next = NULL; 1145 1.2 christos **elpp = el; 1146 1.1 lukem } 1147 1.1 lukem 1148 1.1 lukem return 0; 1149 1.1 lukem } 1150 1.1 lukem 1151 1.1 lukem int 1152 1.1 lukem monitor_back_register_entry_callback( 1153 1.1 lukem struct berval *ndn, 1154 1.1 lukem monitor_callback_t *cb, 1155 1.1 lukem struct berval *nbase, 1156 1.1 lukem int scope, 1157 1.1 lukem struct berval *filter ) 1158 1.1 lukem { 1159 1.1 lukem return monitor_back_register_entry_attrs( ndn, NULL, cb, 1160 1.1 lukem nbase, scope, filter ); 1161 1.1 lukem } 1162 1.1 lukem 1163 1.1 lukem /* 1164 1.1 lukem * TODO: add corresponding calls to remove installed callbacks, entries 1165 1.1 lukem * and so, in case the entity that installed them is removed (e.g. a 1166 1.1 lukem * database, via back-config) 1167 1.1 lukem */ 1168 1.1 lukem int 1169 1.1 lukem monitor_back_unregister_entry( 1170 1.1 lukem struct berval *ndn ) 1171 1.1 lukem { 1172 1.1 lukem monitor_info_t *mi; 1173 1.1 lukem 1174 1.1 lukem if ( be_monitor == NULL ) { 1175 1.1 lukem Debug( LDAP_DEBUG_ANY, 1176 1.1 lukem "monitor_back_unregister_entry(\"%s\"): " 1177 1.1 lukem "monitor database not configured.\n", 1178 1.3 christos ndn->bv_val ); 1179 1.1 lukem 1180 1.1 lukem return -1; 1181 1.1 lukem } 1182 1.1 lukem 1183 1.1 lukem /* entry will be regularly freed, and resources released 1184 1.1 lukem * according to callbacks */ 1185 1.1 lukem if ( slapd_shutdown ) { 1186 1.1 lukem return 0; 1187 1.1 lukem } 1188 1.1 lukem 1189 1.1 lukem mi = ( monitor_info_t * )be_monitor->be_private; 1190 1.1 lukem 1191 1.1 lukem assert( mi != NULL ); 1192 1.1 lukem 1193 1.1 lukem if ( monitor_subsys_is_opened() ) { 1194 1.1 lukem Entry *e = NULL; 1195 1.1 lukem monitor_entry_t *mp = NULL; 1196 1.1 lukem monitor_callback_t *cb = NULL; 1197 1.1 lukem 1198 1.1 lukem if ( monitor_cache_remove( mi, ndn, &e ) != 0 ) { 1199 1.1 lukem /* entry does not exist */ 1200 1.1 lukem Debug( LDAP_DEBUG_ANY, 1201 1.1 lukem "monitor_back_unregister_entry(\"%s\"): " 1202 1.1 lukem "entry removal failed.\n", 1203 1.3 christos ndn->bv_val ); 1204 1.1 lukem return -1; 1205 1.1 lukem } 1206 1.1 lukem 1207 1.1 lukem mp = (monitor_entry_t *)e->e_private; 1208 1.1 lukem assert( mp != NULL ); 1209 1.1 lukem 1210 1.1 lukem for ( cb = mp->mp_cb; cb != NULL; ) { 1211 1.1 lukem monitor_callback_t *next = cb->mc_next; 1212 1.1 lukem 1213 1.1 lukem if ( cb->mc_free ) { 1214 1.1 lukem (void)cb->mc_free( e, &cb->mc_private ); 1215 1.1 lukem } 1216 1.1 lukem ch_free( cb ); 1217 1.1 lukem 1218 1.1 lukem cb = next; 1219 1.1 lukem } 1220 1.1 lukem 1221 1.1 lukem ch_free( mp ); 1222 1.1 lukem e->e_private = NULL; 1223 1.1 lukem entry_free( e ); 1224 1.1 lukem 1225 1.1 lukem } else { 1226 1.1 lukem entry_limbo_t **elpp; 1227 1.1 lukem 1228 1.1 lukem for ( elpp = &mi->mi_entry_limbo; 1229 1.1 lukem *elpp; 1230 1.1 lukem elpp = &(*elpp)->el_next ) 1231 1.1 lukem { 1232 1.1 lukem entry_limbo_t *elp = *elpp; 1233 1.1 lukem 1234 1.1 lukem if ( elp->el_type == LIMBO_ENTRY 1235 1.1 lukem && dn_match( ndn, &elp->el_e->e_nname ) ) 1236 1.1 lukem { 1237 1.1 lukem monitor_callback_t *cb, *next; 1238 1.1 lukem 1239 1.1 lukem for ( cb = elp->el_cb; cb; cb = next ) { 1240 1.1 lukem /* FIXME: call callbacks? */ 1241 1.1 lukem next = cb->mc_next; 1242 1.1 lukem if ( cb->mc_dispose ) { 1243 1.1 lukem cb->mc_dispose( &cb->mc_private ); 1244 1.1 lukem } 1245 1.1 lukem ch_free( cb ); 1246 1.1 lukem } 1247 1.1 lukem assert( elp->el_e != NULL ); 1248 1.1 lukem elp->el_e->e_private = NULL; 1249 1.1 lukem entry_free( elp->el_e ); 1250 1.1 lukem *elpp = elp->el_next; 1251 1.1 lukem ch_free( elp ); 1252 1.1 lukem elpp = NULL; 1253 1.1 lukem break; 1254 1.1 lukem } 1255 1.1 lukem } 1256 1.1 lukem 1257 1.1 lukem if ( elpp != NULL ) { 1258 1.1 lukem /* not found! where did it go? */ 1259 1.1 lukem return 1; 1260 1.1 lukem } 1261 1.1 lukem } 1262 1.1 lukem 1263 1.1 lukem return 0; 1264 1.1 lukem } 1265 1.1 lukem 1266 1.1 lukem int 1267 1.1 lukem monitor_back_unregister_entry_parent( 1268 1.1 lukem struct berval *nrdn, 1269 1.1 lukem monitor_callback_t *target_cb, 1270 1.1 lukem struct berval *nbase, 1271 1.1 lukem int scope, 1272 1.1 lukem struct berval *filter ) 1273 1.1 lukem { 1274 1.1 lukem monitor_info_t *mi; 1275 1.1 lukem struct berval ndn = BER_BVNULL; 1276 1.1 lukem 1277 1.1 lukem if ( be_monitor == NULL ) { 1278 1.1 lukem Debug( LDAP_DEBUG_ANY, 1279 1.1 lukem "monitor_back_unregister_entry_parent(base=\"%s\" scope=%s filter=\"%s\"): " 1280 1.1 lukem "monitor database not configured.\n", 1281 1.1 lukem BER_BVISNULL( nbase ) ? "" : nbase->bv_val, 1282 1.1 lukem ldap_pvt_scope2str( scope ), 1283 1.1 lukem BER_BVISNULL( filter ) ? "" : filter->bv_val ); 1284 1.1 lukem 1285 1.1 lukem return -1; 1286 1.1 lukem } 1287 1.1 lukem 1288 1.1 lukem /* entry will be regularly freed, and resources released 1289 1.1 lukem * according to callbacks */ 1290 1.1 lukem if ( slapd_shutdown ) { 1291 1.1 lukem return 0; 1292 1.1 lukem } 1293 1.1 lukem 1294 1.1 lukem mi = ( monitor_info_t * )be_monitor->be_private; 1295 1.1 lukem 1296 1.1 lukem assert( mi != NULL ); 1297 1.1 lukem 1298 1.1 lukem if ( ( nrdn == NULL || BER_BVISNULL( nrdn ) ) 1299 1.1 lukem && BER_BVISNULL( filter ) ) 1300 1.1 lukem { 1301 1.1 lukem /* need a filter */ 1302 1.1 lukem Debug( LDAP_DEBUG_ANY, 1303 1.1 lukem "monitor_back_unregister_entry_parent(\"\"): " 1304 1.3 christos "need a valid filter\n" ); 1305 1.1 lukem return -1; 1306 1.1 lukem } 1307 1.1 lukem 1308 1.1 lukem if ( monitor_subsys_is_opened() ) { 1309 1.1 lukem Entry *e = NULL; 1310 1.1 lukem monitor_entry_t *mp = NULL; 1311 1.1 lukem 1312 1.1 lukem if ( monitor_search2ndn( nbase, scope, filter, &ndn ) ) { 1313 1.1 lukem /* entry does not exist */ 1314 1.1 lukem Debug( LDAP_DEBUG_ANY, 1315 1.1 lukem "monitor_back_unregister_entry_parent(\"\"): " 1316 1.1 lukem "base=\"%s\" scope=%s filter=\"%s\": " 1317 1.1 lukem "unable to find entry\n", 1318 1.1 lukem nbase->bv_val ? nbase->bv_val : "\"\"", 1319 1.1 lukem ldap_pvt_scope2str( scope ), 1320 1.1 lukem filter->bv_val ); 1321 1.1 lukem return -1; 1322 1.1 lukem } 1323 1.1 lukem 1324 1.1 lukem if ( monitor_cache_remove( mi, &ndn, &e ) != 0 ) { 1325 1.1 lukem /* entry does not exist */ 1326 1.1 lukem Debug( LDAP_DEBUG_ANY, 1327 1.1 lukem "monitor_back_unregister_entry(\"%s\"): " 1328 1.1 lukem "entry removal failed.\n", 1329 1.3 christos ndn.bv_val ); 1330 1.1 lukem ber_memfree( ndn.bv_val ); 1331 1.1 lukem return -1; 1332 1.1 lukem } 1333 1.1 lukem ber_memfree( ndn.bv_val ); 1334 1.1 lukem 1335 1.1 lukem mp = (monitor_entry_t *)e->e_private; 1336 1.1 lukem assert( mp != NULL ); 1337 1.1 lukem 1338 1.1 lukem if ( target_cb != NULL ) { 1339 1.1 lukem monitor_callback_t **cbp; 1340 1.1 lukem 1341 1.1 lukem for ( cbp = &mp->mp_cb; *cbp != NULL; cbp = &(*cbp)->mc_next ) { 1342 1.1 lukem if ( *cbp == target_cb ) { 1343 1.1 lukem if ( (*cbp)->mc_free ) { 1344 1.1 lukem (void)(*cbp)->mc_free( e, &(*cbp)->mc_private ); 1345 1.1 lukem } 1346 1.1 lukem *cbp = (*cbp)->mc_next; 1347 1.1 lukem ch_free( target_cb ); 1348 1.1 lukem break; 1349 1.1 lukem } 1350 1.1 lukem } 1351 1.1 lukem } 1352 1.1 lukem 1353 1.1 lukem 1354 1.1 lukem ch_free( mp ); 1355 1.1 lukem e->e_private = NULL; 1356 1.1 lukem entry_free( e ); 1357 1.1 lukem 1358 1.1 lukem } else { 1359 1.1 lukem entry_limbo_t **elpp; 1360 1.1 lukem 1361 1.1 lukem for ( elpp = &mi->mi_entry_limbo; 1362 1.1 lukem *elpp; 1363 1.1 lukem elpp = &(*elpp)->el_next ) 1364 1.1 lukem { 1365 1.1 lukem entry_limbo_t *elp = *elpp; 1366 1.1 lukem 1367 1.1 lukem if ( elp->el_type == LIMBO_ENTRY_PARENT 1368 1.1 lukem && dn_match( nrdn, &elp->el_e->e_nname ) 1369 1.1 lukem && dn_match( nbase, &elp->el_nbase ) 1370 1.1 lukem && scope == elp->el_scope 1371 1.1 lukem && bvmatch( filter, &elp->el_filter ) ) 1372 1.1 lukem { 1373 1.1 lukem monitor_callback_t *cb, *next; 1374 1.1 lukem 1375 1.1 lukem for ( cb = elp->el_cb; cb; cb = next ) { 1376 1.1 lukem /* FIXME: call callbacks? */ 1377 1.1 lukem next = cb->mc_next; 1378 1.1 lukem if ( cb->mc_dispose ) { 1379 1.1 lukem cb->mc_dispose( &cb->mc_private ); 1380 1.1 lukem } 1381 1.1 lukem ch_free( cb ); 1382 1.1 lukem } 1383 1.1 lukem assert( elp->el_e != NULL ); 1384 1.1 lukem elp->el_e->e_private = NULL; 1385 1.1 lukem entry_free( elp->el_e ); 1386 1.1 lukem if ( !BER_BVISNULL( &elp->el_nbase ) ) { 1387 1.1 lukem ch_free( elp->el_nbase.bv_val ); 1388 1.1 lukem } 1389 1.1 lukem if ( !BER_BVISNULL( &elp->el_filter ) ) { 1390 1.1 lukem ch_free( elp->el_filter.bv_val ); 1391 1.1 lukem } 1392 1.1 lukem *elpp = elp->el_next; 1393 1.1 lukem ch_free( elp ); 1394 1.1 lukem elpp = NULL; 1395 1.1 lukem break; 1396 1.1 lukem } 1397 1.1 lukem } 1398 1.1 lukem 1399 1.1 lukem if ( elpp != NULL ) { 1400 1.1 lukem /* not found! where did it go? */ 1401 1.1 lukem return 1; 1402 1.1 lukem } 1403 1.1 lukem } 1404 1.1 lukem 1405 1.1 lukem return 0; 1406 1.1 lukem } 1407 1.1 lukem 1408 1.1 lukem int 1409 1.1 lukem monitor_back_unregister_entry_attrs( 1410 1.1 lukem struct berval *ndn_in, 1411 1.1 lukem Attribute *target_a, 1412 1.1 lukem monitor_callback_t *target_cb, 1413 1.1 lukem struct berval *nbase, 1414 1.1 lukem int scope, 1415 1.1 lukem struct berval *filter ) 1416 1.1 lukem { 1417 1.1 lukem monitor_info_t *mi; 1418 1.1 lukem struct berval ndn = BER_BVNULL; 1419 1.1 lukem char *fname = ( target_a == NULL ? "callback" : "attrs" ); 1420 1.1 lukem 1421 1.1 lukem if ( be_monitor == NULL ) { 1422 1.3 christos Debug(LDAP_DEBUG_ANY, 1423 1.3 christos "monitor_back_unregister_entry_%s(base=\"%s\" scope=%s filter=\"%s\"): " "monitor database not configured.\n\n", 1424 1.3 christos fname, BER_BVISNULL(nbase) ? "" : nbase->bv_val, 1425 1.3 christos ldap_pvt_scope2str(scope), 1426 1.3 christos BER_BVISNULL(filter) ? "" : filter->bv_val ); 1427 1.1 lukem 1428 1.1 lukem return -1; 1429 1.1 lukem } 1430 1.1 lukem 1431 1.1 lukem /* entry will be regularly freed, and resources released 1432 1.1 lukem * according to callbacks */ 1433 1.1 lukem if ( slapd_shutdown ) { 1434 1.1 lukem return 0; 1435 1.1 lukem } 1436 1.1 lukem 1437 1.1 lukem mi = ( monitor_info_t * )be_monitor->be_private; 1438 1.1 lukem 1439 1.1 lukem assert( mi != NULL ); 1440 1.1 lukem 1441 1.1 lukem if ( ndn_in != NULL ) { 1442 1.1 lukem ndn = *ndn_in; 1443 1.1 lukem } 1444 1.1 lukem 1445 1.1 lukem if ( target_a == NULL && target_cb == NULL ) { 1446 1.1 lukem /* nothing to do */ 1447 1.1 lukem return -1; 1448 1.1 lukem } 1449 1.1 lukem 1450 1.1 lukem if ( ( ndn_in == NULL || BER_BVISNULL( &ndn ) ) 1451 1.1 lukem && BER_BVISNULL( filter ) ) 1452 1.1 lukem { 1453 1.1 lukem /* need a filter */ 1454 1.1 lukem Debug( LDAP_DEBUG_ANY, 1455 1.1 lukem "monitor_back_unregister_entry_%s(\"\"): " 1456 1.1 lukem "need a valid filter\n", 1457 1.3 christos fname ); 1458 1.1 lukem return -1; 1459 1.1 lukem } 1460 1.1 lukem 1461 1.1 lukem if ( monitor_subsys_is_opened() ) { 1462 1.1 lukem Entry *e = NULL; 1463 1.1 lukem monitor_entry_t *mp = NULL; 1464 1.1 lukem int freeit = 0; 1465 1.1 lukem 1466 1.1 lukem if ( BER_BVISNULL( &ndn ) ) { 1467 1.1 lukem if ( monitor_search2ndn( nbase, scope, filter, &ndn ) ) { 1468 1.3 christos Debug(LDAP_DEBUG_ANY, 1469 1.3 christos "monitor_back_unregister_entry_%s(\"\"): " "base=\"%s\" scope=%d filter=\"%s\": " "unable to find entry\n\n", 1470 1.3 christos fname, 1471 1.3 christos nbase->bv_val ? nbase->bv_val : "\"\"", 1472 1.3 christos scope, filter->bv_val ); 1473 1.1 lukem return -1; 1474 1.1 lukem } 1475 1.1 lukem 1476 1.1 lukem freeit = 1; 1477 1.1 lukem } 1478 1.1 lukem 1479 1.1 lukem if ( monitor_cache_get( mi, &ndn, &e ) != 0 ) { 1480 1.1 lukem /* entry does not exist */ 1481 1.1 lukem Debug( LDAP_DEBUG_ANY, 1482 1.1 lukem "monitor_back_unregister_entry(\"%s\"): " 1483 1.1 lukem "entry removal failed.\n", 1484 1.3 christos ndn.bv_val ); 1485 1.1 lukem return -1; 1486 1.1 lukem } 1487 1.1 lukem 1488 1.1 lukem mp = (monitor_entry_t *)e->e_private; 1489 1.1 lukem assert( mp != NULL ); 1490 1.1 lukem 1491 1.1 lukem if ( target_cb != NULL ) { 1492 1.1 lukem monitor_callback_t **cbp; 1493 1.1 lukem 1494 1.1 lukem for ( cbp = &mp->mp_cb; *cbp != NULL; cbp = &(*cbp)->mc_next ) { 1495 1.1 lukem if ( *cbp == target_cb ) { 1496 1.1 lukem if ( (*cbp)->mc_free ) { 1497 1.1 lukem (void)(*cbp)->mc_free( e, &(*cbp)->mc_private ); 1498 1.1 lukem } 1499 1.1 lukem *cbp = (*cbp)->mc_next; 1500 1.1 lukem ch_free( target_cb ); 1501 1.1 lukem break; 1502 1.1 lukem } 1503 1.1 lukem } 1504 1.1 lukem } 1505 1.1 lukem 1506 1.1 lukem if ( target_a != NULL ) { 1507 1.1 lukem Attribute *a; 1508 1.1 lukem 1509 1.1 lukem for ( a = target_a; a != NULL; a = a->a_next ) { 1510 1.1 lukem Modification mod = { 0 }; 1511 1.1 lukem const char *text; 1512 1.1 lukem char textbuf[ SLAP_TEXT_BUFLEN ]; 1513 1.1 lukem 1514 1.1 lukem mod.sm_op = LDAP_MOD_DELETE; 1515 1.1 lukem mod.sm_desc = a->a_desc; 1516 1.1 lukem mod.sm_values = a->a_vals; 1517 1.1 lukem mod.sm_nvalues = a->a_nvals; 1518 1.1 lukem 1519 1.1 lukem (void)modify_delete_values( e, &mod, 1, 1520 1.1 lukem &text, textbuf, sizeof( textbuf ) ); 1521 1.1 lukem } 1522 1.1 lukem } 1523 1.1 lukem 1524 1.1 lukem if ( freeit ) { 1525 1.1 lukem ber_memfree( ndn.bv_val ); 1526 1.1 lukem } 1527 1.1 lukem 1528 1.1 lukem monitor_cache_release( mi, e ); 1529 1.1 lukem 1530 1.1 lukem } else { 1531 1.1 lukem entry_limbo_t **elpp; 1532 1.1 lukem 1533 1.1 lukem for ( elpp = &mi->mi_entry_limbo; 1534 1.1 lukem *elpp; 1535 1.1 lukem elpp = &(*elpp)->el_next ) 1536 1.1 lukem { 1537 1.1 lukem entry_limbo_t *elp = *elpp; 1538 1.1 lukem 1539 1.1 lukem if ( elp->el_type == LIMBO_ATTRS 1540 1.1 lukem && dn_match( nbase, &elp->el_nbase ) 1541 1.1 lukem && scope == elp->el_scope 1542 1.1 lukem && bvmatch( filter, &elp->el_filter ) ) 1543 1.1 lukem { 1544 1.1 lukem monitor_callback_t *cb, *next; 1545 1.1 lukem 1546 1.1 lukem for ( cb = elp->el_cb; cb; cb = next ) { 1547 1.1 lukem /* FIXME: call callbacks? */ 1548 1.1 lukem next = cb->mc_next; 1549 1.1 lukem if ( cb->mc_dispose ) { 1550 1.1 lukem cb->mc_dispose( &cb->mc_private ); 1551 1.1 lukem } 1552 1.1 lukem ch_free( cb ); 1553 1.1 lukem } 1554 1.1 lukem assert( elp->el_e == NULL ); 1555 1.1 lukem if ( elp->el_a != NULL ) { 1556 1.1 lukem attrs_free( elp->el_a ); 1557 1.1 lukem } 1558 1.1 lukem if ( !BER_BVISNULL( &elp->el_nbase ) ) { 1559 1.1 lukem ch_free( elp->el_nbase.bv_val ); 1560 1.1 lukem } 1561 1.1 lukem if ( !BER_BVISNULL( &elp->el_filter ) ) { 1562 1.1 lukem ch_free( elp->el_filter.bv_val ); 1563 1.1 lukem } 1564 1.1 lukem *elpp = elp->el_next; 1565 1.1 lukem ch_free( elp ); 1566 1.1 lukem elpp = NULL; 1567 1.1 lukem break; 1568 1.1 lukem } 1569 1.1 lukem } 1570 1.1 lukem 1571 1.1 lukem if ( elpp != NULL ) { 1572 1.1 lukem /* not found! where did it go? */ 1573 1.1 lukem return 1; 1574 1.1 lukem } 1575 1.1 lukem } 1576 1.1 lukem 1577 1.1 lukem return 0; 1578 1.1 lukem } 1579 1.1 lukem 1580 1.1 lukem int 1581 1.1 lukem monitor_back_unregister_entry_callback( 1582 1.1 lukem struct berval *ndn, 1583 1.1 lukem monitor_callback_t *cb, 1584 1.1 lukem struct berval *nbase, 1585 1.1 lukem int scope, 1586 1.1 lukem struct berval *filter ) 1587 1.1 lukem { 1588 1.1 lukem /* TODO: lookup entry (by ndn, if not NULL, and/or by callback); 1589 1.1 lukem * unregister the callback; if a is not null, unregister the 1590 1.1 lukem * given attrs. In any case, call cb->cb_free */ 1591 1.1 lukem return monitor_back_unregister_entry_attrs( ndn, 1592 1.1 lukem NULL, cb, nbase, scope, filter ); 1593 1.1 lukem } 1594 1.1 lukem 1595 1.1 lukem monitor_subsys_t * 1596 1.1 lukem monitor_back_get_subsys( const char *name ) 1597 1.1 lukem { 1598 1.1 lukem if ( monitor_subsys != NULL ) { 1599 1.1 lukem int i; 1600 1.1 lukem 1601 1.1 lukem for ( i = 0; monitor_subsys[ i ] != NULL; i++ ) { 1602 1.1 lukem if ( strcasecmp( monitor_subsys[ i ]->mss_name, name ) == 0 ) { 1603 1.1 lukem return monitor_subsys[ i ]; 1604 1.1 lukem } 1605 1.1 lukem } 1606 1.1 lukem } 1607 1.1 lukem 1608 1.1 lukem return NULL; 1609 1.1 lukem } 1610 1.1 lukem 1611 1.1 lukem monitor_subsys_t * 1612 1.1 lukem monitor_back_get_subsys_by_dn( 1613 1.1 lukem struct berval *ndn, 1614 1.1 lukem int sub ) 1615 1.1 lukem { 1616 1.1 lukem if ( monitor_subsys != NULL ) { 1617 1.1 lukem int i; 1618 1.1 lukem 1619 1.1 lukem if ( sub ) { 1620 1.1 lukem for ( i = 0; monitor_subsys[ i ] != NULL; i++ ) { 1621 1.1 lukem if ( dnIsSuffix( ndn, &monitor_subsys[ i ]->mss_ndn ) ) { 1622 1.1 lukem return monitor_subsys[ i ]; 1623 1.1 lukem } 1624 1.1 lukem } 1625 1.1 lukem 1626 1.1 lukem } else { 1627 1.1 lukem for ( i = 0; monitor_subsys[ i ] != NULL; i++ ) { 1628 1.1 lukem if ( dn_match( ndn, &monitor_subsys[ i ]->mss_ndn ) ) { 1629 1.1 lukem return monitor_subsys[ i ]; 1630 1.1 lukem } 1631 1.1 lukem } 1632 1.1 lukem } 1633 1.1 lukem } 1634 1.1 lukem 1635 1.1 lukem return NULL; 1636 1.1 lukem } 1637 1.1 lukem 1638 1.1 lukem int 1639 1.1 lukem monitor_back_initialize( 1640 1.1 lukem BackendInfo *bi ) 1641 1.1 lukem { 1642 1.1 lukem static char *controls[] = { 1643 1.1 lukem LDAP_CONTROL_MANAGEDSAIT, 1644 1.1 lukem NULL 1645 1.1 lukem }; 1646 1.1 lukem 1647 1.1 lukem static ConfigTable monitorcfg[] = { 1648 1.1 lukem { NULL, NULL, 0, 0, 0, ARG_IGNORED, 1649 1.1 lukem NULL, NULL, NULL, NULL } 1650 1.1 lukem }; 1651 1.1 lukem 1652 1.1 lukem static ConfigOCs monitorocs[] = { 1653 1.1 lukem { "( OLcfgDbOc:4.1 " 1654 1.1 lukem "NAME 'olcMonitorConfig' " 1655 1.1 lukem "DESC 'Monitor backend configuration' " 1656 1.1 lukem "SUP olcDatabaseConfig " 1657 1.1 lukem ")", 1658 1.1 lukem Cft_Database, monitorcfg }, 1659 1.1 lukem { NULL, 0, NULL } 1660 1.1 lukem }; 1661 1.1 lukem 1662 1.1 lukem struct m_s { 1663 1.1 lukem char *schema; 1664 1.1 lukem slap_mask_t flags; 1665 1.1 lukem int offset; 1666 1.1 lukem } moc[] = { 1667 1.1 lukem { "( 1.3.6.1.4.1.4203.666.3.16.1 " 1668 1.1 lukem "NAME 'monitor' " 1669 1.1 lukem "DESC 'OpenLDAP system monitoring' " 1670 1.1 lukem "SUP top STRUCTURAL " 1671 1.1 lukem "MUST cn " 1672 1.1 lukem "MAY ( " 1673 1.1 lukem "description " 1674 1.1 lukem "$ seeAlso " 1675 1.1 lukem "$ labeledURI " 1676 1.1 lukem "$ monitoredInfo " 1677 1.1 lukem "$ managedInfo " 1678 1.1 lukem "$ monitorOverlay " 1679 1.1 lukem ") )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE, 1680 1.1 lukem offsetof(monitor_info_t, mi_oc_monitor) }, 1681 1.1 lukem { "( 1.3.6.1.4.1.4203.666.3.16.2 " 1682 1.1 lukem "NAME 'monitorServer' " 1683 1.1 lukem "DESC 'Server monitoring root entry' " 1684 1.1 lukem "SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE, 1685 1.1 lukem offsetof(monitor_info_t, mi_oc_monitorServer) }, 1686 1.1 lukem { "( 1.3.6.1.4.1.4203.666.3.16.3 " 1687 1.1 lukem "NAME 'monitorContainer' " 1688 1.1 lukem "DESC 'monitor container class' " 1689 1.1 lukem "SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE, 1690 1.1 lukem offsetof(monitor_info_t, mi_oc_monitorContainer) }, 1691 1.1 lukem { "( 1.3.6.1.4.1.4203.666.3.16.4 " 1692 1.1 lukem "NAME 'monitorCounterObject' " 1693 1.1 lukem "DESC 'monitor counter class' " 1694 1.1 lukem "SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE, 1695 1.1 lukem offsetof(monitor_info_t, mi_oc_monitorCounterObject) }, 1696 1.1 lukem { "( 1.3.6.1.4.1.4203.666.3.16.5 " 1697 1.1 lukem "NAME 'monitorOperation' " 1698 1.1 lukem "DESC 'monitor operation class' " 1699 1.1 lukem "SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE, 1700 1.1 lukem offsetof(monitor_info_t, mi_oc_monitorOperation) }, 1701 1.1 lukem { "( 1.3.6.1.4.1.4203.666.3.16.6 " 1702 1.1 lukem "NAME 'monitorConnection' " 1703 1.1 lukem "DESC 'monitor connection class' " 1704 1.1 lukem "SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE, 1705 1.1 lukem offsetof(monitor_info_t, mi_oc_monitorConnection) }, 1706 1.1 lukem { "( 1.3.6.1.4.1.4203.666.3.16.7 " 1707 1.1 lukem "NAME 'managedObject' " 1708 1.1 lukem "DESC 'monitor managed entity class' " 1709 1.1 lukem "SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE, 1710 1.1 lukem offsetof(monitor_info_t, mi_oc_managedObject) }, 1711 1.1 lukem { "( 1.3.6.1.4.1.4203.666.3.16.8 " 1712 1.1 lukem "NAME 'monitoredObject' " 1713 1.1 lukem "DESC 'monitor monitored entity class' " 1714 1.1 lukem "SUP monitor STRUCTURAL )", SLAP_OC_OPERATIONAL|SLAP_OC_HIDE, 1715 1.1 lukem offsetof(monitor_info_t, mi_oc_monitoredObject) }, 1716 1.1 lukem { NULL, 0, -1 } 1717 1.1 lukem }, mat[] = { 1718 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.1 " 1719 1.1 lukem "NAME 'monitoredInfo' " 1720 1.1 lukem "DESC 'monitored info' " 1721 1.1 lukem /* "SUP name " */ 1722 1.1 lukem "EQUALITY caseIgnoreMatch " 1723 1.1 lukem "SUBSTR caseIgnoreSubstringsMatch " 1724 1.1 lukem "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} " 1725 1.1 lukem "NO-USER-MODIFICATION " 1726 1.1 lukem "USAGE dSAOperation )", SLAP_AT_HIDE, 1727 1.1 lukem offsetof(monitor_info_t, mi_ad_monitoredInfo) }, 1728 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.2 " 1729 1.1 lukem "NAME 'managedInfo' " 1730 1.1 lukem "DESC 'monitor managed info' " 1731 1.1 lukem "SUP name )", SLAP_AT_HIDE, 1732 1.1 lukem offsetof(monitor_info_t, mi_ad_managedInfo) }, 1733 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.3 " 1734 1.1 lukem "NAME 'monitorCounter' " 1735 1.1 lukem "DESC 'monitor counter' " 1736 1.1 lukem "EQUALITY integerMatch " 1737 1.1 lukem "ORDERING integerOrderingMatch " 1738 1.1 lukem "SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 " 1739 1.1 lukem "NO-USER-MODIFICATION " 1740 1.1 lukem "USAGE dSAOperation )", SLAP_AT_HIDE, 1741 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorCounter) }, 1742 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.4 " 1743 1.1 lukem "NAME 'monitorOpCompleted' " 1744 1.1 lukem "DESC 'monitor completed operations' " 1745 1.1 lukem "SUP monitorCounter " 1746 1.1 lukem "NO-USER-MODIFICATION " 1747 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1748 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorOpCompleted) }, 1749 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.5 " 1750 1.1 lukem "NAME 'monitorOpInitiated' " 1751 1.1 lukem "DESC 'monitor initiated operations' " 1752 1.1 lukem "SUP monitorCounter " 1753 1.1 lukem "NO-USER-MODIFICATION " 1754 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1755 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorOpInitiated) }, 1756 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.6 " 1757 1.1 lukem "NAME 'monitorConnectionNumber' " 1758 1.1 lukem "DESC 'monitor connection number' " 1759 1.1 lukem "SUP monitorCounter " 1760 1.1 lukem "NO-USER-MODIFICATION " 1761 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1762 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorConnectionNumber) }, 1763 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.7 " 1764 1.1 lukem "NAME 'monitorConnectionAuthzDN' " 1765 1.1 lukem "DESC 'monitor connection authorization DN' " 1766 1.1 lukem /* "SUP distinguishedName " */ 1767 1.1 lukem "EQUALITY distinguishedNameMatch " 1768 1.1 lukem "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 " 1769 1.1 lukem "NO-USER-MODIFICATION " 1770 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1771 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorConnectionAuthzDN) }, 1772 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.8 " 1773 1.1 lukem "NAME 'monitorConnectionLocalAddress' " 1774 1.1 lukem "DESC 'monitor connection local address' " 1775 1.1 lukem "SUP monitoredInfo " 1776 1.1 lukem "NO-USER-MODIFICATION " 1777 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1778 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorConnectionLocalAddress) }, 1779 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.9 " 1780 1.1 lukem "NAME 'monitorConnectionPeerAddress' " 1781 1.1 lukem "DESC 'monitor connection peer address' " 1782 1.1 lukem "SUP monitoredInfo " 1783 1.1 lukem "NO-USER-MODIFICATION " 1784 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1785 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorConnectionPeerAddress) }, 1786 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.10 " 1787 1.1 lukem "NAME 'monitorTimestamp' " 1788 1.1 lukem "DESC 'monitor timestamp' " 1789 1.1 lukem "EQUALITY generalizedTimeMatch " 1790 1.1 lukem "ORDERING generalizedTimeOrderingMatch " 1791 1.1 lukem "SYNTAX 1.3.6.1.4.1.1466.115.121.1.24 " 1792 1.1 lukem "SINGLE-VALUE " 1793 1.1 lukem "NO-USER-MODIFICATION " 1794 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1795 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorTimestamp) }, 1796 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.11 " 1797 1.1 lukem "NAME 'monitorOverlay' " 1798 1.1 lukem "DESC 'name of overlays defined for a given database' " 1799 1.1 lukem "SUP monitoredInfo " 1800 1.1 lukem "NO-USER-MODIFICATION " 1801 1.1 lukem "USAGE dSAOperation )", SLAP_AT_HIDE, 1802 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorOverlay) }, 1803 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.12 " 1804 1.1 lukem "NAME 'readOnly' " 1805 1.1 lukem "DESC 'read/write status of a given database' " 1806 1.1 lukem "EQUALITY booleanMatch " 1807 1.1 lukem "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 " 1808 1.1 lukem "SINGLE-VALUE " 1809 1.1 lukem "USAGE dSAOperation )", SLAP_AT_HIDE, 1810 1.1 lukem offsetof(monitor_info_t, mi_ad_readOnly) }, 1811 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.13 " 1812 1.1 lukem "NAME 'restrictedOperation' " 1813 1.1 lukem "DESC 'name of restricted operation for a given database' " 1814 1.1 lukem "SUP managedInfo )", SLAP_AT_HIDE, 1815 1.1 lukem offsetof(monitor_info_t, mi_ad_restrictedOperation ) }, 1816 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.14 " 1817 1.1 lukem "NAME 'monitorConnectionProtocol' " 1818 1.1 lukem "DESC 'monitor connection protocol' " 1819 1.1 lukem "SUP monitoredInfo " 1820 1.1 lukem "NO-USER-MODIFICATION " 1821 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1822 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorConnectionProtocol) }, 1823 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.15 " 1824 1.1 lukem "NAME 'monitorConnectionOpsReceived' " 1825 1.1 lukem "DESC 'monitor number of operations received by the connection' " 1826 1.1 lukem "SUP monitorCounter " 1827 1.1 lukem "NO-USER-MODIFICATION " 1828 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1829 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorConnectionOpsReceived) }, 1830 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.16 " 1831 1.1 lukem "NAME 'monitorConnectionOpsExecuting' " 1832 1.1 lukem "DESC 'monitor number of operations in execution within the connection' " 1833 1.1 lukem "SUP monitorCounter " 1834 1.1 lukem "NO-USER-MODIFICATION " 1835 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1836 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorConnectionOpsExecuting) }, 1837 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.17 " 1838 1.1 lukem "NAME 'monitorConnectionOpsPending' " 1839 1.1 lukem "DESC 'monitor number of pending operations within the connection' " 1840 1.1 lukem "SUP monitorCounter " 1841 1.1 lukem "NO-USER-MODIFICATION " 1842 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1843 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorConnectionOpsPending) }, 1844 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.18 " 1845 1.1 lukem "NAME 'monitorConnectionOpsCompleted' " 1846 1.1 lukem "DESC 'monitor number of operations completed within the connection' " 1847 1.1 lukem "SUP monitorCounter " 1848 1.1 lukem "NO-USER-MODIFICATION " 1849 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1850 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorConnectionOpsCompleted) }, 1851 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.19 " 1852 1.1 lukem "NAME 'monitorConnectionGet' " 1853 1.1 lukem "DESC 'number of times connection_get() was called so far' " 1854 1.1 lukem "SUP monitorCounter " 1855 1.1 lukem "NO-USER-MODIFICATION " 1856 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1857 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorConnectionGet) }, 1858 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.20 " 1859 1.1 lukem "NAME 'monitorConnectionRead' " 1860 1.1 lukem "DESC 'number of times connection_read() was called so far' " 1861 1.1 lukem "SUP monitorCounter " 1862 1.1 lukem "NO-USER-MODIFICATION " 1863 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1864 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorConnectionRead) }, 1865 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.21 " 1866 1.1 lukem "NAME 'monitorConnectionWrite' " 1867 1.1 lukem "DESC 'number of times connection_write() was called so far' " 1868 1.1 lukem "SUP monitorCounter " 1869 1.1 lukem "NO-USER-MODIFICATION " 1870 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1871 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorConnectionWrite) }, 1872 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.22 " 1873 1.1 lukem "NAME 'monitorConnectionMask' " 1874 1.1 lukem "DESC 'monitor connection mask' " 1875 1.1 lukem "SUP monitoredInfo " 1876 1.1 lukem "NO-USER-MODIFICATION " 1877 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1878 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorConnectionMask) }, 1879 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.23 " 1880 1.1 lukem "NAME 'monitorConnectionListener' " 1881 1.1 lukem "DESC 'monitor connection listener' " 1882 1.1 lukem "SUP monitoredInfo " 1883 1.1 lukem "NO-USER-MODIFICATION " 1884 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1885 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorConnectionListener) }, 1886 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.24 " 1887 1.1 lukem "NAME 'monitorConnectionPeerDomain' " 1888 1.1 lukem "DESC 'monitor connection peer domain' " 1889 1.1 lukem "SUP monitoredInfo " 1890 1.1 lukem "NO-USER-MODIFICATION " 1891 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1892 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorConnectionPeerDomain) }, 1893 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.25 " 1894 1.1 lukem "NAME 'monitorConnectionStartTime' " 1895 1.1 lukem "DESC 'monitor connection start time' " 1896 1.1 lukem "SUP monitorTimestamp " 1897 1.1 lukem "SINGLE-VALUE " 1898 1.1 lukem "NO-USER-MODIFICATION " 1899 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1900 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorConnectionStartTime) }, 1901 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.26 " 1902 1.1 lukem "NAME 'monitorConnectionActivityTime' " 1903 1.1 lukem "DESC 'monitor connection activity time' " 1904 1.1 lukem "SUP monitorTimestamp " 1905 1.1 lukem "SINGLE-VALUE " 1906 1.1 lukem "NO-USER-MODIFICATION " 1907 1.1 lukem "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1908 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorConnectionActivityTime) }, 1909 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.27 " 1910 1.1 lukem "NAME 'monitorIsShadow' " 1911 1.1 lukem "DESC 'TRUE if the database is shadow' " 1912 1.1 lukem "EQUALITY booleanMatch " 1913 1.1 lukem "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 " 1914 1.1 lukem "SINGLE-VALUE " 1915 1.1 lukem "USAGE dSAOperation )", SLAP_AT_HIDE, 1916 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorIsShadow) }, 1917 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.28 " 1918 1.1 lukem "NAME 'monitorUpdateRef' " 1919 1.1 lukem "DESC 'update referral for shadow databases' " 1920 1.1 lukem "SUP monitoredInfo " 1921 1.1 lukem "SINGLE-VALUE " 1922 1.1 lukem "USAGE dSAOperation )", SLAP_AT_HIDE, 1923 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorUpdateRef) }, 1924 1.1 lukem { "( 1.3.6.1.4.1.4203.666.1.55.29 " 1925 1.1 lukem "NAME 'monitorRuntimeConfig' " 1926 1.1 lukem "DESC 'TRUE if component allows runtime configuration' " 1927 1.1 lukem "EQUALITY booleanMatch " 1928 1.1 lukem "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 " 1929 1.1 lukem "SINGLE-VALUE " 1930 1.1 lukem "USAGE dSAOperation )", SLAP_AT_HIDE, 1931 1.1 lukem offsetof(monitor_info_t, mi_ad_monitorRuntimeConfig) }, 1932 1.2 christos { "( 1.3.6.1.4.1.4203.666.1.55.30 " 1933 1.2 christos "NAME 'monitorSuperiorDN' " 1934 1.2 christos "DESC 'monitor superior DN' " 1935 1.2 christos /* "SUP distinguishedName " */ 1936 1.2 christos "EQUALITY distinguishedNameMatch " 1937 1.2 christos "SYNTAX 1.3.6.1.4.1.1466.115.121.1.12 " 1938 1.2 christos "NO-USER-MODIFICATION " 1939 1.2 christos "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1940 1.2 christos offsetof(monitor_info_t, mi_ad_monitorSuperiorDN) }, 1941 1.4 christos { "( 1.3.6.1.4.1.4203.666.1.55.31 " 1942 1.4 christos "NAME 'monitorConnectionOpsAsync' " 1943 1.4 christos "DESC 'monitor number of asynchronous operations in execution within the connection' " 1944 1.4 christos "SUP monitorCounter " 1945 1.4 christos "NO-USER-MODIFICATION " 1946 1.4 christos "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1947 1.4 christos offsetof(monitor_info_t, mi_ad_monitorConnectionOpsAsync) }, 1948 1.4 christos { "( 1.3.6.1.4.1.4203.666.1.55.32 " 1949 1.4 christos "NAME 'monitorLogLevel' " 1950 1.4 christos "DESC 'current slapd log level' " 1951 1.4 christos "EQUALITY caseIgnoreMatch " 1952 1.4 christos "SUBSTR caseIgnoreSubstringsMatch " 1953 1.4 christos "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 " 1954 1.4 christos "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1955 1.4 christos offsetof(monitor_info_t, mi_ad_monitorLogLevel) }, 1956 1.4 christos { "( 1.3.6.1.4.1.4203.666.1.55.33 " 1957 1.4 christos "NAME 'monitorDebugLevel' " 1958 1.4 christos "DESC 'current slapd debug level' " 1959 1.4 christos "EQUALITY caseIgnoreMatch " 1960 1.4 christos "SUBSTR caseIgnoreSubstringsMatch " 1961 1.4 christos "SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 " 1962 1.4 christos "USAGE dSAOperation )", SLAP_AT_FINAL|SLAP_AT_HIDE, 1963 1.4 christos offsetof(monitor_info_t, mi_ad_monitorDebugLevel) }, 1964 1.1 lukem { NULL, 0, -1 } 1965 1.1 lukem }; 1966 1.1 lukem 1967 1.1 lukem static struct { 1968 1.1 lukem char *name; 1969 1.1 lukem char *oid; 1970 1.1 lukem } s_oid[] = { 1971 1.1 lukem { "olmAttributes", "1.3.6.1.4.1.4203.666.1.55" }, 1972 1.1 lukem { "olmSubSystemAttributes", "olmAttributes:0" }, 1973 1.1 lukem { "olmGenericAttributes", "olmSubSystemAttributes:0" }, 1974 1.1 lukem { "olmDatabaseAttributes", "olmSubSystemAttributes:1" }, 1975 1.3 christos { "olmOverlayAttributes", "olmSubSystemAttributes:2" }, 1976 1.3 christos { "olmModuleAttributes", "olmSubSystemAttributes:3" }, 1977 1.1 lukem 1978 1.3 christos /* for example, back-mdb specific attrs 1979 1.3 christos * are in "olmDatabaseAttributes:12" 1980 1.1 lukem * 1981 1.1 lukem * NOTE: developers, please record here OID assignments 1982 1.1 lukem * for other modules */ 1983 1.1 lukem 1984 1.1 lukem { "olmObjectClasses", "1.3.6.1.4.1.4203.666.3.16" }, 1985 1.1 lukem { "olmSubSystemObjectClasses", "olmObjectClasses:0" }, 1986 1.1 lukem { "olmGenericObjectClasses", "olmSubSystemObjectClasses:0" }, 1987 1.1 lukem { "olmDatabaseObjectClasses", "olmSubSystemObjectClasses:1" }, 1988 1.3 christos { "olmOverlayObjectClasses", "olmSubSystemObjectClasses:2" }, 1989 1.3 christos { "olmModuleObjectClasses", "olmSubSystemObjectClasses:3" }, 1990 1.1 lukem 1991 1.3 christos /* for example, back-mdb specific objectClasses 1992 1.3 christos * are in "olmDatabaseObjectClasses:12" 1993 1.1 lukem * 1994 1.1 lukem * NOTE: developers, please record here OID assignments 1995 1.1 lukem * for other modules */ 1996 1.1 lukem 1997 1.1 lukem { NULL } 1998 1.1 lukem }; 1999 1.1 lukem 2000 1.1 lukem int i, rc; 2001 1.1 lukem monitor_info_t *mi = &monitor_info; 2002 1.1 lukem ConfigArgs c; 2003 1.1 lukem char *argv[ 3 ]; 2004 1.1 lukem 2005 1.1 lukem argv[ 0 ] = "monitor"; 2006 1.1 lukem c.argv = argv; 2007 1.1 lukem c.argc = 3; 2008 1.1 lukem c.fname = argv[0]; 2009 1.1 lukem 2010 1.1 lukem for ( i = 0; s_oid[ i ].name; i++ ) { 2011 1.1 lukem argv[ 1 ] = s_oid[ i ].name; 2012 1.1 lukem argv[ 2 ] = s_oid[ i ].oid; 2013 1.1 lukem 2014 1.1 lukem if ( parse_oidm( &c, 0, NULL ) != 0 ) { 2015 1.1 lukem Debug( LDAP_DEBUG_ANY, 2016 1.1 lukem "monitor_back_initialize: unable to add " 2017 1.1 lukem "objectIdentifier \"%s=%s\"\n", 2018 1.3 christos s_oid[ i ].name, s_oid[ i ].oid ); 2019 1.1 lukem return 1; 2020 1.1 lukem } 2021 1.1 lukem } 2022 1.1 lukem 2023 1.1 lukem /* schema integration */ 2024 1.1 lukem for ( i = 0; mat[ i ].schema; i++ ) { 2025 1.1 lukem int code; 2026 1.1 lukem AttributeDescription **ad = 2027 1.1 lukem ((AttributeDescription **)&(((char *)mi)[ mat[ i ].offset ])); 2028 1.1 lukem 2029 1.1 lukem *ad = NULL; 2030 1.1 lukem code = register_at( mat[ i ].schema, ad, 0 ); 2031 1.1 lukem 2032 1.1 lukem if ( code ) { 2033 1.1 lukem Debug( LDAP_DEBUG_ANY, 2034 1.3 christos "monitor_back_db_init: register_at failed\n" ); 2035 1.1 lukem return -1; 2036 1.1 lukem } 2037 1.1 lukem (*ad)->ad_type->sat_flags |= mat[ i ].flags; 2038 1.1 lukem } 2039 1.1 lukem 2040 1.1 lukem for ( i = 0; moc[ i ].schema; i++ ) { 2041 1.1 lukem int code; 2042 1.1 lukem ObjectClass **Oc = 2043 1.1 lukem ((ObjectClass **)&(((char *)mi)[ moc[ i ].offset ])); 2044 1.1 lukem 2045 1.1 lukem code = register_oc( moc[ i ].schema, Oc, 0 ); 2046 1.1 lukem if ( code ) { 2047 1.1 lukem Debug( LDAP_DEBUG_ANY, 2048 1.3 christos "monitor_back_db_init: register_oc failed\n" ); 2049 1.1 lukem return -1; 2050 1.1 lukem } 2051 1.1 lukem (*Oc)->soc_flags |= moc[ i ].flags; 2052 1.1 lukem } 2053 1.1 lukem 2054 1.1 lukem bi->bi_controls = controls; 2055 1.1 lukem 2056 1.1 lukem bi->bi_init = 0; 2057 1.1 lukem bi->bi_open = 0; 2058 1.1 lukem bi->bi_config = monitor_back_config; 2059 1.1 lukem bi->bi_close = 0; 2060 1.1 lukem bi->bi_destroy = 0; 2061 1.1 lukem 2062 1.1 lukem bi->bi_db_init = monitor_back_db_init; 2063 1.1 lukem #if 0 2064 1.1 lukem bi->bi_db_config = monitor_back_db_config; 2065 1.1 lukem #endif 2066 1.1 lukem bi->bi_db_open = monitor_back_db_open; 2067 1.1 lukem bi->bi_db_close = 0; 2068 1.1 lukem bi->bi_db_destroy = monitor_back_db_destroy; 2069 1.1 lukem 2070 1.1 lukem bi->bi_op_bind = monitor_back_bind; 2071 1.1 lukem bi->bi_op_unbind = 0; 2072 1.1 lukem bi->bi_op_search = monitor_back_search; 2073 1.1 lukem bi->bi_op_compare = monitor_back_compare; 2074 1.1 lukem bi->bi_op_modify = monitor_back_modify; 2075 1.1 lukem bi->bi_op_modrdn = 0; 2076 1.1 lukem bi->bi_op_add = 0; 2077 1.1 lukem bi->bi_op_delete = 0; 2078 1.1 lukem bi->bi_op_abandon = 0; 2079 1.1 lukem 2080 1.1 lukem bi->bi_extended = 0; 2081 1.1 lukem 2082 1.2 christos bi->bi_entry_release_rw = monitor_back_release; 2083 1.1 lukem bi->bi_chk_referrals = 0; 2084 1.1 lukem bi->bi_operational = monitor_back_operational; 2085 1.1 lukem 2086 1.1 lukem /* 2087 1.1 lukem * hooks for slap tools 2088 1.1 lukem */ 2089 1.1 lukem bi->bi_tool_entry_open = 0; 2090 1.1 lukem bi->bi_tool_entry_close = 0; 2091 1.1 lukem bi->bi_tool_entry_first = 0; 2092 1.2 christos bi->bi_tool_entry_first_x = 0; 2093 1.1 lukem bi->bi_tool_entry_next = 0; 2094 1.1 lukem bi->bi_tool_entry_get = 0; 2095 1.1 lukem bi->bi_tool_entry_put = 0; 2096 1.1 lukem bi->bi_tool_entry_reindex = 0; 2097 1.1 lukem bi->bi_tool_sync = 0; 2098 1.1 lukem bi->bi_tool_dn2id_get = 0; 2099 1.1 lukem bi->bi_tool_entry_modify = 0; 2100 1.1 lukem 2101 1.1 lukem bi->bi_connection_init = 0; 2102 1.1 lukem bi->bi_connection_destroy = 0; 2103 1.1 lukem 2104 1.1 lukem bi->bi_extra = (void *)&monitor_extra; 2105 1.1 lukem 2106 1.1 lukem /* 2107 1.1 lukem * configuration objectClasses (fake) 2108 1.1 lukem */ 2109 1.1 lukem bi->bi_cf_ocs = monitorocs; 2110 1.1 lukem 2111 1.1 lukem rc = config_register_schema( monitorcfg, monitorocs ); 2112 1.1 lukem if ( rc ) { 2113 1.1 lukem return rc; 2114 1.1 lukem } 2115 1.1 lukem 2116 1.1 lukem return 0; 2117 1.1 lukem } 2118 1.1 lukem 2119 1.1 lukem int 2120 1.1 lukem monitor_back_db_init( 2121 1.1 lukem BackendDB *be, 2122 1.1 lukem ConfigReply *c) 2123 1.1 lukem { 2124 1.1 lukem int rc; 2125 1.1 lukem struct berval dn = BER_BVC( SLAPD_MONITOR_DN ), 2126 1.1 lukem pdn, 2127 1.1 lukem ndn; 2128 1.1 lukem BackendDB *be2; 2129 1.1 lukem 2130 1.1 lukem monitor_subsys_t *ms; 2131 1.1 lukem 2132 1.1 lukem /* 2133 1.1 lukem * database monitor can be defined once only 2134 1.1 lukem */ 2135 1.1 lukem if ( be_monitor != NULL ) { 2136 1.1 lukem if (c) { 2137 1.1 lukem snprintf(c->msg, sizeof(c->msg),"only one monitor database allowed"); 2138 1.1 lukem } 2139 1.1 lukem return( -1 ); 2140 1.1 lukem } 2141 1.1 lukem be_monitor = be; 2142 1.1 lukem 2143 1.1 lukem /* 2144 1.1 lukem * register subsys 2145 1.1 lukem */ 2146 1.1 lukem for ( ms = known_monitor_subsys; ms->mss_name != NULL; ms++ ) { 2147 1.1 lukem if ( monitor_back_register_subsys( ms ) ) { 2148 1.1 lukem return -1; 2149 1.1 lukem } 2150 1.1 lukem } 2151 1.1 lukem 2152 1.1 lukem /* indicate system schema supported */ 2153 1.1 lukem SLAP_BFLAGS(be) |= SLAP_BFLAG_MONITOR; 2154 1.1 lukem 2155 1.1 lukem rc = dnPrettyNormal( NULL, &dn, &pdn, &ndn, NULL ); 2156 1.1 lukem if( rc != LDAP_SUCCESS ) { 2157 1.1 lukem Debug( LDAP_DEBUG_ANY, 2158 1.1 lukem "unable to normalize/pretty monitor DN \"%s\" (%d)\n", 2159 1.3 christos dn.bv_val, rc ); 2160 1.1 lukem return -1; 2161 1.1 lukem } 2162 1.1 lukem 2163 1.1 lukem ber_bvarray_add( &be->be_suffix, &pdn ); 2164 1.1 lukem ber_bvarray_add( &be->be_nsuffix, &ndn ); 2165 1.1 lukem 2166 1.1 lukem /* NOTE: only one monitor database is allowed, 2167 1.1 lukem * so we use static storage */ 2168 1.4 christos ldap_pvt_thread_mutex_init( &monitor_info.mi_cache_lock ); 2169 1.1 lukem 2170 1.1 lukem be->be_private = &monitor_info; 2171 1.1 lukem 2172 1.1 lukem be2 = select_backend( &ndn, 0 ); 2173 1.1 lukem if ( be2 != be ) { 2174 1.1 lukem char *type = be2->bd_info->bi_type; 2175 1.1 lukem 2176 1.1 lukem if ( overlay_is_over( be2 ) ) { 2177 1.1 lukem slap_overinfo *oi = (slap_overinfo *)be2->bd_info->bi_private; 2178 1.1 lukem type = oi->oi_orig->bi_type; 2179 1.1 lukem } 2180 1.1 lukem 2181 1.1 lukem if (c) { 2182 1.1 lukem snprintf(c->msg, sizeof(c->msg), 2183 1.1 lukem "\"monitor\" database serving namingContext \"%s\" " 2184 1.1 lukem "is hidden by \"%s\" database serving namingContext \"%s\".\n", 2185 1.1 lukem pdn.bv_val, type, be2->be_nsuffix[ 0 ].bv_val ); 2186 1.1 lukem } 2187 1.1 lukem return -1; 2188 1.1 lukem } 2189 1.1 lukem 2190 1.1 lukem return 0; 2191 1.1 lukem } 2192 1.1 lukem 2193 1.1 lukem static void 2194 1.1 lukem monitor_back_destroy_limbo_entry( 2195 1.1 lukem entry_limbo_t *el, 2196 1.1 lukem int dispose ) 2197 1.1 lukem { 2198 1.1 lukem if ( el->el_e ) { 2199 1.1 lukem entry_free( el->el_e ); 2200 1.1 lukem } 2201 1.1 lukem if ( el->el_a ) { 2202 1.1 lukem attrs_free( el->el_a ); 2203 1.1 lukem } 2204 1.1 lukem if ( !BER_BVISNULL( &el->el_nbase ) ) { 2205 1.1 lukem ber_memfree( el->el_nbase.bv_val ); 2206 1.1 lukem } 2207 1.1 lukem if ( !BER_BVISNULL( &el->el_filter ) ) { 2208 1.1 lukem ber_memfree( el->el_filter.bv_val ); 2209 1.1 lukem } 2210 1.1 lukem 2211 1.1 lukem /* NOTE: callbacks are not copied; so only free them 2212 1.1 lukem * if disposing of */ 2213 1.1 lukem if ( el->el_cb && dispose != 0 ) { 2214 1.1 lukem monitor_callback_t *next; 2215 1.1 lukem 2216 1.1 lukem for ( ; el->el_cb; el->el_cb = next ) { 2217 1.1 lukem next = el->el_cb->mc_next; 2218 1.1 lukem if ( el->el_cb->mc_dispose ) { 2219 1.1 lukem el->el_cb->mc_dispose( &el->el_cb->mc_private ); 2220 1.1 lukem } 2221 1.1 lukem ch_free( el->el_cb ); 2222 1.1 lukem } 2223 1.1 lukem } 2224 1.1 lukem 2225 1.1 lukem ch_free( el ); 2226 1.1 lukem } 2227 1.1 lukem 2228 1.1 lukem int 2229 1.1 lukem monitor_back_db_open( 2230 1.1 lukem BackendDB *be, 2231 1.1 lukem ConfigReply *cr) 2232 1.1 lukem { 2233 1.1 lukem monitor_info_t *mi = (monitor_info_t *)be->be_private; 2234 1.1 lukem struct monitor_subsys_t **ms; 2235 1.4 christos Entry *e, *root; 2236 1.1 lukem monitor_entry_t *mp; 2237 1.1 lukem int i; 2238 1.1 lukem struct berval bv, rdn = BER_BVC(SLAPD_MONITOR_DN); 2239 1.2 christos struct tm tms; 2240 1.1 lukem static char tmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ]; 2241 1.1 lukem struct berval desc[] = { 2242 1.1 lukem BER_BVC("This subtree contains monitoring/managing objects."), 2243 1.1 lukem BER_BVC("This object contains information about this server."), 2244 1.1 lukem BER_BVC("Most of the information is held in operational" 2245 1.1 lukem " attributes, which must be explicitly requested."), 2246 1.1 lukem BER_BVNULL }; 2247 1.1 lukem 2248 1.1 lukem int retcode = 0; 2249 1.1 lukem 2250 1.1 lukem assert( be_monitor != NULL ); 2251 1.1 lukem if ( be != be_monitor ) { 2252 1.1 lukem be_monitor = be; 2253 1.1 lukem } 2254 1.1 lukem 2255 1.1 lukem /* 2256 1.1 lukem * Start 2257 1.1 lukem */ 2258 1.2 christos ldap_pvt_gmtime( &starttime, &tms ); 2259 1.2 christos lutil_gentime( tmbuf, sizeof(tmbuf), &tms ); 2260 1.1 lukem 2261 1.1 lukem mi->mi_startTime.bv_val = tmbuf; 2262 1.1 lukem mi->mi_startTime.bv_len = strlen( tmbuf ); 2263 1.1 lukem 2264 1.1 lukem if ( BER_BVISEMPTY( &be->be_rootdn ) ) { 2265 1.1 lukem BER_BVSTR( &mi->mi_creatorsName, SLAPD_ANONYMOUS ); 2266 1.1 lukem BER_BVSTR( &mi->mi_ncreatorsName, SLAPD_ANONYMOUS ); 2267 1.1 lukem } else { 2268 1.1 lukem mi->mi_creatorsName = be->be_rootdn; 2269 1.1 lukem mi->mi_ncreatorsName = be->be_rootndn; 2270 1.1 lukem } 2271 1.1 lukem 2272 1.1 lukem /* 2273 1.1 lukem * creates the "cn=Monitor" entry 2274 1.1 lukem */ 2275 1.2 christos e = monitor_entry_stub( NULL, NULL, &rdn, mi->mi_oc_monitorServer, 2276 1.1 lukem NULL, NULL ); 2277 1.1 lukem 2278 1.1 lukem if ( e == NULL) { 2279 1.1 lukem Debug( LDAP_DEBUG_ANY, 2280 1.1 lukem "unable to create \"%s\" entry\n", 2281 1.3 christos SLAPD_MONITOR_DN ); 2282 1.1 lukem return( -1 ); 2283 1.1 lukem } 2284 1.1 lukem 2285 1.1 lukem attr_merge_normalize( e, slap_schema.si_ad_description, desc, NULL ); 2286 1.1 lukem 2287 1.1 lukem bv.bv_val = strchr( (char *) Versionstr, '$' ); 2288 1.1 lukem if ( bv.bv_val != NULL ) { 2289 1.1 lukem char *end; 2290 1.1 lukem 2291 1.1 lukem bv.bv_val++; 2292 1.1 lukem for ( ; bv.bv_val[ 0 ] == ' '; bv.bv_val++ ) 2293 1.1 lukem ; 2294 1.1 lukem 2295 1.1 lukem end = strchr( bv.bv_val, '$' ); 2296 1.1 lukem if ( end != NULL ) { 2297 1.1 lukem end--; 2298 1.1 lukem 2299 1.1 lukem for ( ; end > bv.bv_val && end[ 0 ] == ' '; end-- ) 2300 1.1 lukem ; 2301 1.1 lukem 2302 1.1 lukem end++; 2303 1.1 lukem 2304 1.1 lukem bv.bv_len = end - bv.bv_val; 2305 1.1 lukem 2306 1.1 lukem } else { 2307 1.1 lukem bv.bv_len = strlen( bv.bv_val ); 2308 1.1 lukem } 2309 1.1 lukem 2310 1.1 lukem if ( attr_merge_normalize_one( e, mi->mi_ad_monitoredInfo, 2311 1.1 lukem &bv, NULL ) ) { 2312 1.1 lukem Debug( LDAP_DEBUG_ANY, 2313 1.1 lukem "unable to add monitoredInfo to \"%s\" entry\n", 2314 1.3 christos SLAPD_MONITOR_DN ); 2315 1.1 lukem return( -1 ); 2316 1.1 lukem } 2317 1.1 lukem } 2318 1.1 lukem 2319 1.1 lukem mp = monitor_entrypriv_create(); 2320 1.1 lukem if ( mp == NULL ) { 2321 1.1 lukem return -1; 2322 1.1 lukem } 2323 1.1 lukem e->e_private = ( void * )mp; 2324 1.1 lukem 2325 1.4 christos if ( monitor_cache_add( mi, e, NULL ) ) { 2326 1.1 lukem Debug( LDAP_DEBUG_ANY, 2327 1.1 lukem "unable to add entry \"%s\" to cache\n", 2328 1.3 christos SLAPD_MONITOR_DN ); 2329 1.1 lukem return -1; 2330 1.1 lukem } 2331 1.1 lukem root = e; 2332 1.1 lukem 2333 1.1 lukem /* 2334 1.1 lukem * Create all the subsystem specific entries 2335 1.1 lukem */ 2336 1.1 lukem for ( i = 0; monitor_subsys[ i ] != NULL; i++ ) { 2337 1.1 lukem int len = strlen( monitor_subsys[ i ]->mss_name ); 2338 1.1 lukem struct berval dn; 2339 1.1 lukem int rc; 2340 1.1 lukem 2341 1.1 lukem dn.bv_len = len + sizeof( "cn=" ) - 1; 2342 1.1 lukem dn.bv_val = ch_calloc( sizeof( char ), dn.bv_len + 1 ); 2343 1.1 lukem strcpy( dn.bv_val, "cn=" ); 2344 1.1 lukem strcat( dn.bv_val, monitor_subsys[ i ]->mss_name ); 2345 1.1 lukem rc = dnPretty( NULL, &dn, &monitor_subsys[ i ]->mss_rdn, NULL ); 2346 1.1 lukem free( dn.bv_val ); 2347 1.1 lukem if ( rc != LDAP_SUCCESS ) { 2348 1.1 lukem Debug( LDAP_DEBUG_ANY, 2349 1.1 lukem "monitor RDN \"%s\" is invalid\n", 2350 1.3 christos dn.bv_val ); 2351 1.1 lukem return( -1 ); 2352 1.1 lukem } 2353 1.1 lukem 2354 1.1 lukem e = monitor_entry_stub( &root->e_name, &root->e_nname, 2355 1.2 christos &monitor_subsys[ i ]->mss_rdn, mi->mi_oc_monitorContainer, 2356 1.1 lukem NULL, NULL ); 2357 1.1 lukem 2358 1.1 lukem if ( e == NULL) { 2359 1.1 lukem Debug( LDAP_DEBUG_ANY, 2360 1.1 lukem "unable to create \"%s\" entry\n", 2361 1.3 christos monitor_subsys[ i ]->mss_dn.bv_val ); 2362 1.1 lukem return( -1 ); 2363 1.1 lukem } 2364 1.1 lukem monitor_subsys[i]->mss_dn = e->e_name; 2365 1.1 lukem monitor_subsys[i]->mss_ndn = e->e_nname; 2366 1.1 lukem 2367 1.1 lukem if ( !BER_BVISNULL( &monitor_subsys[ i ]->mss_desc[ 0 ] ) ) { 2368 1.1 lukem attr_merge_normalize( e, slap_schema.si_ad_description, 2369 1.1 lukem monitor_subsys[ i ]->mss_desc, NULL ); 2370 1.1 lukem } 2371 1.1 lukem 2372 1.1 lukem mp = monitor_entrypriv_create(); 2373 1.1 lukem if ( mp == NULL ) { 2374 1.1 lukem return -1; 2375 1.1 lukem } 2376 1.1 lukem e->e_private = ( void * )mp; 2377 1.1 lukem mp->mp_info = monitor_subsys[ i ]; 2378 1.1 lukem mp->mp_flags = monitor_subsys[ i ]->mss_flags; 2379 1.1 lukem 2380 1.4 christos if ( monitor_cache_add( mi, e, root ) ) { 2381 1.1 lukem Debug( LDAP_DEBUG_ANY, 2382 1.1 lukem "unable to add entry \"%s\" to cache\n", 2383 1.3 christos monitor_subsys[ i ]->mss_dn.bv_val ); 2384 1.1 lukem return -1; 2385 1.1 lukem } 2386 1.1 lukem } 2387 1.1 lukem 2388 1.1 lukem assert( be != NULL ); 2389 1.1 lukem 2390 1.1 lukem be->be_private = mi; 2391 1.1 lukem 2392 1.1 lukem /* 2393 1.1 lukem * opens the monitor backend subsystems 2394 1.1 lukem */ 2395 1.1 lukem for ( ms = monitor_subsys; ms[ 0 ] != NULL; ms++ ) { 2396 1.2 christos if ( ms[ 0 ]->mss_open && ms[ 0 ]->mss_open( be, ms[ 0 ] ) ) { 2397 1.1 lukem return( -1 ); 2398 1.1 lukem } 2399 1.1 lukem ms[ 0 ]->mss_flags |= MONITOR_F_OPENED; 2400 1.1 lukem } 2401 1.1 lukem 2402 1.1 lukem monitor_subsys_opened = 1; 2403 1.1 lukem 2404 1.1 lukem if ( mi->mi_entry_limbo ) { 2405 1.1 lukem entry_limbo_t *el = mi->mi_entry_limbo; 2406 1.1 lukem 2407 1.1 lukem for ( ; el; ) { 2408 1.1 lukem entry_limbo_t *tmp; 2409 1.1 lukem int rc; 2410 1.1 lukem 2411 1.1 lukem switch ( el->el_type ) { 2412 1.1 lukem case LIMBO_ENTRY: 2413 1.1 lukem rc = monitor_back_register_entry( 2414 1.1 lukem el->el_e, 2415 1.1 lukem el->el_cb, 2416 1.1 lukem el->el_mss, 2417 1.1 lukem el->el_flags ); 2418 1.1 lukem break; 2419 1.1 lukem 2420 1.1 lukem case LIMBO_ENTRY_PARENT: 2421 1.1 lukem rc = monitor_back_register_entry_parent( 2422 1.1 lukem el->el_e, 2423 1.1 lukem el->el_cb, 2424 1.1 lukem el->el_mss, 2425 1.1 lukem el->el_flags, 2426 1.1 lukem &el->el_nbase, 2427 1.1 lukem el->el_scope, 2428 1.1 lukem &el->el_filter ); 2429 1.1 lukem break; 2430 1.1 lukem 2431 1.1 lukem 2432 1.1 lukem case LIMBO_ATTRS: 2433 1.1 lukem rc = monitor_back_register_entry_attrs( 2434 1.1 lukem el->el_ndn, 2435 1.1 lukem el->el_a, 2436 1.1 lukem el->el_cb, 2437 1.1 lukem &el->el_nbase, 2438 1.1 lukem el->el_scope, 2439 1.1 lukem &el->el_filter ); 2440 1.1 lukem break; 2441 1.1 lukem 2442 1.1 lukem case LIMBO_CB: 2443 1.1 lukem rc = monitor_back_register_entry_callback( 2444 1.1 lukem el->el_ndn, 2445 1.1 lukem el->el_cb, 2446 1.1 lukem &el->el_nbase, 2447 1.1 lukem el->el_scope, 2448 1.1 lukem &el->el_filter ); 2449 1.1 lukem break; 2450 1.1 lukem 2451 1.1 lukem case LIMBO_BACKEND: 2452 1.1 lukem rc = monitor_back_register_backend( el->el_bi ); 2453 1.1 lukem break; 2454 1.1 lukem 2455 1.1 lukem case LIMBO_DATABASE: 2456 1.1 lukem rc = monitor_back_register_database( el->el_be, el->el_ndn ); 2457 1.1 lukem break; 2458 1.1 lukem 2459 1.1 lukem case LIMBO_OVERLAY_INFO: 2460 1.1 lukem rc = monitor_back_register_overlay_info( el->el_on ); 2461 1.1 lukem break; 2462 1.1 lukem 2463 1.1 lukem case LIMBO_OVERLAY: 2464 1.2 christos rc = monitor_back_register_overlay( el->el_be, el->el_on, el->el_ndn ); 2465 1.2 christos break; 2466 1.2 christos 2467 1.2 christos case LIMBO_SUBSYS: 2468 1.2 christos rc = monitor_back_register_subsys( el->el_mss ); 2469 1.1 lukem break; 2470 1.1 lukem 2471 1.1 lukem default: 2472 1.1 lukem assert( 0 ); 2473 1.1 lukem } 2474 1.1 lukem 2475 1.1 lukem tmp = el; 2476 1.1 lukem el = el->el_next; 2477 1.1 lukem monitor_back_destroy_limbo_entry( tmp, rc ); 2478 1.1 lukem 2479 1.1 lukem if ( rc != 0 ) { 2480 1.1 lukem /* try all, but report error at end */ 2481 1.1 lukem retcode = 1; 2482 1.1 lukem } 2483 1.1 lukem } 2484 1.1 lukem 2485 1.1 lukem mi->mi_entry_limbo = NULL; 2486 1.1 lukem } 2487 1.1 lukem 2488 1.1 lukem return retcode; 2489 1.1 lukem } 2490 1.1 lukem 2491 1.1 lukem int 2492 1.1 lukem monitor_back_config( 2493 1.1 lukem BackendInfo *bi, 2494 1.1 lukem const char *fname, 2495 1.1 lukem int lineno, 2496 1.1 lukem int argc, 2497 1.1 lukem char **argv ) 2498 1.1 lukem { 2499 1.1 lukem /* 2500 1.1 lukem * eventually, will hold backend specific configuration parameters 2501 1.1 lukem */ 2502 1.1 lukem return SLAP_CONF_UNKNOWN; 2503 1.1 lukem } 2504 1.1 lukem 2505 1.1 lukem #if 0 2506 1.1 lukem int 2507 1.1 lukem monitor_back_db_config( 2508 1.1 lukem Backend *be, 2509 1.1 lukem const char *fname, 2510 1.1 lukem int lineno, 2511 1.1 lukem int argc, 2512 1.1 lukem char **argv ) 2513 1.1 lukem { 2514 1.1 lukem monitor_info_t *mi = ( monitor_info_t * )be->be_private; 2515 1.1 lukem 2516 1.1 lukem /* 2517 1.1 lukem * eventually, will hold database specific configuration parameters 2518 1.1 lukem */ 2519 1.1 lukem return SLAP_CONF_UNKNOWN; 2520 1.1 lukem } 2521 1.1 lukem #endif 2522 1.1 lukem 2523 1.1 lukem int 2524 1.1 lukem monitor_back_db_destroy( 2525 1.1 lukem BackendDB *be, 2526 1.1 lukem ConfigReply *cr) 2527 1.1 lukem { 2528 1.1 lukem monitor_info_t *mi = ( monitor_info_t * )be->be_private; 2529 1.1 lukem 2530 1.1 lukem if ( mi == NULL ) { 2531 1.1 lukem return -1; 2532 1.1 lukem } 2533 1.1 lukem 2534 1.1 lukem /* 2535 1.1 lukem * FIXME: destroys all the data 2536 1.1 lukem */ 2537 1.1 lukem /* NOTE: mi points to static storage; don't free it */ 2538 1.1 lukem 2539 1.1 lukem (void)monitor_cache_destroy( mi ); 2540 1.1 lukem 2541 1.1 lukem if ( monitor_subsys ) { 2542 1.1 lukem int i; 2543 1.1 lukem 2544 1.1 lukem for ( i = 0; monitor_subsys[ i ] != NULL; i++ ) { 2545 1.4 christos if ( !BER_BVISNULL( &monitor_subsys[ i ]->mss_rdn ) ) { 2546 1.4 christos ch_free( monitor_subsys[ i ]->mss_rdn.bv_val ); 2547 1.4 christos } 2548 1.4 christos 2549 1.1 lukem if ( monitor_subsys[ i ]->mss_destroy ) { 2550 1.1 lukem monitor_subsys[ i ]->mss_destroy( be, monitor_subsys[ i ] ); 2551 1.1 lukem } 2552 1.1 lukem } 2553 1.1 lukem 2554 1.1 lukem ch_free( monitor_subsys ); 2555 1.1 lukem } 2556 1.1 lukem 2557 1.1 lukem if ( mi->mi_entry_limbo ) { 2558 1.1 lukem entry_limbo_t *el = mi->mi_entry_limbo; 2559 1.1 lukem 2560 1.1 lukem for ( ; el; ) { 2561 1.1 lukem entry_limbo_t *tmp = el; 2562 1.1 lukem el = el->el_next; 2563 1.1 lukem monitor_back_destroy_limbo_entry( tmp, 1 ); 2564 1.1 lukem } 2565 1.1 lukem } 2566 1.1 lukem 2567 1.4 christos ldap_pvt_thread_mutex_destroy( &monitor_info.mi_cache_lock ); 2568 1.1 lukem 2569 1.1 lukem be->be_private = NULL; 2570 1.1 lukem 2571 1.1 lukem return 0; 2572 1.1 lukem } 2573