]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/back-monitor/init.c
cleanup subsystems monitoring OID handling
[openldap] / servers / slapd / back-monitor / init.c
index 736a6cfdb9e76750385e69891e38720f622117e6..6aa67d54f4b18435b8a5aeee46103997e80445f8 100644 (file)
@@ -437,7 +437,7 @@ monitor_back_register_entry_parent(
                        "monitor_back_register_entry_parent(base=\"%s\" scope=%s filter=\"%s\"): "
                        "monitor database not configured.\n",
                        BER_BVISNULL( base ) ? "" : base->bv_val,
-                       scope == LDAP_SCOPE_BASE ? "base" : ( scope == LDAP_SCOPE_ONELEVEL ? "one" : "subtree" ),
+                       ldap_pvt_scope2str( scope ),
                        BER_BVISNULL( filter ) ? "" : filter->bv_val );
                return -1;
        }
@@ -471,7 +471,7 @@ monitor_back_register_entry_parent(
                        /* entry does not exist */
                        Debug( LDAP_DEBUG_ANY,
                                "monitor_back_register_entry_parent(\"\"): "
-                               "base=%s scope=%d filter=%s : "
+                               "base=\"%s\" scope=%d filter=\"%s\": "
                                "unable to find entry\n",
                                base->bv_val ? base->bv_val : "\"\"",
                                scope, filter->bv_val );
@@ -685,8 +685,12 @@ monitor_filter2ndn(
        cb.sc_private = (void *)ndn;
 
        op->ors_scope = scope;
-       ber_dupbv_x( &op->ors_filterstr, filter, op->o_tmpmemctx );
        op->ors_filter = str2filter_x( op, filter->bv_val );
+       if ( op->ors_filter == NULL ) {
+               rc = LDAP_OTHER;
+               goto cleanup;
+       }
+       ber_dupbv_x( &op->ors_filterstr, filter, op->o_tmpmemctx );
        op->ors_attrs = slap_anlist_no_attrs;
        op->ors_attrsonly = 0;
        op->ors_tlimit = SLAP_NO_LIMIT;
@@ -702,10 +706,19 @@ monitor_filter2ndn(
 
        rc = op->o_bd->be_search( op, &rs );
 
-       filter_free_x( op, op->ors_filter );
-       op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
-       op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
-       op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
+cleanup:;
+       if ( op->ors_filter != NULL ) {
+               filter_free_x( op, op->ors_filter );
+       }
+       if ( !BER_BVISNULL( &op->ors_filterstr ) ) {
+               op->o_tmpfree( op->ors_filterstr.bv_val, op->o_tmpmemctx );
+       }
+       if ( !BER_BVISNULL( &op->o_req_dn ) ) {
+               op->o_tmpfree( op->o_req_dn.bv_val, op->o_tmpmemctx );
+       }
+       if ( !BER_BVISNULL( &op->o_req_ndn ) ) {
+               op->o_tmpfree( op->o_req_ndn.bv_val, op->o_tmpmemctx );
+       }
 
        if ( rc != 0 ) {
                return rc;
@@ -752,7 +765,7 @@ monitor_back_register_entry_attrs(
                        "monitor database not configured.\n",
                        fname,
                        BER_BVISNULL( base ) ? "" : base->bv_val,
-                       scope == LDAP_SCOPE_BASE ? "base" : ( scope == LDAP_SCOPE_ONELEVEL ? "one" : "subtree" ),
+                       ldap_pvt_scope2str( scope ),
                        BER_BVISNULL( filter ) ? "" : filter->bv_val );
                Debug( LDAP_DEBUG_ANY, "%s\n", buf, 0, 0 );
 
@@ -797,7 +810,7 @@ monitor_back_register_entry_attrs(
 
                                snprintf( buf, sizeof( buf ),
                                        "monitor_back_register_entry_%s(\"\"): "
-                                       "base=%s scope=%d filter=%s : "
+                                       "base=\"%s\" scope=%d filter=\"%s\": "
                                        "unable to find entry\n",
                                        fname,
                                        base->bv_val ? base->bv_val : "\"\"",
@@ -838,14 +851,26 @@ monitor_back_register_entry_attrs(
                        for ( atp = &e->e_attrs; *atp; atp = &(*atp)->a_next )
                                /* just get to last */ ;
 
-                       *atp = attrs_dup( a );
-                       if ( *atp == NULL ) {
-                               Debug( LDAP_DEBUG_ANY,
-                                       "monitor_back_register_entry_%s(\"%s\"): "
-                                       "attrs_dup() failed\n",
-                                       fname, e->e_name.bv_val, 0 );
-                               rc = -1;
-                               goto done;
+                       for ( ; a != NULL; a = a->a_next ) {
+                               assert( a->a_desc != NULL );
+                               assert( a->a_vals != NULL );
+
+                               if ( attr_find( e->e_attrs, a->a_desc ) ) {
+                                       attr_merge( e, a->a_desc, a->a_vals,
+                                               a->a_nvals == a->a_vals ? NULL : a->a_nvals );
+
+                               } else {
+                                       *atp = attr_dup( a );
+                                       if ( *atp == NULL ) {
+                                               Debug( LDAP_DEBUG_ANY,
+                                                       "monitor_back_register_entry_%s(\"%s\"): "
+                                                       "attr_dup() failed\n",
+                                                       fname, e->e_name.bv_val, 0 );
+                                               rc = -1;
+                                               goto done;
+                                       }
+                                       atp = &(*atp)->a_next;
+                               }
                        }
                }
 
@@ -860,7 +885,7 @@ monitor_back_register_entry_attrs(
 
 done:;
                if ( rc ) {
-                       if ( *atp ) {
+                       if ( atp && *atp ) {
                                attrs_free( *atp );
                                *atp = NULL;
                        }
@@ -923,6 +948,219 @@ monitor_back_register_entry_callback(
                        base, scope, filter );
 }
 
+/*
+ * TODO: add corresponding calls to remove installed callbacks, entries
+ * and so, in case the entity that installed them is removed (e.g. a 
+ * database, via back-config)
+ */
+int
+monitor_back_unregister_entry(
+       Entry                   *target_e )
+{
+       monitor_info_t  *mi;
+
+       if ( be_monitor == NULL ) {
+               Debug( LDAP_DEBUG_ANY,
+                       "monitor_back_unregister_entry(\"%s\"): "
+                       "monitor database not configured.\n",
+                       target_e->e_name.bv_val, 0, 0 );
+
+               return -1;
+       }
+
+       mi = ( monitor_info_t * )be_monitor->be_private;
+
+       assert( mi != NULL );
+
+       if ( monitor_subsys_opened ) {
+               Entry                   *e = NULL;
+               monitor_entry_t         *mp = NULL;
+               monitor_callback_t      *cb = NULL;
+
+               if ( monitor_cache_remove( mi, &target_e->e_nname, &e ) != 0 ) {
+                       /* entry does not exist */
+                       Debug( LDAP_DEBUG_ANY,
+                               "monitor_back_unregister_entry(\"%s\"): "
+                               "entry removal failed.\n",
+                               target_e->e_name.bv_val, 0, 0 );
+                       return -1;
+               }
+
+               mp = (monitor_entry_t *)e->e_private;
+               assert( mp != NULL );
+
+               for ( cb = mp->mp_cb; cb != NULL; ) {
+                       monitor_callback_t      *next = cb->mc_next;
+
+                       if ( cb->mc_free ) {
+                               (void)cb->mc_free( e, cb->mc_private );
+                       }
+                       ch_free( cb );
+
+                       cb = next;
+               }
+
+       } else {
+               /* TODO: remove from limbo */
+               return 1;
+       }
+
+       return 0;
+}
+
+int
+monitor_back_unregister_entry_attrs(
+       struct berval           *ndn_in,
+       Attribute               *target_a,
+       monitor_callback_t      *target_cb,
+       struct berval           *base,
+       int                     scope,
+       struct berval           *filter )
+{
+       monitor_info_t  *mi;
+       struct berval   ndn = BER_BVNULL;
+       char            *fname = ( target_a == NULL ? "callback" : "attrs" );
+
+       if ( be_monitor == NULL ) {
+               char            buf[ SLAP_TEXT_BUFLEN ];
+
+               snprintf( buf, sizeof( buf ),
+                       "monitor_back_unregister_entry_%s(base=\"%s\" scope=%s filter=\"%s\"): "
+                       "monitor database not configured.\n",
+                       fname,
+                       BER_BVISNULL( base ) ? "" : base->bv_val,
+                       (char *)ldap_pvt_scope2str( scope ),
+                       BER_BVISNULL( filter ) ? "" : filter->bv_val );
+               Debug( LDAP_DEBUG_ANY, "%s\n", buf, 0, 0 );
+
+               return -1;
+       }
+
+       mi = ( monitor_info_t * )be_monitor->be_private;
+
+       assert( mi != NULL );
+
+       if ( ndn_in != NULL ) {
+               ndn = *ndn_in;
+       }
+
+       if ( target_a == NULL && target_cb == NULL ) {
+               /* nothing to do */
+               return -1;
+       }
+
+       if ( ( ndn_in == NULL || BER_BVISNULL( &ndn ) )
+                       && BER_BVISNULL( filter ) )
+       {
+               /* need a filter */
+               Debug( LDAP_DEBUG_ANY,
+                       "monitor_back_unregister_entry_%s(\"\"): "
+                       "need a valid filter\n",
+                       fname, 0, 0 );
+               return -1;
+       }
+
+       if ( monitor_subsys_opened ) {
+               Entry                   *e = NULL;
+               monitor_entry_t         *mp = NULL;
+               int                     freeit = 0;
+
+               if ( BER_BVISNULL( &ndn ) ) {
+                       if ( monitor_filter2ndn( base, scope, filter, &ndn ) ) {
+                               char            buf[ SLAP_TEXT_BUFLEN ];
+
+                               snprintf( buf, sizeof( buf ),
+                                       "monitor_back_unregister_entry_%s(\"\"): "
+                                       "base=\"%s\" scope=%d filter=\"%s\": "
+                                       "unable to find entry\n",
+                                       fname,
+                                       base->bv_val ? base->bv_val : "\"\"",
+                                       scope, filter->bv_val );
+
+                               /* entry does not exist */
+                               Debug( LDAP_DEBUG_ANY, "%s\n", buf, 0, 0 );
+                               return -1;
+                       }
+
+                       freeit = 1;
+               }
+
+               if ( monitor_cache_get( mi, &ndn, &e ) != 0 ) {
+                       /* entry does not exist */
+                       Debug( LDAP_DEBUG_ANY,
+                               "monitor_back_unregister_entry(\"%s\"): "
+                               "entry removal failed.\n",
+                               ndn.bv_val, 0, 0 );
+                       return -1;
+               }
+
+               mp = (monitor_entry_t *)e->e_private;
+               assert( mp != NULL );
+
+               if ( target_cb != NULL ) {
+                       monitor_callback_t      **cbp;
+
+                       for ( cbp = &mp->mp_cb; *cbp != NULL; cbp = &(*cbp)->mc_next ) {
+                               if ( *cbp == target_cb ) {
+                                       if ( (*cbp)->mc_free ) {
+                                               (void)(*cbp)->mc_free( e, (*cbp)->mc_private );
+                                       }
+                                       *cbp = (*cbp)->mc_next;
+                                       ch_free( target_cb );
+                                       break;
+                               }
+                       }
+               }
+
+               if ( target_a != NULL ) {
+                       Attribute       *a;
+
+                       for ( a = target_a; a != NULL; a = a->a_next ) {
+                               Modification    mod = { 0 };
+                               const char      *text;
+                               char            textbuf[ SLAP_TEXT_BUFLEN ];
+
+                               mod.sm_op = LDAP_MOD_DELETE;
+                               mod.sm_desc = a->a_desc;
+                               mod.sm_values = a->a_vals;
+                               mod.sm_nvalues = a->a_nvals;
+
+                               (void)modify_delete_values( e, &mod, 1,
+                                       &text, textbuf, sizeof( textbuf ) );
+                       }
+               }
+
+               if ( freeit ) {
+                       ber_memfree( ndn.bv_val );
+               }
+
+               if ( e ) {
+                       monitor_cache_release( mi, e );
+               }
+
+       } else {
+               /* TODO: remove from limbo */
+               return 1;
+       }
+
+       return 0;
+}
+
+int
+monitor_back_unregister_entry_callback(
+       struct berval           *ndn,
+       monitor_callback_t      *cb,
+       struct berval           *base,
+       int                     scope,
+       struct berval           *filter )
+{
+       /* TODO: lookup entry (by ndn, if not NULL, and/or by callback);
+        * unregister the callback; if a is not null, unregister the
+        * given attrs.  In any case, call cb->cb_free */
+       return monitor_back_unregister_entry_attrs( ndn,
+               NULL, cb, base, scope, filter );
+}
+
 monitor_subsys_t *
 monitor_back_get_subsys( const char *name )
 {
@@ -1264,10 +1502,55 @@ monitor_back_initialize(
                { NULL, NULL, 0, -1 }
        };
 
+       static struct {
+               char                    *name;
+               char                    *oid;
+       }               s_oid[] = {
+               { "olmAttributes",                      "1.3.6.1.4.1.4203.666.1.55" },
+               { "olmSubSystemAttributes",             "olmAttributes:0" },
+               { "olmGenericAttributes",               "olmSubSystemAttributes:0" },
+               { "olmDatabaseAttributes",              "olmSubSystemAttributes:1" },
+
+               /* for example, back-bdb specific attrs
+                * are in "olmDatabaseAttributes:1"
+                *
+                * NOTE: developers, please record here OID assignments
+                * for other modules */
+
+               { "olmObjectClasses",                   "1.3.6.1.4.1.4203.666.3.16" },
+               { "olmSubSystemObjectClasses",          "olmObjectClasses:0" },
+               { "olmGenericObjectClasses",            "olmSubSystemObjectClasses:0" },
+               { "olmDatabaseObjectClasses",           "olmSubSystemObjectClasses:1" },
+
+               /* for example, back-bdb specific objectClasses
+                * are in "olmDatabaseObjectClasses:1"
+                *
+                * NOTE: developers, please record here OID assignments
+                * for other modules */
+
+               { NULL }
+       };
+
        int                     i, rc;
        const char              *text;
        monitor_info_t          *mi = &monitor_info;
 
+       for ( i = 0; s_oid[ i ].name; i++ ) {
+               char    *argv[ 3 ];
+       
+               argv[ 0 ] = "monitor";
+               argv[ 1 ] = s_oid[ i ].name;
+               argv[ 2 ] = s_oid[ i ].oid;
+
+               if ( parse_oidm( argv[ 0 ], i, 3, argv, 0, NULL ) != 0 ) {
+                       Debug( LDAP_DEBUG_ANY,
+                               "monitor_back_initialize: unable to add "
+                               "objectIdentifier \"%s=%s\"\n",
+                               s_oid[ i ].name, s_oid[ i ].oid, 0 );
+                       return 1;
+               }
+       }
+
        /* schema integration */
        for ( i = 0; mat[ i ].name; i++ ) {
                LDAPAttributeType       *at;
@@ -1285,6 +1568,7 @@ monitor_back_initialize(
                }
 
                if ( at->at_oid == NULL ) {
+                       ldap_attributetype_free(at);
                        Debug( LDAP_DEBUG_ANY, "monitor_back_db_init: "
                                "null OID for attributeType \"%s\"\n",
                                mat[ i ].name, 0, 0 );
@@ -1293,6 +1577,7 @@ monitor_back_initialize(
 
                code = at_add(at, 0, NULL, &err);
                if ( code ) {
+                       ldap_attributetype_free(at);
                        Debug( LDAP_DEBUG_ANY, "monitor_back_db_init: "
                                "%s in attributeType \"%s\"\n",
                                scherr2str(code), mat[ i ].name, 0 );
@@ -1328,6 +1613,7 @@ monitor_back_initialize(
                }
 
                if ( oc->oc_oid == NULL ) {
+                       ldap_objectclass_free(oc);
                        Debug( LDAP_DEBUG_ANY,
                                "objectclass \"%s\" has no OID\n" ,
                                moc[ i ].name, 0, 0 );
@@ -1336,12 +1622,12 @@ monitor_back_initialize(
 
                code = oc_add(oc, 0, NULL, &err);
                if ( code ) {
+                       ldap_objectclass_free(oc);
                        Debug( LDAP_DEBUG_ANY,
                                "objectclass \"%s\": %s \"%s\"\n" ,
                                moc[ i ].name, scherr2str(code), err );
                        return -1;
                }
-
                ldap_memfree(oc);
 
                Oc = oc_find( moc[ i ].name );
@@ -1496,16 +1782,21 @@ monitor_back_db_open(
 {
        monitor_info_t          *mi = (monitor_info_t *)be->be_private;
        struct monitor_subsys_t **ms;
-       Entry                   *e, **ep;
+       Entry                   *e, **ep, *root;
        monitor_entry_t         *mp;
        int                     i;
-       char                    buf[ BACKMONITOR_BUFSIZE ];
-       struct berval           bv;
+       struct berval           bv, rdn = BER_BVC(SLAPD_MONITOR_DN);
        struct tm               *tms;
 #ifdef HAVE_GMTIME_R
        struct tm               tm_buf;
 #endif
        static char             tmbuf[ LDAP_LUTIL_GENTIME_BUFSIZE ];
+       struct berval   desc[] = {
+               BER_BVC("This subtree contains monitoring/managing objects."),
+               BER_BVC("This object contains information about this server."),
+               BER_BVC("Most of the information is held in operational"
+               " attributes, which must be explicitly requested."),
+               BER_BVNULL };
 
        assert( be_monitor != NULL );
        if ( be != be_monitor ) {
@@ -1542,35 +1833,18 @@ monitor_back_db_open(
 
        if ( BER_BVISEMPTY( &be->be_rootdn ) ) {
                BER_BVSTR( &mi->mi_creatorsName, SLAPD_ANONYMOUS );
+               BER_BVSTR( &mi->mi_ncreatorsName, SLAPD_ANONYMOUS );
        } else {
                mi->mi_creatorsName = be->be_rootdn;
+               mi->mi_ncreatorsName = be->be_rootndn;
        }
 
        /*
         * creates the "cn=Monitor" entry 
         */
-       snprintf( buf, sizeof( buf ), 
-               "dn: %s\n"
-               "objectClass: %s\n"
-               "structuralObjectClass: %s\n"
-               "cn: Monitor\n"
-               "description: This subtree contains monitoring/managing objects.\n"
-               "description: This object contains information about this server.\n"
-               "description: Most of the information is held in operational"
-               " attributes, which must be explicitly requested.\n"
-               "creatorsName: %s\n"
-               "modifiersName: %s\n"
-               "createTimestamp: %s\n"
-               "modifyTimestamp: %s\n",
-               SLAPD_MONITOR_DN,
-               mi->mi_oc_monitorServer->soc_cname.bv_val,
-               mi->mi_oc_monitorServer->soc_cname.bv_val,
-               mi->mi_creatorsName.bv_val,
-               mi->mi_creatorsName.bv_val,
-               mi->mi_startTime.bv_val,
-               mi->mi_startTime.bv_val );
-
-       e = str2entry( buf );
+       e = monitor_entry_stub( NULL, NULL, &rdn, mi->mi_oc_monitorServer, mi,
+               NULL, NULL );
+
        if ( e == NULL) {
                Debug( LDAP_DEBUG_ANY,
                        "unable to create \"%s\" entry\n",
@@ -1578,6 +1852,8 @@ monitor_back_db_open(
                return( -1 );
        }
 
+       attr_merge_normalize( e, slap_schema.si_ad_description, desc, NULL );
+
        bv.bv_val = strchr( (char *) Versionstr, '$' );
        if ( bv.bv_val != NULL ) {
                char    *end;
@@ -1623,6 +1899,7 @@ monitor_back_db_open(
                        SLAPD_MONITOR_DN, 0, 0 );
                return -1;
        }
+       root = e;
 
        /*      
         * Create all the subsystem specific entries
@@ -1645,46 +1922,18 @@ monitor_back_db_open(
                        return( -1 );
                }
 
-               dn.bv_len += sizeof( SLAPD_MONITOR_DN ); /* 1 for the , */
-               dn.bv_val = ch_malloc( dn.bv_len + 1 );
-               strcpy( dn.bv_val , monitor_subsys[ i ]->mss_rdn.bv_val );
-               strcat( dn.bv_val, "," SLAPD_MONITOR_DN );
-               rc = dnPrettyNormal( NULL, &dn, &monitor_subsys[ i ]->mss_dn,
-                       &monitor_subsys[ i ]->mss_ndn, NULL );
-               free( dn.bv_val );
-               if ( rc != LDAP_SUCCESS ) {
-                       Debug( LDAP_DEBUG_ANY,
-                               "monitor DN \"%s\" is invalid\n", 
-                               dn.bv_val, 0, 0 );
-                       return( -1 );
-               }
+               e = monitor_entry_stub( &root->e_name, &root->e_nname,
+                       &monitor_subsys[ i ]->mss_rdn, mi->mi_oc_monitorContainer, mi,
+                       NULL, NULL );
 
-               snprintf( buf, sizeof( buf ),
-                               "dn: %s\n"
-                               "objectClass: %s\n"
-                               "structuralObjectClass: %s\n"
-                               "cn: %s\n"
-                               "creatorsName: %s\n"
-                               "modifiersName: %s\n"
-                               "createTimestamp: %s\n"
-                               "modifyTimestamp: %s\n",
-                               monitor_subsys[ i ]->mss_dn.bv_val,
-                               mi->mi_oc_monitorContainer->soc_cname.bv_val,
-                               mi->mi_oc_monitorContainer->soc_cname.bv_val,
-                               monitor_subsys[ i ]->mss_name,
-                               mi->mi_creatorsName.bv_val,
-                               mi->mi_creatorsName.bv_val,
-                               mi->mi_startTime.bv_val,
-                               mi->mi_startTime.bv_val );
-               
-               e = str2entry( buf );
-               
                if ( e == NULL) {
                        Debug( LDAP_DEBUG_ANY,
                                "unable to create \"%s\" entry\n", 
                                monitor_subsys[ i ]->mss_dn.bv_val, 0, 0 );
                        return( -1 );
                }
+               monitor_subsys[i]->mss_dn = e->e_name;
+               monitor_subsys[i]->mss_ndn = e->e_nname;
 
                if ( !BER_BVISNULL( &monitor_subsys[ i ]->mss_desc[ 0 ] ) ) {
                        attr_merge_normalize( e, slap_schema.si_ad_description,
@@ -1860,14 +2109,6 @@ monitor_back_db_destroy(
                        if ( !BER_BVISNULL( &monitor_subsys[ i ]->mss_rdn ) ) {
                                ch_free( monitor_subsys[ i ]->mss_rdn.bv_val );
                        }
-
-                       if ( !BER_BVISNULL( &monitor_subsys[ i ]->mss_dn ) ) {
-                               ch_free( monitor_subsys[ i ]->mss_dn.bv_val );
-                       }
-
-                       if ( !BER_BVISNULL( &monitor_subsys[ i ]->mss_ndn ) ) {
-                               ch_free( monitor_subsys[ i ]->mss_ndn.bv_val );
-                       }
                }
 
                ch_free( monitor_subsys );