From e3e1edf7b9afe9eec5aa8cdf87321904b1d9710e Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 14 May 2018 13:48:18 +0100 Subject: [PATCH 1/5] s4/setup/tests: Add test for non ascii password setting samba-tool Bug: https://bugzilla.samba.org/show_bug.cgi?id=13435 Signed-off-by: Noel Power --- source4/setup/tests/blackbox_setpassword.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source4/setup/tests/blackbox_setpassword.sh b/source4/setup/tests/blackbox_setpassword.sh index 8055740f101..ccc94c3f05d 100755 --- a/source4/setup/tests/blackbox_setpassword.sh +++ b/source4/setup/tests/blackbox_setpassword.sh @@ -25,6 +25,8 @@ testit "setpassword" $samba_tool user setpassword --configfile=$PREFIX/simple-dc testit "setpassword" $samba_tool user setpassword --configfile=$PREFIX/simple-dc/etc/smb.conf testuser --newpassword=testp@ssw0Rd --must-change-at-next-login +testit "setpassword" $samba_tool user setpassword --configfile=$PREFIX/simple-dc/etc/smb.conf testuser --newpassword=Täst123 --must-change-at-next-login + testit "passwordsettings" $samba_tool domain passwordsettings set --quiet --configfile=$PREFIX/simple-dc/etc/smb.conf --complexity=default --history-length=default --min-pwd-length=default --min-pwd-age=default --max-pwd-age=default --store-plaintext=on exit $failed From f37652788deddf3ad6111789d7ea62e25778cf75 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Mon, 14 May 2018 13:38:20 +0100 Subject: [PATCH 2/5] python/samba: Fix incorrect encode of password In python2 you can encode a 'str' type which doesn't really make sense since it is already bytes (as such). In python3 this isn't possible you can't encode bytes or decode strings. Also because you can call encode on 'str' in python2 it tries to to what you wanted and it implicity calls decode('ascii') before performing the encode. This is why we get mention of ascii codec in the error. This patch should future proof for python3 also. Bug: https://bugzilla.samba.org/show_bug.cgi?id=13435 Signed-off-by: Noel Power --- python/samba/samdb.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/python/samba/samdb.py b/python/samba/samdb.py index 424a648446b..abe434c8578 100644 --- a/python/samba/samdb.py +++ b/python/samba/samdb.py @@ -589,7 +589,11 @@ def setpassword(self, search_filter, password, if len(res) > 1: raise Exception('Matched %u multiple users with filter "%s"' % (len(res), search_filter)) user_dn = res[0].dn - pw = text_type(b'"' + password.encode('utf-8') + b'"', 'utf-8').encode('utf-16-le') + if not isinstance(password, text_type): + pw = password.decode('utf-8') + else: + pw = password + pw = ('"' + pw + '"').encode('utf-16-le') setpw = """ dn: %s changetype: modify From cb1689344f21b09955b3697b2f6e079d192c2f59 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Tue, 15 May 2018 18:27:23 +0100 Subject: [PATCH 3/5] testprogs/blackbox: Add test to set and use password with non-ascii Signed-off-by: Noel Power --- testprogs/blackbox/test_password_settings.sh | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/testprogs/blackbox/test_password_settings.sh b/testprogs/blackbox/test_password_settings.sh index 49d512692f5..1edf2bfa921 100755 --- a/testprogs/blackbox/test_password_settings.sh +++ b/testprogs/blackbox/test_password_settings.sh @@ -64,6 +64,7 @@ testit "reset password policies beside of minimum password age of 0 days" \ TEST_USERNAME="$(mktemp -u alice-XXXXXX)" TEST_PASSWORD="testPaSS@00%" TEST_PASSWORD_NEW="testPaSS@01%" +TEST_PASSWORD_NON_ASCII="Täst123" TEST_PASSWORD_SHORT="secret" TEST_PASSWORD_WEAK="Supersecret" TEST_PRINCIPAL="$TEST_USERNAME@$REALM" @@ -100,6 +101,22 @@ TEST_PASSWORD_OLD=$TEST_PASSWORD TEST_PASSWORD=$TEST_PASSWORD_NEW TEST_PASSWORD_NEW="testPaSS@02%" +testit "kinit with user password" \ + do_kinit $TEST_PRINCIPAL $TEST_PASSWORD || failed=`expr $failed + 1` + +test_smbclient "Test login with user kerberos ccache" \ + "ls" "$SMB_UNC" -k yes || failed=`expr $failed + 1` + +########################################################### +### Change the users password +########################################################### + +testit "change user (non-ascii) password with 'samba-tool user password' (unforced)" \ + $VALGRIND $samba_tool user password -W$DOMAIN -U$TEST_USERNAME%$TEST_PASSWORD -k no --newpassword=$TEST_PASSWORD_NON_ASCII || failed=`expr $failed + 1` + +TEST_PASSWORD_OLD=$TEST_PASSWORD_NEW +TEST_PASSWORD=$TEST_PASSWORD_NON_ASCII + testit "kinit with user password" \ do_kinit $TEST_PRINCIPAL $TEST_PASSWORD || failed=`expr $failed + 1` From 9cf60369598c74b5ad07d25e9110838ba030f16d Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 16 May 2018 16:46:41 +0100 Subject: [PATCH 4/5] s4/libnet: Allow passwords containing non ascii characters to be passed Although we can pass unicode to py_net_change_password unfortunately in Python2 unicode strings are encoded with the default encoding (e.g. ascii) when extracting the unicode string to buffer. In Python3 the default encoding for "s" format is utf8. Use the "es" format instead of "s" so we can specify the encoding so behaviour is correct in py2/py3. Signed-off-by: Noel Power --- source4/libnet/py_net.c | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/source4/libnet/py_net.c b/source4/libnet/py_net.c index 0567dbd6353..6aff373b359 100644 --- a/source4/libnet/py_net.c +++ b/source4/libnet/py_net.c @@ -155,21 +155,26 @@ static PyObject *py_net_change_password(py_net_Object *self, PyObject *args, PyO { union libnet_ChangePassword r; NTSTATUS status; - TALLOC_CTX *mem_ctx; - struct tevent_context *ev; + TALLOC_CTX *mem_ctx = NULL; + struct tevent_context *ev = NULL; const char *kwnames[] = { "newpassword", "oldpassword", "domain", "username", NULL }; - + const char *newpass = NULL; + const char *oldpass = NULL; ZERO_STRUCT(r); - - if (!PyArg_ParseTupleAndKeywords(args, kwargs, "s|sss:change_password", + if (!PyArg_ParseTupleAndKeywords(args, kwargs, "es|esss:change_password", discard_const_p(char *, kwnames), - &r.generic.in.newpassword, - &r.generic.in.oldpassword, + "utf8", + &newpass, + "utf8", + &oldpass, &r.generic.in.domain_name, &r.generic.in.account_name)) { return NULL; } + r.generic.in.newpassword = newpass; + r.generic.in.oldpassword = oldpass; + r.generic.level = LIBNET_CHANGE_PASSWORD_GENERIC; if (r.generic.in.account_name == NULL) { r.generic.in.account_name @@ -200,12 +205,12 @@ static PyObject *py_net_change_password(py_net_Object *self, PyObject *args, PyO r.generic.out.error_string ? r.generic.out.error_string : nt_errstr(status)); - talloc_free(mem_ctx); return NULL; } talloc_free(mem_ctx); - + PyMem_Free(discard_const_p(char,newpass)); + PyMem_Free(discard_const_p(char,oldpass)); Py_RETURN_NONE; } From fc032e55dbd6f2e02a0dec82aed4321b9bae4183 Mon Sep 17 00:00:00 2001 From: Noel Power Date: Wed, 16 May 2018 16:51:34 +0100 Subject: [PATCH 5/5] python/samba/netcmd: net.change_password should be passed string password param which in python2 (is str) is incorrectly encoded before passing to net.change_password. python2 - password is either unicode or str, if str we should decode to get unicode (and then pass to net.change_password). python3 - password is either str or bytes, if bytes then decode (and pass as 'str' to net.change_password). Signed-off-by: Noel Power --- python/samba/netcmd/user.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/python/samba/netcmd/user.py b/python/samba/netcmd/user.py index 4009d6304bf..f211b5158ce 100644 --- a/python/samba/netcmd/user.py +++ b/python/samba/netcmd/user.py @@ -54,7 +54,7 @@ SuperCommand, Option, ) - +from samba.compat import text_type try: import io @@ -713,7 +713,9 @@ def run(self, credopts=None, sambaopts=None, versionopts=None, self.outf.write("Sorry, passwords do not match.\n") try: - net.change_password(password.encode('utf-8')) + if not isinstance(password, text_type): + password = password.decode('utf8') + net.change_password(password) except Exception as msg: # FIXME: catch more specific exception raise CommandError("Failed to change password : %s" % msg)