python/samba.tests: Ensure samba-tool is called with correct python ver.
[samba.git] / python / samba / tests / blackbox / bug13653.py
1 # Black box tests verify bug 13653
2 #
3 # Copyright (C) Catalyst.Net Ltd'. 2018
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
17
18 """Blackbox test verifying bug 13653
19
20 https://bugzilla.samba.org/show_bug.cgi?id=13653
21
22
23 When creating a new user and specifying the local filepath of the sam.ldb DB,
24 it's possible to create an account that you can't actually login with.
25
26 This only happens if the DB is using encrypted secrets and you specify "ldb://"
27 in the sam.ldb path, e.g. "-H ldb://st/ad_dc/private/sam.ldb".
28 The user account will be created, but its secrets will not be encrypted.
29 Attempts to login as the user will then be rejected due to invalid credentials.
30
31 We think this may also cause replication/joins to break.
32
33 You do get a warning about "No encrypted secrets key file" when this happens,
34 although the reason behind this message is not obvious. Specifying a "tdb://"
35 prefix, or not specifying a prefix, works fine.
36
37 Example of the problem below using the ad_dc testenv.
38
39 addc$ bin/samba-tool user create tdb-user pass12#
40       -H tdb://st/ad_dc/private/sam.ldb
41 User 'tdb-user' created successfully
42
43 # HERE: using the "ldb://" prefix generates a warning, but the user is still
44 # created successfully.
45
46 addc$ bin/samba-tool user create ldb-user pass12#
47       -H ldb://st/ad_dc/private/sam.ldb
48 No encrypted secrets key file. Secret attributes will not be encrypted or
49 decrypted
50
51 User 'ldb-user' created successfully
52
53 addc$ bin/samba-tool user create noprefix-user pass12#
54       -H st/ad_dc/private/sam.ldb
55 User 'noprefix-user' created successfully
56
57 addc$ bin/ldbsearch -H ldap://$SERVER -Utdb-user%pass12# '(cn=tdb-user)' dn
58 # record 1
59 dn: CN=tdb-user,CN=Users,DC=addom,DC=samba,DC=example,DC=com
60
61 # Referral
62 ref: ldap://addom.samba.example.com/CN=Configuration,DC=addom,DC=samba,
63      DC=example,DC=com
64
65 # Referral
66 ref: ldap://addom.samba.example.com/DC=DomainDnsZones,DC=addom,DC=samba,
67      DC=example,DC=com
68
69 # Referral
70 ref: ldap://addom.samba.example.com/DC=ForestDnsZones,DC=addom,DC=samba,
71      DC=example,DC=com
72
73 # returned 4 records
74 # 1 entries
75 # 3 referrals
76
77 # HERE: can't login as the user created with "ldb://" prefix
78
79 addc$ bin/ldbsearch -H ldap://$SERVER -Uldb-user%pass12# '(cn=ldb-user)' dn
80 Wrong username or password: kinit for ldb-user@ADDOM.SAMBA.EXAMPLE.COM failed
81 (Client not found in Kerberos database)
82
83 Failed to bind - LDAP error 49 LDAP_INVALID_CREDENTIALS
84                -  <8009030C: LdapErr: DSID-0C0904DC,
85                     comment: AcceptSecurityContext error, data 54e, v1db1> <>
86 Failed to connect to 'ldap://addc' with backend
87     'ldap': LDAP error 49 LDAP_INVALID_CREDENTIALS
88             -  <8009030C: LdapErr: DSID-0C0904DC,
89                comment: AcceptSecurityContext error, data 54e, v1db1> <>
90 Failed to connect to ldap://addc - LDAP error 49 LDAP_INVALID_CREDENTIALS
91     -  <8009030C: LdapErr: DSID-0C0904DC,
92        comment: AcceptSecurityContext error, data 54e, v1db1> <>
93 addc$ bin/ldbsearch -H ldap://$SERVER -Unoprefix-user%pass12#
94       '(cn=noprefix-user)' dn
95 # record 1
96 dn: CN=noprefix-user,CN=Users,DC=addom,DC=samba,DC=example,DC=com
97
98 # Referral
99 ref: ldap://addom.samba.example.com/CN=Configuration,DC=addom,DC=samba,
100     DC=example,DC=com
101
102 # Referral
103 ref: ldap://addom.samba.example.com/DC=DomainDnsZones,DC=addom,DC=samba,
104      DC=example,DC=com
105
106 # Referral
107 ref: ldap://addom.samba.example.com/DC=ForestDnsZones,DC=addom,DC=samba,
108      DC=example,DC=com
109
110 # returned 4 records
111 # 1 entries
112 # 3 referrals
113 """
114
115 from samba.tests import (
116     BlackboxTestCase,
117     BlackboxProcessError,
118     delete_force,
119     env_loadparm)
120 from samba.credentials import Credentials
121 from samba.samdb import SamDB
122 from samba.auth import system_session
123 from os import environ
124
125
126 class Bug13653Tests(BlackboxTestCase):
127
128     # Open a local connection to the SamDB
129     # and load configuration from the OS environment.
130     def setUp(self):
131         super(Bug13653Tests, self).setUp()
132         self.env = environ["TEST_ENV"]
133         self.server = environ["SERVER"]
134         self.prefix = environ["PREFIX_ABS"]
135         lp = env_loadparm()
136         creds = Credentials()
137         session = system_session()
138         creds.guess(lp)
139         self.ldb = SamDB(session_info=session,
140                          credentials=creds,
141                          lp=lp)
142
143     # Delete the user account created by the test case.
144     # The user name is in self.user
145     def tearDown(self):
146         super(Bug13653Tests, self).tearDown()
147         try:
148             dn = "CN=%s,CN=Users,%s" % (self.user, self.ldb.domain_dn())
149             delete_force(self.ldb, dn)
150         except Exception as e:
151             # We ignore any exceptions deleting the user in tearDown
152             # this allows the known fail mechanism to work for this test
153             # so the test can be committed before the fix.
154             # otherwise this delete fails with
155             #   Error(11)  unpacking encrypted secret, data possibly corrupted
156             #   or altered
157             pass
158
159     # Delete the user account created by the test case.
160     # The user name is in self.user
161     def delete_user(self):
162         dn = "CN=%s,CN=Users,%s" % (self.user, self.ldb.domain_dn())
163         try:
164             delete_force(self.ldb, dn)
165         except Exception as e:
166             self.fail(str(e))
167
168     def _test_scheme(self, scheme):
169         """Ensure a user can be created by samba-tool with the supplied scheme
170            and that that user can logon."""
171
172         self.delete_user()
173
174         password = self.random_password()
175         db_path = "%s/%s/%s/private/sam.ldb" % (scheme, self.prefix, self.env)
176         try:
177             command =\
178                 "samba-tool user create %s %s -H %s" % (
179                     self.user, password, db_path)
180             self.check_run(command)
181             command =\
182                 "bin/ldbsearch -H ldap://%s/ -U%s%%%s '(cn=%s)' dn" % (
183                     self.server, self.user, password, self.user)
184             self.check_run(command)
185         except BlackboxProcessError as e:
186             self.fail(str(e))
187
188     def test_tdb_scheme(self):
189         """Ensure a user can be created by samba-tool with the "tbd://" scheme
190            and that that user can logon."""
191
192         self.user = "TDB_USER"
193         self._test_scheme("tdb://")
194
195     def test_mdb_scheme(self):
196         """Ensure a user can be created by samba-tool with the "mdb://" scheme
197            and that that user can logon.
198
199            NOTE: this test is currently in knownfail.d/encrypted_secrets as
200                  sam.ldb is currently a tdb even if the lmdb backend is
201                  selected
202         """
203
204         self.user = "MDB_USER"
205         self._test_scheme("mdb://")
206
207     def test_ldb_scheme(self):
208         """Ensure a user can be created by samba-tool with the "ldb://" scheme
209            and that that user can logon."""
210
211         self.user = "LDB_USER"
212         self._test_scheme("ldb://")