diff --git a/__openerp__.py b/__openerp__.py
index eeb618d63ccf933f4b2e3d3aad7984519a58990e_X19vcGVuZXJwX18ucHk=..151a4edd9121e28e4df3f9436e2647eaac919f71_X19vcGVuZXJwX18ucHk= 100644
--- a/__openerp__.py
+++ b/__openerp__.py
@@ -35,7 +35,8 @@
 
     'data': [
         'data/auth_saml.xml',
+        'data/ir_config_parameter.xml',
 
         'security/ir.model.access.csv',
 
         'views/auth_saml.xml',
@@ -38,7 +39,8 @@
 
         'security/ir.model.access.csv',
 
         'views/auth_saml.xml',
+        'views/base_settings.xml',
         'views/res_users.xml',
     ],
 
diff --git a/data/ir_config_parameter.xml b/data/ir_config_parameter.xml
new file mode 100644
index 0000000000000000000000000000000000000000..151a4edd9121e28e4df3f9436e2647eaac919f71_ZGF0YS9pcl9jb25maWdfcGFyYW1ldGVyLnhtbA==
--- /dev/null
+++ b/data/ir_config_parameter.xml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data noupdate="1">
+
+        <!-- Add a setting; to be manipulated via "general settings". -->
+
+        <record id="allow_saml_uid_and_internal_password" model="ir.config_parameter">
+            <field name="key">auth_saml.allow_saml.uid_and_internal_password</field>
+            <field name="value">0</field>
+        </record>
+
+    </data>
+</openerp>
diff --git a/documentation/index.rst b/documentation/index.rst
index eeb618d63ccf933f4b2e3d3aad7984519a58990e_ZG9jdW1lbnRhdGlvbi9pbmRleC5yc3Q=..151a4edd9121e28e4df3f9436e2647eaac919f71_ZG9jdW1lbnRhdGlvbi9pbmRleC5yc3Q= 100644
--- a/documentation/index.rst
+++ b/documentation/index.rst
@@ -84,3 +84,5 @@
 and make sure the URLs point where they should. Edit the file if necessary.
 
 Then save its content into the corresponding box in the openerp SAML2 Provider form.
+
+There are additional SAML-related settings in Configuration > General settings.
diff --git a/model/__init__.py b/model/__init__.py
index eeb618d63ccf933f4b2e3d3aad7984519a58990e_bW9kZWwvX19pbml0X18ucHk=..151a4edd9121e28e4df3f9436e2647eaac919f71_bW9kZWwvX19pbml0X18ucHk= 100644
--- a/model/__init__.py
+++ b/model/__init__.py
@@ -1,5 +1,6 @@
 # flake8: noqa
 
 import auth_saml
+import base_settings
 import res_users
 import saml_token
diff --git a/model/base_settings.py b/model/base_settings.py
new file mode 100644
index 0000000000000000000000000000000000000000..151a4edd9121e28e4df3f9436e2647eaac919f71_bW9kZWwvYmFzZV9zZXR0aW5ncy5weQ==
--- /dev/null
+++ b/model/base_settings.py
@@ -0,0 +1,98 @@
+from openerp import SUPERUSER_ID
+from openerp.osv import fields
+from openerp.osv import orm
+
+
+_SAML_UID_AND_PASS_SETTING = 'auth_saml.allow_saml.uid_and_internal_password'
+
+
+class base_settings(orm.TransientModel):
+    """Inherit from base.config.settings to add a setting. This is only here
+    for easier access; the setting is not actually stored by this (transient)
+    collection. Instead, it is kept in sync with the
+    "auth_saml.allow_saml.uid_and_internal_password" global setting. See
+    comments in the definition of the "res.config.settings" collection for
+    details.
+    """
+
+    _inherit = 'base.config.settings'
+
+    _columns = {
+        'allow_saml_uid_and_internal_password': fields.boolean(
+            (
+                'Allow SAML users to posess an Odoo password (warning: '
+                'decreases security)'
+            ),
+        ),
+    }
+
+    def allow_saml_uid_and_internal_password(self, cr, context=None):
+        """Read the allow_saml_uid_and_internal_password setting.
+        Use the admin account to bypass security restrictions.
+        """
+
+        uid = SUPERUSER_ID
+
+        config_obj = self.pool['ir.config_parameter']
+
+        config_ids = config_obj.search(
+            cr, uid,
+            [('key', '=', _SAML_UID_AND_PASS_SETTING)],
+            limit=1,
+            context=context
+        )
+        if not config_ids:
+            return False
+
+        config = config_obj.browse(
+            cr, uid, config_ids, context=context
+        )[0]
+        return (True if config.value == '1' else False)
+
+    def get_default_allow_saml_uid_and_internal_password(
+        self, cr, uid, fields, context=None
+    ):
+        """Read the allow_saml_uid_and_internal_password setting. This function
+        is called when the form is shown.
+        """
+
+        ret = {}
+
+        if 'allow_saml_uid_and_internal_password' in fields:
+            ret['allow_saml_uid_and_internal_password'] = (
+                self.allow_saml_uid_and_internal_password(cr, context)
+            )
+
+        return ret
+
+    def set_allow_saml_uid_and_internal_password(
+        self, cr, uid, ids, context=None
+    ):
+        """Update the allow_saml_uid_and_internal_password setting. This
+        function is called when saving the form.
+        """
+
+        dlg = self.browse(cr, uid, ids, context=context)[0]
+
+        setting_value = (
+            '1' if dlg.allow_saml_uid_and_internal_password else '0'
+        )
+
+        config_obj = self.pool['ir.config_parameter']
+        config_ids = config_obj.search(
+            cr, uid,
+            [('key', '=', _SAML_UID_AND_PASS_SETTING)],
+            limit=1,
+            context=context
+        )
+        if config_ids:
+            config_obj.write(
+                cr, uid, config_ids, {'value': setting_value}, context=context
+            )
+        else:
+            # The setting doesn't exist; create it.
+            config_obj.create(
+                cr, uid,
+                {'key': _SAML_UID_AND_PASS_SETTING, 'value': setting_value},
+                context=context
+            )
diff --git a/model/res_users.py b/model/res_users.py
index eeb618d63ccf933f4b2e3d3aad7984519a58990e_bW9kZWwvcmVzX3VzZXJzLnB5..151a4edd9121e28e4df3f9436e2647eaac919f71_bW9kZWwvcmVzX3VzZXJzLnB5 100644
--- a/model/res_users.py
+++ b/model/res_users.py
@@ -28,6 +28,10 @@
         password.
         """
 
+        if self._allow_saml_uid_and_internal_password(cr, context):
+            # The constraint is a no-op in this case.
+            return True
+
         users = self.browse(cr, uid, ids, context=context)
         for user in users:
             if user.password and user.saml_uid:
@@ -201,8 +205,9 @@
         """
 
         if vals and vals.get('saml_uid'):
-            vals['password'] = False
+            if not self._allow_saml_uid_and_internal_password(cr, context):
+                vals['password'] = False
 
         return super(res_users, self).write(
             cr, uid, ids, vals, context=context
         )
@@ -205,4 +210,10 @@
 
         return super(res_users, self).write(
             cr, uid, ids, vals, context=context
         )
+
+    def _allow_saml_uid_and_internal_password(self, cr, context):
+        setting_obj = self.pool['base.config.settings']
+        return setting_obj.allow_saml_uid_and_internal_password(
+            cr, context=context
+        )
diff --git a/views/base_settings.xml b/views/base_settings.xml
new file mode 100644
index 0000000000000000000000000000000000000000..151a4edd9121e28e4df3f9436e2647eaac919f71_dmlld3MvYmFzZV9zZXR0aW5ncy54bWw=
--- /dev/null
+++ b/views/base_settings.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<openerp>
+    <data>
+
+        <!-- Inherit from the configuration form to add a setting. -->
+
+        <record id="auth_saml_base_settings_form" model="ir.ui.view">
+            <field name="name">auth_saml_base_settings_form</field>
+            <field name="model">base.config.settings</field>
+            <field name="inherit_id" ref="base_setup.view_general_configuration" />
+            <field name="arch" type="xml">
+
+                <xpath expr="//field[@name='module_auth_oauth']/.."
+                    position="after">
+                    <div>
+                        <field name="allow_saml_uid_and_internal_password"
+                            class="oe_inline" />
+                        <label for="allow_saml_uid_and_internal_password" />
+                    </div>
+                </xpath>
+
+            </field>
+        </record>
+
+    </data>
+</openerp>