[SCM] Samba Shared Repository - branch master updated

Andrew Bartlett abartlet at samba.org
Wed Jul 1 14:57:04 UTC 2020


The branch, master has been updated
       via  d3086501456 tls: Use NORMAL:-VERS-SSL3.0 as the default configuration
       via  cabf873b75b selftest: Run test of how userPassword / crypt() style passwords are stored in quicktest
       via  2c4ecf002a3 selftest: Split samba.tests.samba_tool.user_virtualCryptSHA into GPG and not GPG parts
       via  91453f110fa dsdb: Allow "password hash userPassword schemes = CryptSHA256" to work on RHEL7
      from  213501163c0 share_mode_lock.c: initialize out param

https://git.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit d30865014569f4b9a1261d9f0c40bc4fc98f883e
Author: Andreas Schneider <asn at samba.org>
Date:   Tue Jun 30 17:12:17 2020 +0200

    tls: Use NORMAL:-VERS-SSL3.0 as the default configuration
    
    This seems to be really broken in GnuTLS and the documentation is also
    not correct.
    
    This partially reverts 53e3a959b958a3b099df6ecc5f6e294e96bd948e
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14408
    
    Signed-off-by: Andreas Schneider <asn at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>
    
    Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
    Autobuild-Date(master): Wed Jul  1 14:56:33 UTC 2020 on sn-devel-184

commit cabf873b75b1d4d456190358bc3ed051bca16978
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Jul 1 14:31:54 2020 +1200

    selftest: Run test of how userPassword / crypt() style passwords are stored in quicktest
    
    This ensures that the crypt_r()/crypt_rn()/crypt() behaviour is tested in all
    the samba-o3 builds and so is checked on RHEL7 in GitLab CI.
    
    https://bugzilla.samba.org/show_bug.cgi?id=14424
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit 2c4ecf002a3fbbe8be061814468529c8bd6bb7aa
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Jul 1 14:30:24 2020 +1200

    selftest: Split samba.tests.samba_tool.user_virtualCryptSHA into GPG and not GPG parts
    
    This allows the userPassword (not GPG) part of the test to run on hosts without
    python3-gpg (eg RHEL7) while still testing the userPassword handling.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14424
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

commit 91453f110fa72062291eb59ad9d95fab0f423557
Author: Andrew Bartlett <abartlet at samba.org>
Date:   Wed Jul 1 14:35:39 2020 +1200

    dsdb: Allow "password hash userPassword schemes = CryptSHA256" to work on RHEL7
    
    On RHEL7 crypt_r() will set errno.  This is a problem because the implementation of crypt_r()
    in RHEL8 and elsewhere in libcrypt will return non-NULL but set errno on failure.
    
    The workaround is to use crypt_rn(), provided only by libcrypt, which will return NULL
    on failure, and so avoid checking errno in the non-failure case.
    
    BUG: https://bugzilla.samba.org/show_bug.cgi?id=14424
    
    Signed-off-by: Andrew Bartlett <abartlet at samba.org>
    Reviewed-by: Alexander Bokovoy <ab at samba.org>

-----------------------------------------------------------------------

Summary of changes:
 docs-xml/smbdotconf/security/tlspriority.xml       |   6 +-
 lib/param/loadparm.c                               |   6 -
 lib/replace/wscript                                |   1 +
 python/samba/tests/docs.py                         |  21 --
 .../tests/samba_tool/user_virtualCryptSHA_base.py  | 118 ++++++++++
 .../tests/samba_tool/user_virtualCryptSHA_gpg.py   | 261 +++++++++++++++++++++
 .../user_virtualCryptSHA_userPassword.py           | 185 +++++++++++++++
 selftest/quick                                     |   3 +
 source3/param/loadparm.c                           |   8 +-
 source4/dsdb/samdb/ldb_modules/password_hash.c     |  37 ++-
 source4/selftest/tests.py                          |   3 +-
 11 files changed, 603 insertions(+), 46 deletions(-)
 create mode 100644 python/samba/tests/samba_tool/user_virtualCryptSHA_base.py
 create mode 100644 python/samba/tests/samba_tool/user_virtualCryptSHA_gpg.py
 create mode 100644 python/samba/tests/samba_tool/user_virtualCryptSHA_userPassword.py


Changeset truncated at 500 lines:

diff --git a/docs-xml/smbdotconf/security/tlspriority.xml b/docs-xml/smbdotconf/security/tlspriority.xml
index 6d1f0dcb912..471dc25ba3b 100644
--- a/docs-xml/smbdotconf/security/tlspriority.xml
+++ b/docs-xml/smbdotconf/security/tlspriority.xml
@@ -12,10 +12,8 @@
    <ulink url="http://gnutls.org/manual/html_node/Priority-Strings.html">GNUTLS
    Priority-Strings documentation at http://gnutls.org/manual/html_node/Priority-Strings.html</ulink>
    </para>
-   <para>By default it will try to find a config file matching "SAMBA", but if
-   that does not exist will use the entry for "SYSTEM" and last fallback to
-   NORMAL. In all cases the SSL3.0 protocol will be disabled.</para>
+   <para>The SSL3.0 protocol will be disabled.</para>
  </description>
 
- <value type="default">@SAMBA,SYSTEM,NORMAL:!-VERS-SSL3.0</value>
+ <value type="default">NORMAL:-VERS-SSL3.0</value>
 </samba:parameter>
diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c
index 53eedeb0cb2..da639a8b0ff 100644
--- a/lib/param/loadparm.c
+++ b/lib/param/loadparm.c
@@ -2818,15 +2818,9 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx)
 	lpcfg_do_global_parameter(lp_ctx, "tls keyfile", "tls/key.pem");
 	lpcfg_do_global_parameter(lp_ctx, "tls certfile", "tls/cert.pem");
 	lpcfg_do_global_parameter(lp_ctx, "tls cafile", "tls/ca.pem");
-#ifdef HAVE_GNUTLS_SET_DEFAULT_PRIORITY_APPEND
-	lpcfg_do_global_parameter(lp_ctx,
-				  "tls priority",
-				  "@SAMBA,SYSTEM,NORMAL:!-VERS-SSL3.0");
-#else
 	lpcfg_do_global_parameter(lp_ctx,
 				  "tls priority",
 				  "NORMAL:-VERS-SSL3.0");
-#endif
 
 	lpcfg_do_global_parameter(lp_ctx, "nsupdate command", "/usr/bin/nsupdate -g");
 
diff --git a/lib/replace/wscript b/lib/replace/wscript
index ab2b3c043af..55c8903f1c8 100644
--- a/lib/replace/wscript
+++ b/lib/replace/wscript
@@ -661,6 +661,7 @@ def configure(conf):
 
     conf.CHECK_FUNCS_IN('crypt', 'crypt', checklibc=True)
     conf.CHECK_FUNCS_IN('crypt_r', 'crypt', checklibc=True)
+    conf.CHECK_FUNCS_IN('crypt_rn', 'crypt', checklibc=True)
 
     conf.CHECK_VARIABLE('rl_event_hook', define='HAVE_DECL_RL_EVENT_HOOK', always=True,
                         headers='readline.h readline/readline.h readline/history.h')
diff --git a/python/samba/tests/docs.py b/python/samba/tests/docs.py
index 10339702a97..135be830521 100644
--- a/python/samba/tests/docs.py
+++ b/python/samba/tests/docs.py
@@ -29,22 +29,6 @@ import multiprocessing
 import concurrent.futures
 import tempfile
 
-config_h = os.path.join("bin/default/include/config.h")
-config_hash = dict()
-
-if os.path.exists(config_h):
-    config_hash = dict()
-    f = open(config_h, 'r')
-    try:
-        lines = f.readlines()
-        config_hash = dict((x[0], ' '.join(x[1:]))
-                           for x in map(lambda line: line.strip().split(' ')[1:],
-                                        list(filter(lambda line: (line[0:7] == '#define') and (len(line.split(' ')) > 2), lines))))
-    finally:
-        f.close()
-
-have_gnutls_system_config_support = ("HAVE_GNUTLS_SET_DEFAULT_PRIORITY_APPEND" in config_hash)
-
 class TestCase(samba.tests.TestCaseInTempDir):
 
     def _format_message(self, parameters, message):
@@ -234,11 +218,6 @@ class SmbDotConfTests(TestCase):
         'smbd max async dosmode',
     ])
 
-    # 'tls priority' has a legacy default value if we don't link against a
-    # modern GnuTLS version.
-    if not have_gnutls_system_config_support:
-        special_cases.add('tls priority')
-
     def setUp(self):
         super(SmbDotConfTests, self).setUp()
         # create a minimal smb.conf file for testparm
diff --git a/python/samba/tests/samba_tool/user_virtualCryptSHA_base.py b/python/samba/tests/samba_tool/user_virtualCryptSHA_base.py
new file mode 100644
index 00000000000..e32f8d7343c
--- /dev/null
+++ b/python/samba/tests/samba_tool/user_virtualCryptSHA_base.py
@@ -0,0 +1,118 @@
+# Tests for the samba-tool user sub command reading Primary:userPassword
+#
+# Copyright (C) Andrew Bartlett <abartlet at samba.org> 2017
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+import os
+import time
+import base64
+import ldb
+import samba
+from samba.tests.samba_tool.base import SambaToolCmdTest
+from samba.credentials import Credentials
+from samba.samdb import SamDB
+from samba.auth import system_session
+from samba.ndr import ndr_unpack
+from samba.dcerpc import drsblobs
+from samba import dsdb
+import re
+
+USER_NAME = "CryptSHATestUser"
+HASH_OPTION = "password hash userPassword schemes"
+
+# Get the value of an attribute from the output string
+# Note: Does not correctly handle values spanning multiple lines,
+#       which is acceptable for it's usage in these tests.
+
+
+def _get_attribute(out, name):
+    p = re.compile("^" + name + ":\s+(\S+)")
+    for line in out.split("\n"):
+        m = p.match(line)
+        if m:
+            return m.group(1)
+    return ""
+
+
+class UserCmdCryptShaTestCase(SambaToolCmdTest):
+    """
+    Tests for samba-tool user subcommands generation of the virtualCryptSHA256
+    and virtualCryptSHA512 attributes
+    """
+    users = []
+    samdb = None
+
+    def setUp(self):
+        super(UserCmdCryptShaTestCase, self).setUp()
+
+    def add_user(self, hashes=""):
+        self.lp = samba.tests.env_loadparm()
+
+        # set the extra hashes to be calculated
+        self.lp.set(HASH_OPTION, hashes)
+
+        self.creds = Credentials()
+        self.session = system_session()
+        self.ldb = SamDB(
+            session_info=self.session,
+            credentials=self.creds,
+            lp=self.lp)
+
+        password = self.random_password()
+        self.runsubcmd("user",
+                       "create",
+                       USER_NAME,
+                       password)
+
+    def tearDown(self):
+        super(UserCmdCryptShaTestCase, self).tearDown()
+        self.runsubcmd("user", "delete", USER_NAME)
+
+    def _get_password(self, attributes, decrypt=False):
+        command = ["user",
+                   "getpassword",
+                   USER_NAME,
+                   "--attributes",
+                   attributes]
+        if decrypt:
+            command.append("--decrypt-samba-gpg")
+
+        (result, out, err) = self.runsubcmd(*command)
+        self.assertCmdSuccess(result,
+                              out,
+                              err,
+                              "Ensure getpassword runs")
+        self.assertEqual(err, "", "getpassword")
+        self.assertMatch(out,
+                         "Got password OK",
+                         "getpassword out[%s]" % out)
+        return out
+
+    # Change the just the NT password hash, as would happen if the password
+    # was updated by Windows, the userPassword values are now obsolete.
+    #
+    def _change_nt_hash(self):
+        res = self.ldb.search(expression = "cn=%s" % USER_NAME,
+                              scope      = ldb.SCOPE_SUBTREE)
+        msg = ldb.Message()
+        msg.dn = res[0].dn
+        msg["unicodePwd"] = ldb.MessageElement(b"ABCDEF1234567890",
+                                               ldb.FLAG_MOD_REPLACE,
+                                               "unicodePwd")
+        self.ldb.modify(
+            msg,
+            controls=["local_oid:%s:0" %
+                      dsdb.DSDB_CONTROL_BYPASS_PASSWORD_HASH_OID])
diff --git a/python/samba/tests/samba_tool/user_virtualCryptSHA_gpg.py b/python/samba/tests/samba_tool/user_virtualCryptSHA_gpg.py
new file mode 100644
index 00000000000..25c02d9ac2a
--- /dev/null
+++ b/python/samba/tests/samba_tool/user_virtualCryptSHA_gpg.py
@@ -0,0 +1,261 @@
+# Tests for the samba-tool user sub command reading Primary:userPassword
+#
+# Copyright (C) Andrew Bartlett <abartlet at samba.org> 2017
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+#
+
+from samba.tests.samba_tool.user_virtualCryptSHA_base import UserCmdCryptShaTestCase, _get_attribute
+
+class UserCmdCryptShaTestCaseGPG(UserCmdCryptShaTestCase):
+    """
+    Tests for samba-tool user subcommands generation of the virtualCryptSHA256
+    and virtualCryptSHA512 attributes
+    """
+
+    # gpg decryption enabled.
+    # both virtual attributes specified, no rounds option
+    # no hashes stored in supplementalCredentials
+    # Should get values
+    def test_gpg_both_hashes_no_rounds(self):
+        self.add_user()
+        out = self._get_password("virtualCryptSHA256,virtualCryptSHA512", True)
+
+        self.assertTrue("virtualCryptSHA256:" in out)
+        self.assertTrue("virtualCryptSHA512:" in out)
+        self.assertTrue("rounds=" not in out)
+
+    # gpg decryption enabled.
+    # SHA256 specified
+    # no hashes stored in supplementalCredentials
+    # No rounds
+    #
+    # Should get values
+    def test_gpg_sha256_no_rounds(self):
+        self.add_user()
+        out = self._get_password("virtualCryptSHA256", True)
+
+        self.assertTrue("virtualCryptSHA256:" in out)
+        self.assertTrue("virtualCryptSHA512:" not in out)
+        self.assertTrue("rounds=" not in out)
+
+    # gpg decryption enabled.
+    # SHA512 specified
+    # no hashes stored in supplementalCredentials
+    # No rounds
+    #
+    # Should get values
+    def test_gpg_sha512_no_rounds(self):
+        self.add_user()
+        out = self._get_password("virtualCryptSHA512", True)
+
+        self.assertTrue("virtualCryptSHA256:" not in out)
+        self.assertTrue("virtualCryptSHA512:" in out)
+        self.assertTrue("rounds=" not in out)
+
+    # gpg decryption enabled.
+    # SHA128 specified, i.e. invalid/unknown algorithm
+    # no hashes stored in supplementalCredentials
+    # No rounds
+    #
+    # Should not get values
+    def test_gpg_invalid_alg_no_rounds(self):
+        self.add_user()
+        out = self._get_password("virtualCryptSHA128", True)
+
+        self.assertTrue("virtualCryptSHA256:" not in out)
+        self.assertTrue("virtualCryptSHA512:" not in out)
+        self.assertTrue("rounds=" not in out)
+
+    # gpg decryption enabled.
+    # both virtual attributes specified, no rounds option
+    # no hashes stored in supplementalCredentials
+    # underlying windows password changed, so plain text password is
+    # invalid.
+    # Should not get values
+    def test_gpg_both_hashes_no_rounds_pwd_changed(self):
+        self.add_user()
+        self._change_nt_hash()
+        out = self._get_password("virtualCryptSHA256,virtualCryptSHA512", True)
+
+        self.assertTrue("virtualCryptSHA256:" not in out)
+        self.assertTrue("virtualCryptSHA512:" not in out)
+        self.assertTrue("rounds=" not in out)
+
+    # gpg decryption enabled.
+    # SHA256 specified, no rounds option
+    # no hashes stored in supplementalCredentials
+    # underlying windows password changed, so plain text password is
+    # invalid.
+    # Should not get values
+    def test_gpg_sha256_no_rounds_pwd_changed(self):
+        self.add_user()
+        self._change_nt_hash()
+        out = self._get_password("virtualCryptSHA256", True)
+
+        self.assertTrue("virtualCryptSHA256:" not in out)
+        self.assertTrue("virtualCryptSHA512:" not in out)
+        self.assertTrue("rounds=" not in out)
+
+    # gpg decryption enabled.
+    # SHA512 specified, no rounds option
+    # no hashes stored in supplementalCredentials
+    # underlying windows password changed, so plain text password is
+    # invalid.
+    # Should not get values
+    def test_gpg_sha512_no_rounds_pwd_changed(self):
+        self.add_user()
+        self._change_nt_hash()
+        out = self._get_password("virtualCryptSHA256", True)
+
+        self.assertTrue("virtualCryptSHA256:" not in out)
+        self.assertTrue("virtualCryptSHA512:" not in out)
+        self.assertTrue("rounds=" not in out)
+
+    # gpg decryption enabled.
+    # both virtual attributes specified, rounds specified
+    # no hashes stored in supplementalCredentials
+    # Should get values reflecting the requested rounds
+    def test_gpg_both_hashes_both_rounds(self):
+        self.add_user()
+        out = self._get_password(
+            "virtualCryptSHA256;rounds=10123,virtualCryptSHA512;rounds=10456",
+            True)
+
+        self.assertTrue("virtualCryptSHA256:" in out)
+        self.assertTrue("virtualCryptSHA512:" in out)
+
+        sha256 = _get_attribute(out, "virtualCryptSHA256")
+        self.assertTrue(sha256.startswith("{CRYPT}$5$rounds=10123$"))
+
+        sha512 = _get_attribute(out, "virtualCryptSHA512")
+        self.assertTrue(sha512.startswith("{CRYPT}$6$rounds=10456$"))
+
+    # gpg decryption enabled.
+    # both virtual attributes specified, rounds specified
+    # invalid rounds for sha256
+    # no hashes stored in supplementalCredentials
+    # Should get values, no rounds for sha256, rounds for sha 512
+    def test_gpg_both_hashes_sha256_rounds_invalid(self):
+        self.add_user()
+        out = self._get_password(
+            "virtualCryptSHA256;rounds=invalid,virtualCryptSHA512;rounds=3125",
+            True)
+
+        self.assertTrue("virtualCryptSHA256:" in out)
+        self.assertTrue("virtualCryptSHA512:" in out)
+
+        sha256 = _get_attribute(out, "virtualCryptSHA256")
+        self.assertTrue(sha256.startswith("{CRYPT}$5$"))
+        self.assertTrue("rounds" not in sha256)
+
+        sha512 = _get_attribute(out, "virtualCryptSHA512")
+        self.assertTrue(sha512.startswith("{CRYPT}$6$rounds=3125$"))
+
+    # gpg decryption enabled.
+    # both virtual attributes specified, rounds specified
+    # both hashes stored in supplementalCredentials, with no rounds
+    # Should get calculated hashed with the correct number of rounds
+    def test_gpg_both_hashes_rounds_stored_hashes(self):
+        self.add_user("CryptSHA512 CryptSHA256")
+
+        out = self._get_password("virtualCryptSHA256;rounds=2561," +
+                                 "virtualCryptSHA512;rounds=5129",
+                                 True)
+
+        self.assertTrue("virtualCryptSHA256:" in out)
+        self.assertTrue("virtualCryptSHA512:" in out)
+        self.assertTrue("rounds=" in out)
+
+        # Should be calculating the hashes
+        # so they should change between calls.
+        sha256 = _get_attribute(out, "virtualCryptSHA256")
+        sha512 = _get_attribute(out, "virtualCryptSHA512")
+
+        out = self._get_password("virtualCryptSHA256;rounds=2561," +
+                                 "virtualCryptSHA512;rounds=5129",
+                                 True)
+        self.assertFalse(sha256 == _get_attribute(out, "virtualCryptSHA256"))
+        self.assertFalse(sha512 == _get_attribute(out, "virtualCryptSHA512"))
+
+        # The returned hashes should specify the correct number of rounds
+        self.assertTrue(sha256.startswith("{CRYPT}$5$rounds=2561"))
+        self.assertTrue(sha512.startswith("{CRYPT}$6$rounds=5129"))
+
+    # gpg decryption enabled.
+    # both virtual attributes specified, rounds specified
+    # both hashes stored in supplementalCredentials, with rounds
+    # Should get values
+    def test_gpg_both_hashes_rounds_stored_hashes_with_rounds(self):
+        self.add_user("CryptSHA512 " +
+                      "CryptSHA256 " +
+                      "CryptSHA512:rounds=5129 " +
+                      "CryptSHA256:rounds=2561")
+
+        out = self._get_password("virtualCryptSHA256;rounds=2561," +
+                                 "virtualCryptSHA512;rounds=5129",
+                                 True)
+
+        self.assertTrue("virtualCryptSHA256:" in out)
+        self.assertTrue("virtualCryptSHA512:" in out)
+        self.assertTrue("rounds=" in out)
+
+        # Should be using the pre computed hash in supplementalCredentials
+        # so it should not change between calls.
+        sha256 = _get_attribute(out, "virtualCryptSHA256")
+        sha512 = _get_attribute(out, "virtualCryptSHA512")
+
+        out = self._get_password("virtualCryptSHA256;rounds=2561," +
+                                 "virtualCryptSHA512;rounds=5129",
+                                 True)
+        self.assertEquals(sha256, _get_attribute(out, "virtualCryptSHA256"))
+        self.assertEquals(sha512, _get_attribute(out, "virtualCryptSHA512"))
+
+        # The returned hashes should specify the correct number of rounds
+        self.assertTrue(sha256.startswith("{CRYPT}$5$rounds=2561"))
+        self.assertTrue(sha512.startswith("{CRYPT}$6$rounds=5129"))
+
+    # gpg decryption enabled.
+    # both virtual attributes specified, rounds specified
+    # both hashes stored in supplementalCredentials, with rounds
+    # number of rounds stored/requested do not match
+    # Should get calculated hashes with the correct number of rounds
+    def test_gpg_both_hashes_rounds_stored_hashes_with_rounds_no_match(self):
+        self.add_user("CryptSHA512 " +
+                      "CryptSHA256 " +
+                      "CryptSHA512:rounds=5129 " +
+                      "CryptSHA256:rounds=2561")
+
+        out = self._get_password("virtualCryptSHA256;rounds=4000," +
+                                 "virtualCryptSHA512;rounds=5000",
+                                 True)
+
+        self.assertTrue("virtualCryptSHA256:" in out)
+        self.assertTrue("virtualCryptSHA512:" in out)
+        self.assertTrue("rounds=" in out)
+
+        # Should be calculating the hashes
+        # so they should change between calls.
+        sha256 = _get_attribute(out, "virtualCryptSHA256")
+        sha512 = _get_attribute(out, "virtualCryptSHA512")
+
+        out = self._get_password("virtualCryptSHA256;rounds=4000," +
+                                 "virtualCryptSHA512;rounds=5000",
+                                 True)
+        self.assertFalse(sha256 == _get_attribute(out, "virtualCryptSHA256"))
+        self.assertFalse(sha512 == _get_attribute(out, "virtualCryptSHA512"))
+
+        # The calculated hashes should specify the correct number of rounds
+        self.assertTrue(sha256.startswith("{CRYPT}$5$rounds=4000"))
+        self.assertTrue(sha512.startswith("{CRYPT}$6$rounds=5000"))
diff --git a/python/samba/tests/samba_tool/user_virtualCryptSHA_userPassword.py b/python/samba/tests/samba_tool/user_virtualCryptSHA_userPassword.py
new file mode 100644
index 00000000000..6c1c6295b85
--- /dev/null
+++ b/python/samba/tests/samba_tool/user_virtualCryptSHA_userPassword.py
@@ -0,0 +1,185 @@
+# Tests for the samba-tool user sub command reading Primary:userPassword
+#
+# Copyright (C) Andrew Bartlett <abartlet at samba.org> 2017
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License


-- 
Samba Shared Repository



More information about the samba-cvs mailing list