]> git.sur5r.net Git - openldap/commitdiff
Added readOnly attribute, can be toggled on individual databases.
authorHoward Chu <hyc@openldap.org>
Tue, 27 Apr 2004 01:56:38 +0000 (01:56 +0000)
committerHoward Chu <hyc@openldap.org>
Tue, 27 Apr 2004 01:56:38 +0000 (01:56 +0000)
servers/slapd/back-monitor/back-monitor.h
servers/slapd/back-monitor/database.c
servers/slapd/back-monitor/init.c
servers/slapd/back-monitor/proto-back-monitor.h

index cddd899abc4ec5b9ebc7aa0713e959d72cc61896..e9e8df1006c220fef76a5f95f7d6a62c70048561 100644 (file)
@@ -103,6 +103,7 @@ struct monitorinfo {
        AttributeDescription *mi_ad_seeAlso;
        AttributeDescription *mi_ad_l;
        AttributeDescription *mi_ad_labeledURI;
+       AttributeDescription *mi_ad_readOnly;
 };
 
 /*
index 7191e5479b43efefe69d745a31faafa5d8bdc504..b754376c334685c424bf284831f7f5b2525cae9e 100644 (file)
@@ -45,6 +45,7 @@ monitor_subsys_database_init(
        Entry                   *e, *e_database, *e_tmp;
        int                     i;
        struct monitorentrypriv *mp;
+       struct berval *tf;
 
        assert( be != NULL );
 
@@ -67,6 +68,9 @@ monitor_subsys_database_init(
 #endif
                return( -1 );
        }
+       tf = (global_restrictops & SLAP_RESTRICT_OP_WRITES) ?
+               (struct berval *)&slap_true_bv : (struct berval *)&slap_false_bv ; 
+       attr_merge_one( e_database, mi->mi_ad_readOnly, tf, tf );
 
        e_tmp = NULL;
        for ( i = nBackendDB; i--; ) {
@@ -137,6 +141,9 @@ monitor_subsys_database_init(
                        attr_merge( e_database, slap_schema.si_ad_namingContexts,
                                        be->be_suffix, be->be_nsuffix );
                }
+               tf = (be->be_restrictops & SLAP_RESTRICT_OP_WRITES) ?
+                       (struct berval *)&slap_true_bv : (struct berval *)&slap_false_bv ; 
+               attr_merge_one( e, mi->mi_ad_readOnly, tf, tf );
 
                if ( oi != NULL ) {
                        slap_overinst *on = oi->oi_list;
@@ -236,6 +243,120 @@ monitor_subsys_database_init(
        return( 0 );
 }
 
+int
+monitor_subsys_database_modify(
+       Operation       *op,
+       Entry           *e
+)
+{
+       struct monitorinfo *mi = (struct monitorinfo *)op->o_bd->be_private;
+       int rc = LDAP_OTHER;
+       Attribute *save_attrs;
+       Modifications *modlist = op->oq_modify.rs_modlist;
+       Modifications *ml;
+       Backend *be;
+       int gotval = 1, i, n, cur;
+       
+       i = sscanf( e->e_nname.bv_val, "cn=database %d,", &n );
+       if ( i != 1 )
+               return LDAP_UNWILLING_TO_PERFORM;
+
+       if ( n < 0 || n >= nBackendDB )
+               return LDAP_NO_SUCH_OBJECT;
+
+       be = &backendDB[n];
+       cur = (be->be_restrictops & SLAP_RESTRICT_OP_WRITES) ? 1 : 0;
+
+       save_attrs = e->e_attrs;
+       e->e_attrs = attrs_dup( e->e_attrs );
+
+       for ( ml=modlist; ml; ml=ml->sml_next ) {
+               Modification *mod = &ml->sml_mod;
+
+               if ( mod->sm_desc == mi->mi_ad_readOnly ) {
+                       int val = -1;
+
+                       if ( mod->sm_values ) {
+                               /* single-valued */
+                               if ( !BER_BVISNULL(&mod->sm_values[1]) ) {
+                                       rc = LDAP_CONSTRAINT_VIOLATION;
+                                       break;
+                               }
+                               if ( bvmatch( &slap_true_bv, mod->sm_values )) {
+                                       val = 1;
+                               } else if ( bvmatch( &slap_false_bv, mod->sm_values )) {
+                                       val = 0;
+                               }
+                       }
+                       switch( mod->sm_op ) {
+                       case LDAP_MOD_DELETE:
+                               if ( val < 0 || val == cur ) {
+                                       gotval--;
+                                       cur = -1;
+                               } else {
+                                       rc = LDAP_NO_SUCH_ATTRIBUTE;
+                               }
+                               break;
+                       case LDAP_MOD_REPLACE:
+                               gotval--;
+                               cur = -1;
+                               /* FALLTHRU */
+                       case LDAP_MOD_ADD:
+                               if ( val < 0 ) {
+                                       rc = LDAP_INVALID_SYNTAX;
+                               } else {
+                                       gotval++;
+                                       cur = val;
+                               }
+                               break;
+                       default:
+                               rc = LDAP_OTHER;
+                               break;
+                       }
+                       if ( rc ) {
+                               break;
+                       }
+               } else if ( is_at_operational( mod->sm_desc->ad_type )) {
+               /* accept all operational attributes */
+                       attr_delete( &e->e_attrs, mod->sm_desc );
+                       rc = attr_merge( e, mod->sm_desc, mod->sm_values,
+                               mod->sm_nvalues );
+                       if ( rc ) {
+                               rc = LDAP_OTHER;
+                               break;
+                       }
+               } else {
+                       rc = LDAP_UNWILLING_TO_PERFORM;
+                       break;
+               }
+       }
+       if ( gotval == 1 && cur >= 0 ) {
+               struct berval *tf;
+               tf = cur ? (struct berval *)&slap_true_bv : (struct berval *)&slap_false_bv;
+               attr_delete( &e->e_attrs, mi->mi_ad_readOnly );
+               rc = attr_merge_one( e, mi->mi_ad_readOnly, tf, tf );
+               if ( rc == LDAP_SUCCESS ) {
+                       if ( cur ) {
+                               be->be_restrictops |= SLAP_RESTRICT_OP_WRITES;
+                       } else {
+                               be->be_restrictops &= ~SLAP_RESTRICT_OP_WRITES;
+                       }
+               } else {
+                       rc = LDAP_OTHER;
+               }
+       } else {
+               rc = LDAP_CONSTRAINT_VIOLATION;
+       }
+       if ( rc == LDAP_SUCCESS ) {
+               attrs_free( save_attrs );
+       } else {
+               Attribute *tmp = e->e_attrs;
+               e->e_attrs = save_attrs;
+               attrs_free( tmp );
+       }
+       return rc;
+}
+
 #if defined(LDAP_SLAPI)
 static int
 monitor_back_add_plugin( Backend *be, Entry *e_database )
index 6173c12949a43fa90a258415105a776ffc32eed1..5ed5b01bb31713623cd04bd5ddb7871b11887a8f 100644 (file)
@@ -55,7 +55,7 @@ struct monitorsubsys monitor_subsys[] = {
                monitor_subsys_database_init,
                NULL,   /* update */
                NULL,   /* create */
-               NULL    /* modify */
+               monitor_subsys_database_modify
                }, { 
                SLAPD_MONITOR_BACKEND, SLAPD_MONITOR_BACKEND_NAME, 
                BER_BVNULL, BER_BVNULL, BER_BVNULL,
@@ -457,6 +457,14 @@ monitor_back_db_open(
                        "NO-USER-MODIFICATION "
                        "USAGE directoryOperation )", SLAP_AT_HIDE,
                        offsetof(struct monitorinfo, mi_ad_monitorOverlay) },
+               { "readOnly", "( 1.3.6.1.4.1.4203.666.1.31 "
+                       "NAME 'readOnly' "
+                       "DESC 'read/write status of a given database' "
+                       "EQUALITY booleanMatch "
+                       "SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 "
+                       "SINGLE-VALUE "
+                       "USAGE directoryOperation )", SLAP_AT_HIDE,
+                       offsetof(struct monitorinfo, mi_ad_readOnly) },
 #ifdef INTEGRATE_CORE_SCHEMA
                { NULL, NULL, 0, -1 },  /* description */
                { NULL, NULL, 0, -1 },  /* seeAlso */
index 9b5980174bab47f264e6d2487a533978da240e7f..072504e59bd9adb54887eba7e666206c9a47fd7a 100644 (file)
@@ -41,6 +41,7 @@ int monitor_subsys_backend_init LDAP_P(( BackendDB *be ));
  * databases 
  */
 int monitor_subsys_database_init LDAP_P(( BackendDB *be ));
+int monitor_subsys_database_modify LDAP_P(( Operation *op, Entry *e ));
 
 /*
  * threads