diff --git a/contrib/smarty/plugins/block.render.php b/contrib/smarty/plugins/block.render.php
index 5244ec90c2084139fdce62eba80a57cd80b9a144..23e6b8a72652fae47919f4732cf21282329eb9b5 100644
--- a/contrib/smarty/plugins/block.render.php
+++ b/contrib/smarty/plugins/block.render.php
@@ -37,7 +37,7 @@ function smarty_block_render ($params, $text)
     echo '<div style="color:blue;">'.$acl.(isset($params['aclName']) ? ' ['.$params['aclName'].']' : '').'</div>';
   }
 
-  /* Read / Write*/
+  /* Read / Write */
   if (preg_match('/w/i', $acl)) {
     return $text;
   }
diff --git a/html/main.php b/html/main.php
index df5cd95a6c81a61d59f0337c60804a2ab4c3a806..aa345adc65b7fbd30d56130760f5cbf60bfdf12a 100644
--- a/html/main.php
+++ b/html/main.php
@@ -180,7 +180,6 @@ $smarty->assign("date", date("l, dS F Y H:i:s O"));
 $lang = session::global_get('lang');
 $smarty->assign('lang',  preg_replace('/_.*$/', '', $lang));
 $smarty->assign('rtl',   Language::isRTL($lang));
-$smarty->assign('must',  '<span class="must">*</span>');
 if (isset($plugin_index)) {
   $plug = "?plug=$plugin_index";
 } else {
diff --git a/html/setup.php b/html/setup.php
index f9ef8a8af5a2831fe48fec79f51d62e0f4b1a280..cd115681d1cf8e78b8c7755380f185f5eb092c42 100644
--- a/html/setup.php
+++ b/html/setup.php
@@ -89,7 +89,6 @@ Language::init($lang);
 
 $smarty->assign('lang', preg_replace('/_.*$/', '', $lang));
 $smarty->assign('rtl',  Language::isRTL($lang));
-$smarty->assign('must', '<span class="must">*</span>');
 
 /* Minimal config */
 if (!session::global_is_set('config')) {
diff --git a/html/themes/breezy/less/plugin.less b/html/themes/breezy/less/plugin.less
index adf358033ccf6875a4b4060396e289a552c25e03..41c7ee6f750ef46f93103c500c9a220f436344de 100644
--- a/html/themes/breezy/less/plugin.less
+++ b/html/themes/breezy/less/plugin.less
@@ -214,6 +214,31 @@ html.rtl .plugin-section.invisible {
   display: none;
 }
 
+html.ltr .plugin-section,
+html.rtl .plugin-section {
+  &.nonreadable {
+    display: none;
+  }
+  > div > table > tbody > tr {
+    &.nonreadable {
+      display: none;
+    }
+    &.nonwritable.subattribute {
+      display: none;
+    }
+    &.nonwritable .subattribute {
+      display: none;
+    }
+    &.nonwritable input:disabled {
+      color: @text-color;
+    }
+    &.required > td > label::after {
+      content: "*";
+      color: @warning-red-color;
+    }
+  }
+}
+
 fieldset.plugin-section.critical legend span,
 .plugin-section.critical > span.legend {
   font-weight: bold;
diff --git a/html/themes/breezy/less/style.less b/html/themes/breezy/less/style.less
index 81a5e7c06d87cbe250242ae0d3913f70caa31d7b..6b909d7a30b5b57ffce90ae7747361cbccb7279f 100644
--- a/html/themes/breezy/less/style.less
+++ b/html/themes/breezy/less/style.less
@@ -115,10 +115,6 @@ hr {
   height: 1px;
 }
 
-.must {
-  color: @warning-red-color;
-}
-
 img.center {
   text-align: center;
   vertical-align: middle;
diff --git a/html/themes/breezy/plugin.css b/html/themes/breezy/plugin.css
index 857e4b3f31928180c6e2cd90df3ea4522dd4f012..c98c5a7813fcfc6e871c4cef325f52d0d3ff4e3a 100644
--- a/html/themes/breezy/plugin.css
+++ b/html/themes/breezy/plugin.css
@@ -197,6 +197,31 @@ html.ltr .plugin-section.invisible,
 html.rtl .plugin-section.invisible {
   display: none;
 }
+html.ltr .plugin-section.nonreadable,
+html.rtl .plugin-section.nonreadable {
+  display: none;
+}
+html.ltr .plugin-section > div > table > tbody > tr.nonreadable,
+html.rtl .plugin-section > div > table > tbody > tr.nonreadable {
+  display: none;
+}
+html.ltr .plugin-section > div > table > tbody > tr.nonwritable.subattribute,
+html.rtl .plugin-section > div > table > tbody > tr.nonwritable.subattribute {
+  display: none;
+}
+html.ltr .plugin-section > div > table > tbody > tr.nonwritable .subattribute,
+html.rtl .plugin-section > div > table > tbody > tr.nonwritable .subattribute {
+  display: none;
+}
+html.ltr .plugin-section > div > table > tbody > tr.nonwritable input:disabled,
+html.rtl .plugin-section > div > table > tbody > tr.nonwritable input:disabled {
+  color: #31363b;
+}
+html.ltr .plugin-section > div > table > tbody > tr.required > td > label::after,
+html.rtl .plugin-section > div > table > tbody > tr.required > td > label::after {
+  content: "*";
+  color: #dd0000;
+}
 fieldset.plugin-section.critical legend span,
 .plugin-section.critical > span.legend {
   font-weight: bold;
diff --git a/html/themes/breezy/style.css b/html/themes/breezy/style.css
index 71a0edea79a3122f3fc99469a32aca815acd6317..884baf83eab63f5ba40d82aff874b6cba967553e 100644
--- a/html/themes/breezy/style.css
+++ b/html/themes/breezy/style.css
@@ -110,9 +110,6 @@ hr {
   background-color: #c0c2c3;
   height: 1px;
 }
-.must {
-  color: #dd0000;
-}
 img.center {
   text-align: center;
   vertical-align: middle;
diff --git a/html/themes/legacy/style.css b/html/themes/legacy/style.css
index 4b55e0cb83a4e27afa82354f36b6542217644c4f..caf7aa415f257005ade0c66f496d971802eebf0f 100644
--- a/html/themes/legacy/style.css
+++ b/html/themes/legacy/style.css
@@ -112,7 +112,9 @@ background-color: #aaa;
 height: 1px;
 }
 
-.must {
+html.ltr .plugin-section > div > table > tbody > tr.required > td > label::after,
+html.rtl .plugin-section > div > table > tbody > tr.required > td > label::after {
+content: "*";
 color: red;
 font-family: arial,helvetica,sans-serif;
 }
diff --git a/ihtml/themes/breezy/simpleplugin_section.tpl b/ihtml/themes/breezy/simpleplugin_section.tpl
index 0c9b525010bbf53f6717842dbdfdb8906449f241..4909f228e95a2e9f95a1b8f983f7f0f8fc5077eb 100644
--- a/ihtml/themes/breezy/simpleplugin_section.tpl
+++ b/ihtml/themes/breezy/simpleplugin_section.tpl
@@ -3,7 +3,12 @@
   <div>
   <table>
     {foreach from=$attributes item=attribute key=id}
-      <tr>
+      <tr class="
+        {if $attribute.subattribute}subattribute{/if}
+        {if $attribute.required}required{/if}
+        {if !$attribute.readable}nonreadable{/if}
+        {if !$attribute.writable}nonwritable{/if}
+      ">
         <td title="{$attribute.description|escape}"><label for="{$attribute.htmlid}">{eval var=$attribute.label}</label></td>
         <td>{eval var=$attribute.input}</td>
       </tr>
diff --git a/include/class_standAlonePage.inc b/include/class_standAlonePage.inc
index 43b22792a31ef079ac176f9d70510247bc0e051f..201e3728a5411a5d7c6cba377acd7dcabdd9229f 100644
--- a/include/class_standAlonePage.inc
+++ b/include/class_standAlonePage.inc
@@ -163,7 +163,6 @@ class standAlonePage
     $lang = session::global_get('lang');
     $smarty->assign('lang',         preg_replace('/_.*$/', '', $lang));
     $smarty->assign('rtl',          Language::isRTL($lang));
-    $smarty->assign('must',         '<span class="must">*</span>');
     $smarty->assign('usePrototype', 'FALSE');
     $smarty->assign('CSRFtoken',    CSRFProtection::getToken());
 
diff --git a/include/class_template.inc b/include/class_template.inc
index bbe6875cf1cf9aceb915b7a7ce1ee19b64582ec9..17e9616e2e2b979a4d9e5f088b2e852900b73fbf 100644
--- a/include/class_template.inc
+++ b/include/class_template.inc
@@ -285,7 +285,9 @@ class template
           // We assign ACLs so that attributes can use them in their template code
           $smarty->assign($plugin->attributesAccess[$attr]->getAcl().'ACL', $plugin->aclGetPermissions($plugin->attributesAccess[$attr]->getAcl()));
         }
-        $plugin->attributesAccess[$attr]->renderAttribute($attributesRendered, FALSE);
+        $readable = $plugin->attrIsReadable($attr);
+        $writable = $plugin->attrIsWriteable($attr);
+        $plugin->attributesAccess[$attr]->renderAttribute($attributesRendered, FALSE, $readable, $writable);
       }
 
       $smarty->assign('section', $this->tabObject->by_name[$class]);
diff --git a/include/simpleplugin/attributes/class_CompositeAttribute.inc b/include/simpleplugin/attributes/class_CompositeAttribute.inc
index 4d4a3a211489b9a4c0862b5b481496e8dc763ee3..e8408a3d77938ad6add057f4ce3ffebb1f71e600 100644
--- a/include/simpleplugin/attributes/class_CompositeAttribute.inc
+++ b/include/simpleplugin/attributes/class_CompositeAttribute.inc
@@ -229,15 +229,15 @@ class CompositeAttribute extends Attribute
     unset($attribute);
   }
 
-  function renderAttribute (array &$attributes, bool $readOnly)
+  function renderAttribute (array &$attributes, bool $readOnly, bool $readable, bool $writable)
   {
     if ($this->visible) {
       if ($this->linearRendering) {
-        parent::renderAttribute($attributes, $readOnly);
+        parent::renderAttribute($attributes, $readOnly, $readable, $writable);
       } else {
         foreach ($this->attributes as &$attribute) {
           $attribute->setDisabled($this->disabled);
-          $attribute->renderAttribute($attributes, $readOnly);
+          $attribute->renderAttribute($attributes, $readOnly, $readable, $writable);
         }
         unset($attribute);
       }
diff --git a/include/simpleplugin/attributes/class_FileAttribute.inc b/include/simpleplugin/attributes/class_FileAttribute.inc
index 0d760894f4723900a94847d964854d8f74abf1c8..0be6a09e8900b0fb92c4a48273e64b6541dca6ee 100644
--- a/include/simpleplugin/attributes/class_FileAttribute.inc
+++ b/include/simpleplugin/attributes/class_FileAttribute.inc
@@ -206,12 +206,12 @@ class FileDownloadAttribute extends FileAttribute
     return $ids;
   }
 
-  function renderAttribute (array &$attributes, bool $readOnly)
+  function renderAttribute (array &$attributes, bool $readOnly, bool $readable, bool $writable)
   {
     if ($this->upload === FALSE) {
-      parent::renderAttribute($attributes, FALSE);
+      parent::renderAttribute($attributes, FALSE, $readable, $writable);
     } else {
-      parent::renderAttribute($attributes, $readOnly);
+      parent::renderAttribute($attributes, $readOnly, $readable, $writable);
     }
   }
 }
diff --git a/include/simpleplugin/attributes/class_MailsAttribute.inc b/include/simpleplugin/attributes/class_MailsAttribute.inc
index ec456257c9d0d4491cccb2c55091d3ff9676c15b..8ce42552247d6178ed5d16e3d13769083b5183d8 100644
--- a/include/simpleplugin/attributes/class_MailsAttribute.inc
+++ b/include/simpleplugin/attributes/class_MailsAttribute.inc
@@ -97,18 +97,18 @@ class MailsAttribute extends DialogAttribute
     $id = $this->getHtmlId();
     $buttons  = $this->renderInputField(
       'submit', 'add'.$id,
-      ['value' => '{msgPool type=addButton}']
+      ['value' => '{msgPool type=addButton}', 'class' => 'subattribute']
     );
     $buttons  .= $this->renderInputField(
       'submit', 'add'.$id.'_dialog',
       [
-        'class' => 'dialog',
+        'class' => 'dialog subattribute',
         'value' => '{msgPool type=addButton} (from list)'
       ]
     );
     $buttons  .= $this->renderInputField(
       'submit', 'del'.$id,
-      ['value' => '{msgPool type=delButton}']
+      ['value' => '{msgPool type=delButton}', 'class' => 'subattribute']
     );
     return $buttons;
   }
diff --git a/include/simpleplugin/attributes/class_SelectAttribute.inc b/include/simpleplugin/attributes/class_SelectAttribute.inc
index c1117839df771c38bbe356b6319ce44ba307ccf3..16be00530ed8215024501fc52db4756c1955e240 100644
--- a/include/simpleplugin/attributes/class_SelectAttribute.inc
+++ b/include/simpleplugin/attributes/class_SelectAttribute.inc
@@ -193,6 +193,9 @@ class SelectAttribute extends Attribute
       $js       = $this->managedAttributesJS();
       $display  .= 'onChange="javascript:'.htmlentities($js, ENT_COMPAT, 'UTF-8').'"';
     }
+    if ($this->isSubAttribute) {
+      $display .= 'class="subattribute" ';
+    }
     $display .= '>';
     $display .= '{html_options values=$'.$id.'_choices output=$'.$id.'_outputs selected=$'.$id.'_selected}';
     $display .= '</select>';
diff --git a/include/simpleplugin/attributes/class_SetAttribute.inc b/include/simpleplugin/attributes/class_SetAttribute.inc
index 8b4a62241812d9007bad2a99d8c57fee96094941..ae6478572430cf586f3155ee02cb3639381f60ef 100644
--- a/include/simpleplugin/attributes/class_SetAttribute.inc
+++ b/include/simpleplugin/attributes/class_SetAttribute.inc
@@ -227,26 +227,28 @@ class SetAttribute extends Attribute
     }
   }
 
-  function renderAttribute (array &$attributes, bool $readOnly)
+  function renderAttribute (array &$attributes, bool $readOnly, bool $readable, bool $writable)
   {
     if ($this->attribute === FALSE) {
-      return parent::renderAttribute($attributes, $readOnly);
+      return parent::renderAttribute($attributes, $readOnly, $readable, $writable);
     }
     if ($this->visible) {
       $this->attribute->setDisabled($this->disabled);
       if ($this->linearRendering || $readOnly) {
-        parent::renderAttribute($attributes, $readOnly);
+        parent::renderAttribute($attributes, $readOnly, $readable, $writable);
       } else {
         $attributes[$this->getLdapName()] = [
           'htmlid'        => $this->getForHtmlId(),
-          'label'         => '{literal}'.$this->getLabel().'{/literal}'.($this->isRequired() ? '{$must}' : ''),
+          'label'         => '{literal}'.$this->getLabel().'{/literal}',
           'description'   => ($this->isRequired() ? sprintf(_("%s (required)"), $this->getDescription()) : $this->getDescription()),
           'input'         => $this->renderAcl($this->renderOnlyFormInput()),
           'subattribute'  => $this->isSubAttribute,
           'required'      => $this->isRequired(),
+          'readable'      => $readable,
+          'writable'      => $writable,
         ];
         $this->handleEditingValue();
-        $this->attribute->renderAttribute($attributes, $readOnly);
+        $this->attribute->renderAttribute($attributes, $readOnly, $acl);
         $attributes[$this->getLdapName().'_buttons'] = [
           'htmlid'        => 'add'.$this->getHtmlId(),
           'label'         => '',
@@ -254,6 +256,8 @@ class SetAttribute extends Attribute
           'input'         => $this->renderAcl($this->renderButtons()),
           'subattribute'  => TRUE,
           'required'      => FALSE,
+          'readable'      => $readable,
+          'writable'      => $writable,
         ];
       }
     }
@@ -289,8 +293,8 @@ class SetAttribute extends Attribute
   function renderButtons ()
   {
     $id = $this->getHtmlId();
-    $buttons  = $this->renderInputField('submit', 'add'.$id, ['value' => '{msgPool type=addButton}', 'formnovalidate' => 'formnovalidate']);
-    $buttons .= $this->renderInputField('submit', 'del'.$id, ['value' => '{msgPool type=delButton}', 'formnovalidate' => 'formnovalidate']);
+    $buttons  = $this->renderInputField('submit', 'add'.$id, ['value' => '{msgPool type=addButton}', 'formnovalidate' => 'formnovalidate', 'class' => 'subattribute']);
+    $buttons .= $this->renderInputField('submit', 'del'.$id, ['value' => '{msgPool type=delButton}', 'formnovalidate' => 'formnovalidate', 'class' => 'subattribute']);
     return $buttons;
   }
 
@@ -667,7 +671,7 @@ class OrderedArrayAttribute extends SetAttribute
   function renderButtons ()
   {
     $id = $this->getHtmlId();
-    $buttons = $this->renderInputField('submit', 'add'.$id, ['value' => '{msgPool type=addButton}', 'formnovalidate' => 'formnovalidate']);
+    $buttons = $this->renderInputField('submit', 'add'.$id, ['value' => '{msgPool type=addButton}', 'formnovalidate' => 'formnovalidate', 'class' => 'subattribute']);
     return $buttons;
   }
 }
diff --git a/include/simpleplugin/class_Attribute.inc b/include/simpleplugin/class_Attribute.inc
index 65161d69a54a90be238cb4521d5804387ea00a0b..828cc735a7976cc006608f2e71ad11519ca5f078 100644
--- a/include/simpleplugin/class_Attribute.inc
+++ b/include/simpleplugin/class_Attribute.inc
@@ -583,8 +583,12 @@ class Attribute
    *  \param array &$attributes the attributes array
    *
    *  \param bool $readOnly should we show text or input
+   *
+   *  \param bool $readable ACL read
+   *
+   *  \param bool $writable ACL write
    */
-  function renderAttribute (array &$attributes, bool $readOnly)
+  function renderAttribute (array &$attributes, bool $readOnly, bool $readable, bool $writable)
   {
     if ($this->visible) {
       if ($readOnly) {
@@ -607,11 +611,13 @@ class Attribute
       }
       $attributes[$this->getLdapName()] = [
         'htmlid'        => $this->getForHtmlId(),
-        'label'         => '{literal}'.$this->getLabel().'{/literal}'.($this->isRequired() ? '{$must}' : ''),
+        'label'         => '{literal}'.$this->getLabel().'{/literal}',
         'description'   => ($this->isRequired() ? sprintf(_("%s (required)"), $this->getDescription()) : $this->getDescription()),
         'input'         => $input,
         'subattribute'  => $this->isSubAttribute,
         'required'      => $this->isRequired(),
+        'readable'      => $readable,
+        'writable'      => $writable,
       ];
     }
   }
@@ -824,7 +830,7 @@ class FakeAttribute extends Attribute
     $this->setInLdap(FALSE);
   }
 
-  function renderAttribute (array &$attributes, bool $readOnly)
+  function renderAttribute (array &$attributes, bool $readOnly, bool $readable, bool $writable)
   {
     $attributes[$this->getLdapName()] = $this->getValue();
   }
diff --git a/include/simpleplugin/class_dialogAttributes.inc b/include/simpleplugin/class_dialogAttributes.inc
index 45877e45d3209cbae9230de2a5e1733f0fc9f5df..dd5f3f57bd128bf259085f7d5edbcb1cab9d25c8 100644
--- a/include/simpleplugin/class_dialogAttributes.inc
+++ b/include/simpleplugin/class_dialogAttributes.inc
@@ -200,13 +200,14 @@ abstract class DialogAttribute extends SetAttribute
     if ($this->isTemplate()) {
       $buttons  .= $this->renderInputField(
         'text', $id,
-        ['value' => $this->editingValue]
+        ['value' => $this->editingValue, 'class' => 'subattribute']
       );
       $buttons  .= $this->renderInputField(
         'submit', 'add'.$id,
         [
           'value'           => '{msgPool type=addButton}',
-          'formnovalidate'  => 'formnovalidate'
+          'formnovalidate'  => 'formnovalidate',
+          'class'           => 'subattribute',
         ]
       );
       $dialogButtonValue = _('Add (dialog)');
@@ -214,16 +215,17 @@ abstract class DialogAttribute extends SetAttribute
     $buttons  .= $this->renderInputField(
       'submit', 'add'.$id.'_dialog',
       [
-        'class'           => 'dialog',
+        'class'           => 'dialog subattribute',
         'value'           => $dialogButtonValue,
-        'formnovalidate'  => 'formnovalidate'
+        'formnovalidate'  => 'formnovalidate',
       ]
     );
     $buttons  .= $this->renderInputField(
       'submit', 'del'.$id,
       [
         'value'           => '{msgPool type=delButton}',
-        'formnovalidate'  => 'formnovalidate'
+        'formnovalidate'  => 'formnovalidate',
+        'class'           => 'subattribute',
       ]
     );
     return $buttons;
@@ -294,7 +296,7 @@ abstract class DialogOrderedArrayAttribute extends OrderedArrayAttribute
     return $this->renderInputField(
       'submit', 'add'.$id.'_dialog',
       [
-        'class'           => 'dialog',
+        'class'           => 'dialog subattribute',
         'value'           => '{msgPool type=addButton}',
         'formnovalidate'  => 'formnovalidate'
       ]
diff --git a/include/simpleplugin/class_simplePlugin.inc b/include/simpleplugin/class_simplePlugin.inc
index 940604f8362a407d465741d07effc93c168e513b..a1f0164d77fec3d5556735178e2717ddd6206a92 100644
--- a/include/simpleplugin/class_simplePlugin.inc
+++ b/include/simpleplugin/class_simplePlugin.inc
@@ -785,6 +785,21 @@ class simplePlugin implements SimpleTab
     return $display;
   }
 
+  /*! \brief Check if logged in user have enough right to read this attribute value
+   *
+   * \param mixed $attr Attribute object or name (in this case it will be fetched from attributesAccess)
+   */
+  function attrIsReadable ($attr): bool
+  {
+    if (!is_object($attr)) {
+      $attr = $this->attributesAccess[$attr];
+    }
+    if ($attr->getLdapName() == 'base') {
+      return TRUE;
+    }
+    return $this->acl_is_readable($attr->getAcl());
+  }
+
   /*! \brief Check if logged in user have enough right to write this attribute value
    *
    * \param mixed $attr Attribute object or name (in this case it will be fetched from attributesAccess)
@@ -852,20 +867,29 @@ class simplePlugin implements SimpleTab
       }
       $smarty->assign("section", $legend);
       $smarty->assign("sectionId", $section);
+      $sectionClasses = '';
       if (isset($sectionInfo['class'])) {
-        $smarty->assign("sectionClasses", ' '.join(' ', $sectionInfo['class']));
-      } else {
-        $smarty->assign("sectionClasses", '');
+        $sectionClasses .= ' '.join(' ', $sectionInfo['class']);
       }
-      $attributes = [];
+      $attributes       = [];
+      $readableSection  = FALSE;
       foreach ($sectionInfo['attrs'] as $attr) {
         if ($attr->getAclInfo() !== FALSE) {
           // We assign ACLs so that attributes can use them in their template code
-          $smarty->assign($attr->getAcl()."ACL", $this->aclGetPermissions($attr->getAcl(), NULL, $this->acl_skip_write()));
+          $smarty->assign($attr->getAcl().'ACL', $this->aclGetPermissions($attr->getAcl(), NULL, $this->acl_skip_write()));
+        }
+        $readable = $this->attrIsReadable($attr);
+        $writable = $this->attrIsWriteable($attr);
+        if (!$readableSection && ($readable || $writable)) {
+          $readableSection = TRUE;
         }
-        $attr->renderAttribute($attributes, $readOnly);
+        $attr->renderAttribute($attributes, $readOnly, $readable, $writable);
+      }
+      $smarty->assign('attributes', $attributes);
+      if (!$readableSection) {
+        $sectionClasses .= ' nonreadable';
       }
-      $smarty->assign("attributes", $attributes);
+      $smarty->assign('sectionClasses', $sectionClasses);
       // We fetch each section with the section template
       if (isset($sectionInfo['template'])) {
         $displaySection = $smarty->fetch($sectionInfo['template']);
@@ -923,7 +947,7 @@ class simplePlugin implements SimpleTab
   /*! \brief Can we write the attribute */
   function acl_is_writeable ($attribute, bool $skipWrite = FALSE): bool
   {
-    return preg_match('/w/', $this->aclGetPermissions($attribute, NULL, $skipWrite));
+    return (strpos($this->aclGetPermissions($attribute, NULL, $skipWrite), 'w') !== FALSE);
   }
 
   /*!
@@ -933,7 +957,7 @@ class simplePlugin implements SimpleTab
    */
   function acl_is_readable ($attribute): bool
   {
-    return preg_match('/r/', $this->aclGetPermissions($attribute));
+    return (strpos($this->aclGetPermissions($attribute), 'r') !== FALSE);
   }
 
   /*!
@@ -943,7 +967,7 @@ class simplePlugin implements SimpleTab
    */
   function acl_is_createable (string $base = NULL): bool
   {
-    return preg_match('/c/', $this->aclGetPermissions('0', $base));
+    return (strpos($this->aclGetPermissions('0', $base), 'c') !== FALSE);
   }
 
   /*!
@@ -953,7 +977,7 @@ class simplePlugin implements SimpleTab
    */
   function acl_is_removeable (string $base = NULL): bool
   {
-    return preg_match('/d/', $this->aclGetPermissions('0', $base));
+    return (strpos($this->aclGetPermissions('0', $base), 'd') !== FALSE);
   }
 
   /*!
@@ -963,7 +987,7 @@ class simplePlugin implements SimpleTab
    */
   function acl_is_moveable (string $base = NULL): bool
   {
-    return preg_match('/m/', $this->aclGetPermissions('0', $base));
+    return (strpos($this->aclGetPermissions('0', $base), 'm') !== FALSE);
   }
 
   /*! \brief Get the acl permissions for an attribute or the plugin itself */
diff --git a/plugins/personal/generic/class_UserPasswordAttribute.inc b/plugins/personal/generic/class_UserPasswordAttribute.inc
index 607d2b59646c796d22247498cce688f99dfcf14e..7b73efaa96a729f415b5c87f35ca1c67c9271aef 100644
--- a/plugins/personal/generic/class_UserPasswordAttribute.inc
+++ b/plugins/personal/generic/class_UserPasswordAttribute.inc
@@ -88,12 +88,12 @@ class UserPasswordAttribute extends CompositeAttribute
   }
 
   /* We need to handle method select disabling manually */
-  function renderAttribute (array &$attributes, bool $readOnly)
+  function renderAttribute (array &$attributes, bool $readOnly, bool $readable, bool $writable)
   {
     global $config;
     if ($this->visible) {
       if ($this->linearRendering) {
-        parent::renderAttribute($attributes, $readOnly);
+        parent::renderAttribute($attributes, $readOnly, $readable, $writable);
       } else {
         foreach ($this->attributes as $key => &$attribute) {
           if (is_object($this->plugin) && $this->plugin->is_template && ($key == 2)) {
@@ -105,7 +105,7 @@ class UserPasswordAttribute extends CompositeAttribute
           } else {
             $attribute->setDisabled($this->disabled);
           }
-          $attribute->renderAttribute($attributes, $readOnly);
+          $attribute->renderAttribute($attributes, $readOnly, $readable, $writable);
         }
         unset($attribute);
       }