1 /* monitor.c - monitor ldap backend */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2003-2012 The OpenLDAP Foundation.
6 * Portions Copyright 1999-2003 Howard Chu.
7 * Portions Copyright 2000-2003 Pierangelo Masarati.
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted only as authorized by the OpenLDAP
14 * A copy of this license is available in the file LICENSE in the
15 * top-level directory of the distribution or, alternatively, at
16 * <http://www.OpenLDAP.org/license.html>.
19 * This work was initially developed by the Howard Chu for inclusion
20 * in OpenLDAP Software and subsequently enhanced by Pierangelo
27 #include <ac/string.h>
28 #include <ac/unistd.h>
29 #include <ac/stdlib.h>
33 #include "back-ldap.h"
37 static ObjectClass *oc_olmLDAPDatabase;
39 static AttributeDescription *ad_olmDbURIList;
42 * NOTE: there's some confusion in monitor OID arc;
43 * by now, let's consider:
45 * Subsystems monitor attributes 1.3.6.1.4.1.4203.666.1.55.0
46 * Databases monitor attributes 1.3.6.1.4.1.4203.666.1.55.0.1
47 * LDAP database monitor attributes 1.3.6.1.4.1.4203.666.1.55.0.1.2
49 * Subsystems monitor objectclasses 1.3.6.1.4.1.4203.666.3.16.0
50 * Databases monitor objectclasses 1.3.6.1.4.1.4203.666.3.16.0.1
51 * LDAP database monitor objectclasses 1.3.6.1.4.1.4203.666.3.16.0.1.2
58 { "olmLDAPAttributes", "olmDatabaseAttributes:2" },
59 { "olmLDAPObjectClasses", "olmDatabaseObjectClasses:2" },
66 AttributeDescription **ad;
68 { "( olmLDAPAttributes:1 "
69 "NAME ( 'olmDbURIList' ) "
70 "DESC 'List of URIs a proxy is serving; can be modified run-time' "
81 /* augments an existing object, so it must be AUXILIARY
82 * FIXME: derive from some ABSTRACT "monitoredEntity"? */
83 { "( olmLDAPObjectClasses:1 "
84 "NAME ( 'olmLDAPDatabase' ) "
89 &oc_olmLDAPDatabase },
95 ldap_back_monitor_update(
101 ldapinfo_t *li = (ldapinfo_t *)priv;
105 /* update olmDbURIList */
106 a = attr_find( e->e_attrs, ad_olmDbURIList );
110 assert( a->a_vals != NULL );
111 assert( !BER_BVISNULL( &a->a_vals[ 0 ] ) );
112 assert( BER_BVISNULL( &a->a_vals[ 1 ] ) );
114 ldap_pvt_thread_mutex_lock( &li->li_uri_mutex );
116 ber_str2bv( li->li_uri, 0, 0, &bv );
117 if ( !bvmatch( &a->a_vals[ 0 ], &bv ) ) {
118 ber_bvreplace( &a->a_vals[ 0 ], &bv );
121 ldap_pvt_thread_mutex_unlock( &li->li_uri_mutex );
124 return SLAP_CB_CONTINUE;
128 ldap_back_monitor_modify(
134 ldapinfo_t *li = (ldapinfo_t *) priv;
136 Attribute *save_attrs = NULL;
138 *ml_olmDbURIList = NULL;
139 struct berval ul = BER_BVNULL;
142 for ( ml = op->orm_modlist; ml; ml = ml->sml_next ) {
143 if ( ml->sml_desc == ad_olmDbURIList ) {
144 if ( ml_olmDbURIList != NULL ) {
145 rs->sr_err = LDAP_CONSTRAINT_VIOLATION;
146 rs->sr_text = "conflicting modifications";
150 if ( ml->sml_op != LDAP_MOD_REPLACE ) {
151 rs->sr_err = LDAP_CONSTRAINT_VIOLATION;
152 rs->sr_text = "modification not allowed";
156 ml_olmDbURIList = ml;
163 return SLAP_CB_CONTINUE;
166 save_attrs = attrs_dup( e->e_attrs );
168 if ( ml_olmDbURIList != NULL ) {
170 LDAPURLDesc *ludlist = NULL;
173 ml = ml_olmDbURIList;
174 assert( ml->sml_nvalues != NULL );
176 if ( BER_BVISNULL( &ml->sml_nvalues[ 0 ] ) ) {
177 rs->sr_err = LDAP_CONSTRAINT_VIOLATION;
178 rs->sr_text = "no value provided";
182 if ( !BER_BVISNULL( &ml->sml_nvalues[ 1 ] ) ) {
183 rs->sr_err = LDAP_CONSTRAINT_VIOLATION;
184 rs->sr_text = "multiple values provided";
188 rc = ldap_url_parselist_ext( &ludlist,
189 ml->sml_nvalues[ 0 ].bv_val, NULL,
190 LDAP_PVT_URL_PARSE_NOEMPTY_HOST
191 | LDAP_PVT_URL_PARSE_DEF_PORT );
192 if ( rc != LDAP_URL_SUCCESS ) {
193 rs->sr_err = LDAP_INVALID_SYNTAX;
194 rs->sr_text = "unable to parse URI list";
198 ul.bv_val = ldap_url_list2urls( ludlist );
199 ldap_free_urllist( ludlist );
200 if ( ul.bv_val == NULL ) {
201 rs->sr_err = LDAP_OTHER;
204 ul.bv_len = strlen( ul.bv_val );
206 a = attr_find( e->e_attrs, ad_olmDbURIList );
208 if ( a->a_nvals == a->a_vals ) {
209 a->a_nvals = ch_calloc( sizeof( struct berval ), 2 );
212 ber_bvreplace( &a->a_vals[ 0 ], &ul );
213 ber_bvreplace( &a->a_nvals[ 0 ], &ul );
216 attr_merge_normalize_one( e, ad_olmDbURIList, &ul, NULL );
221 if ( !BER_BVISNULL( &ul ) ) {
222 ldap_pvt_thread_mutex_lock( &li->li_uri_mutex );
224 ch_free( li->li_uri );
226 li->li_uri = ul.bv_val;
227 ldap_pvt_thread_mutex_unlock( &li->li_uri_mutex );
233 if ( !BER_BVISNULL( &ul ) ) {
234 ldap_memfree( ul.bv_val );
237 if ( rs->sr_err == LDAP_SUCCESS ) {
238 attrs_free( save_attrs );
239 return SLAP_CB_CONTINUE;
242 attrs_free( e->e_attrs );
243 e->e_attrs = save_attrs;
249 ldap_back_monitor_free(
253 ldapinfo_t *li = (ldapinfo_t *)(*priv);
257 if ( !slapd_shutdown ) {
258 memset( &li->li_monitor_info, 0, sizeof( li->li_monitor_info ) );
261 return SLAP_CB_CONTINUE;
265 ldap_back_monitor_conn_create(
272 monitor_entry_t *mp_parent;
273 ldap_monitor_info_t *lmi;
276 assert( e_parent->e_private != NULL );
278 mp_parent = e_parent->e_private;
279 lmi = (ldap_monitor_info_t *)mp_parent->mp_info;
282 /* do the hard work! */
288 * call from within ldap_back_initialize()
291 ldap_back_monitor_initialize( void )
297 static int ldap_back_monitor_initialized = 0;
299 /* set to 0 when successfully initialized; otherwise, remember failure */
300 static int ldap_back_monitor_initialized_failure = 1;
302 /* register schema here; if compiled as dynamic object,
303 * must be loaded __after__ back_monitor.la */
305 if ( ldap_back_monitor_initialized++ ) {
306 return ldap_back_monitor_initialized_failure;
309 if ( backend_info( "monitor" ) == NULL ) {
313 argv[ 0 ] = "back-ldap monitor";
317 for ( i = 0; s_oid[ i ].name; i++ ) {
319 argv[ 1 ] = s_oid[ i ].name;
320 argv[ 2 ] = s_oid[ i ].oid;
322 if ( parse_oidm( &c, 0, NULL ) != 0 ) {
323 Debug( LDAP_DEBUG_ANY,
324 "ldap_back_monitor_initialize: unable to add "
325 "objectIdentifier \"%s=%s\"\n",
326 s_oid[ i ].name, s_oid[ i ].oid, 0 );
331 for ( i = 0; s_at[ i ].desc != NULL; i++ ) {
332 code = register_at( s_at[ i ].desc, s_at[ i ].ad, 1 );
333 if ( code != LDAP_SUCCESS ) {
334 Debug( LDAP_DEBUG_ANY,
335 "ldap_back_monitor_initialize: register_at failed for attributeType (%s)\n",
336 s_at[ i ].desc, 0, 0 );
340 (*s_at[ i ].ad)->ad_type->sat_flags |= SLAP_AT_HIDE;
344 for ( i = 0; s_oc[ i ].desc != NULL; i++ ) {
345 code = register_oc( s_oc[ i ].desc, s_oc[ i ].oc, 1 );
346 if ( code != LDAP_SUCCESS ) {
347 Debug( LDAP_DEBUG_ANY,
348 "ldap_back_monitor_initialize: register_oc failed for objectClass (%s)\n",
349 s_oc[ i ].desc, 0, 0 );
353 (*s_oc[ i ].oc)->soc_flags |= SLAP_OC_HIDE;
357 return ( ldap_back_monitor_initialized_failure = LDAP_SUCCESS );
361 * call from within ldap_back_db_init()
364 ldap_back_monitor_db_init( BackendDB *be )
368 rc = ldap_back_monitor_initialize();
369 if ( rc != LDAP_SUCCESS ) {
373 #if 0 /* uncomment to turn monitoring on by default */
374 SLAP_DBFLAGS( be ) |= SLAP_DBFLAG_MONITORING;
381 * call from within ldap_back_db_open()
384 ldap_back_monitor_db_open( BackendDB *be )
386 ldapinfo_t *li = (ldapinfo_t *) be->be_private;
389 monitor_extra_t *mbe;
391 if ( !SLAP_DBMONITORING( be ) ) {
395 /* check if monitor is configured and usable */
396 mi = backend_info( "monitor" );
397 if ( !mi || !mi->bi_extra ) {
398 SLAP_DBFLAGS( be ) ^= SLAP_DBFLAG_MONITORING;
403 /* don't bother if monitor is not configured */
404 if ( !mbe->is_configured() ) {
405 static int warning = 0;
407 if ( warning++ == 0 ) {
408 Debug( LDAP_DEBUG_ANY, "ldap_back_monitor_db_open: "
409 "monitoring disabled; "
410 "configure monitor database to enable\n",
417 /* caller (e.g. an overlay based on back-ldap) may want to use
418 * a different DN and RDNs... */
419 if ( BER_BVISNULL( &li->li_monitor_info.lmi_ndn ) ) {
420 rc = mbe->register_database( be, &li->li_monitor_info.lmi_ndn );
422 Debug( LDAP_DEBUG_ANY, "ldap_back_monitor_db_open: "
423 "failed to register the databse with back-monitor\n",
427 if ( BER_BVISNULL( &li->li_monitor_info.lmi_conn_rdn ) ) {
428 ber_str2bv( "cn=Connections", 0, 1,
429 &li->li_monitor_info.lmi_conn_rdn );
431 if ( BER_BVISNULL( &li->li_monitor_info.lmi_ops_rdn ) ) {
432 ber_str2bv( "cn=Operations", 0, 1,
433 &li->li_monitor_info.lmi_ops_rdn );
440 * call from within ldap_back_db_close()
443 ldap_back_monitor_db_close( BackendDB *be )
445 ldapinfo_t *li = (ldapinfo_t *) be->be_private;
447 if ( li && !BER_BVISNULL( &li->li_monitor_info.lmi_ndn ) ) {
449 monitor_extra_t *mbe;
451 /* check if monitor is configured and usable */
452 mi = backend_info( "monitor" );
453 if ( mi && mi->bi_extra ) {
457 * Unregister all entries our subsystems have created.
458 * Will only really be necessary when
459 * SLAPD_CONFIG_DELETE is enabled.
461 * Might need a way to unregister subsystems instead.
470 * call from within ldap_back_db_destroy()
473 ldap_back_monitor_db_destroy( BackendDB *be )
475 ldapinfo_t *li = (ldapinfo_t *) be->be_private;
478 memset( &li->li_monitor_info, 0, sizeof( li->li_monitor_info ) );