Bug 14118 - samba-tool user create fails with non-ASCII usernames and python2
Summary: samba-tool user create fails with non-ASCII usernames and python2
Status: RESOLVED WONTFIX
Alias: None
Product: Samba 4.1 and newer
Classification: Unclassified
Component: Python (show other bugs)
Version: 4.10.8
Hardware: All All
: P5 normal (vote)
Target Milestone: ---
Assignee: Douglas Bagnall
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-09-05 11:05 UTC by Björn Baumbach
Modified: 2020-01-08 11:49 UTC (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Björn Baumbach 2019-09-05 11:05:53 UTC
Running "samba-tool user create" with python2 fails if the username includes non-ASCII characters.

Example:

# samba-tool user create Björn Passw0rd
ERROR(<type 'exceptions.UnicodeDecodeError'>): Failed to add user 'Björn':  - 'ascii' codec can't decode byte 0xc3 in position 10: ordinal not in range(128)
  File "/usr/lib/python2.7/dist-packages/samba/netcmd/user.py", line 433, in run
    smartcard_required=smartcard_required)
  File "/usr/lib/python2.7/dist-packages/samba/samdb.py", line 493, in newuser
    force_password_change_at_next_login_req)
  File "/usr/lib/python2.7/dist-packages/samba/samdb.py", line 609, in setpassword
    """ % (user_dn, base64.b64encode(pw).decode('utf-8'))

The .decode('utf-8'), which fails here, has been introduced with a45e70bf47cb4b48f69a237298e143f574bf58bb, which works fine with Python3, but not with Python2.
Comment 1 Douglas Bagnall 2019-09-05 22:15:01 UTC
Thanks Björn.

I am a little baffled by this, since the thing being .decode()ed is the base64 encoded password, right? which should be ascii only since it is base64.

The 0xC3 it complains about is more likely part of the 0xC3 0xB6 sequence for "ö",
and the position 10 is about right for "\ndn: CN=Björn,...", so I suspect the user_dn is at fault.

What do you see if you print the user_dn first?:

diff --git a/python/samba/samdb.py b/python/samba/samdb.py
index 308b5f96a7b..20fdf9d0f02 100644
--- a/python/samba/samdb.py
+++ b/python/samba/samdb.py
@@ -596,6 +596,7 @@ member: %s
             if len(res) > 1:
                 raise Exception('Matched %u multiple users with filter "%s"' % (len(res), search_filter))
             user_dn = res[0].dn
+            print(user_dn, type(user_dn))
+            print("%s" % user_dn)
             if not isinstance(password, text_type):
                 pw = password.decode('utf-8')
             else:
Comment 2 Björn Baumbach 2019-09-06 09:05:35 UTC
(In reply to Douglas Bagnall from comment #1)
> What do you see if you print the user_dn first?

I see the following:

# samba-tool user create Björn Passw0rd
(Dn('CN=Bj\xc3\xb6rn,CN=Users,DC=X,DC=X'), <type 'ldb.Dn'>)
CN=Björn,CN=Users,DC=X,DC=X

I could also decode('utf-8') the user_dn string (from the ldb.Dn), but then the following modify_ldif() complains and required an encode('utf-8').
Comment 3 Douglas Bagnall 2019-09-06 10:52:48 UTC
(In reply to Björn Baumbach from comment #2)
> # samba-tool user create Björn Passw0rd
> (Dn('CN=Bj\xc3\xb6rn,CN=Users,DC=X,DC=X'), <type 'ldb.Dn'>)
> CN=Björn,CN=Users,DC=X,DC=X

I can't work out why that 'print("%s" % user_dn)' worked when the original
'"dn: %s..." %(user_dn, ...)' did not, but never mind.

I think we'll have to go:

from samba.compat import PY3 

and then in setpassword:

   if not PY3:
       user_dn = whatever_is_necessary(user_dn)


Unfortunately, it looks like other methods will have similar problems (setexpiry for example).

It doesn't have to be excessively pretty, since this problem is necessarily unique to 4.10.
Comment 4 Amit Kumar 2019-09-09 07:08:42 UTC
On samba DC using PY3 user can be created!
# samba-tool -V
4.10.6

# samba-tool user create Björn Passw0rd
User 'Björn' created successfully
Comment 5 Björn Jacke 2020-01-08 11:49:06 UTC
looks like this will not change any more in 4.10. I close this as wontfix. As this is 4.10 with py2 only, this is not too bad to ignore now I guess. If someone has a fix before 4.10 is out of bugfix mode just reopen this again.