mirror of
https://github.com/samba-team/samba.git
synced 2025-02-25 17:57:42 +03:00
python:tests: Add SAMR password change tests for fips
Signed-off-by: Andreas Schneider <asn@samba.org> Reviewed-by: Alexander Bokovoy <ab@samba.org>
This commit is contained in:
parent
7d54e4b49c
commit
9a3ba502d8
188
python/samba/tests/dcerpc/samr_change_password.py
Normal file
188
python/samba/tests/dcerpc/samr_change_password.py
Normal file
@ -0,0 +1,188 @@
|
||||
# Unix SMB/CIFS implementation.
|
||||
#
|
||||
# Copyright © 2020 Andreas Schneider <asn@samba.org>
|
||||
#
|
||||
# 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/>.
|
||||
#
|
||||
|
||||
"""Tests for samba.dcerpc.samr.password"""
|
||||
|
||||
import os
|
||||
import ctypes
|
||||
import samba.tests
|
||||
|
||||
from samba import crypto, generate_random_password, generate_random_bytes, ntstatus
|
||||
from samba.auth import system_session
|
||||
from samba.credentials import Credentials
|
||||
from samba.credentials import SMB_ENCRYPTION_REQUIRED
|
||||
from samba.dcerpc import samr, security, lsa
|
||||
from samba.samdb import SamDB
|
||||
from samba.tests import RpcInterfaceTestCase
|
||||
|
||||
|
||||
class SamrPasswordTests(RpcInterfaceTestCase):
|
||||
def setUp(self):
|
||||
super(SamrPasswordTests, self).setUp()
|
||||
self.open_samdb()
|
||||
|
||||
self.create_user_account(10000)
|
||||
|
||||
self.remote_server = samba.tests.env_get_var_value('SERVER')
|
||||
self.remote_domain = samba.tests.env_get_var_value('DOMAIN')
|
||||
self.remote_user = samba.tests.env_get_var_value('USERNAME')
|
||||
self.remote_password = samba.tests.env_get_var_value('PASSWORD')
|
||||
self.remote_binding_string = "ncacn_np:%s[krb5]" % (self.remote_server)
|
||||
|
||||
self.remote_creds = Credentials()
|
||||
self.remote_creds.guess(self.lp)
|
||||
self.remote_creds.set_username(self.remote_user)
|
||||
self.remote_creds.set_password(self.remote_password)
|
||||
|
||||
def tearDown(self):
|
||||
super(SamrPasswordTests, self).tearDown()
|
||||
|
||||
samr.Close(self.user_handle)
|
||||
samr.Close(self.domain_handle)
|
||||
samr.Close(self.handle)
|
||||
|
||||
samba.tests.delete_force(self.samdb, self.user_dn)
|
||||
|
||||
#
|
||||
# Open the samba database
|
||||
#
|
||||
def open_samdb(self):
|
||||
self.lp = samba.tests.env_loadparm()
|
||||
|
||||
self.local_creds = Credentials()
|
||||
self.local_creds.guess(self.lp)
|
||||
self.session = system_session()
|
||||
self.samdb = SamDB(session_info=self.session,
|
||||
credentials=self.local_creds,
|
||||
lp=self.lp)
|
||||
|
||||
#
|
||||
# Open a SAMR Domain handle
|
||||
#
|
||||
def open_domain_handle(self):
|
||||
self.handle = self.conn.Connect2(None,
|
||||
security.SEC_FLAG_MAXIMUM_ALLOWED)
|
||||
|
||||
self.domain_sid = self.conn.LookupDomain(self.handle,
|
||||
lsa.String(self.remote_domain))
|
||||
|
||||
self.domain_handle = self.conn.OpenDomain(self.handle,
|
||||
security.SEC_FLAG_MAXIMUM_ALLOWED,
|
||||
self.domain_sid)
|
||||
|
||||
def open_user_handle(self):
|
||||
name = lsa.String(self.user_name)
|
||||
|
||||
rids = self.conn.LookupNames(self.domain_handle, [name])
|
||||
|
||||
self.user_handle = self.conn.OpenUser(self.domain_handle,
|
||||
security.SEC_FLAG_MAXIMUM_ALLOWED,
|
||||
rids[0].ids[0])
|
||||
#
|
||||
# Create a test user account
|
||||
#
|
||||
def create_user_account(self, user_id):
|
||||
self.user_name = ("SAMR_USER_%d" % user_id)
|
||||
self.user_pass = generate_random_password(32, 32)
|
||||
self.user_dn = "cn=%s,cn=users,%s" % (self.user_name, self.samdb.domain_dn())
|
||||
|
||||
samba.tests.delete_force(self.samdb, self.user_dn)
|
||||
|
||||
self.samdb.newuser(self.user_name,
|
||||
self.user_pass,
|
||||
description="Password for " + self.user_name + " is " + self.user_pass,
|
||||
givenname=self.user_name,
|
||||
surname=self.user_name)
|
||||
|
||||
|
||||
def init_samr_CryptPassword(self, password, session_key):
|
||||
|
||||
def encode_pw_buffer(password):
|
||||
data = bytearray([0] * 516)
|
||||
|
||||
p = samba.string_to_byte_array(password.encode('utf-16-le'))
|
||||
plen = len(p)
|
||||
|
||||
b = generate_random_bytes(512 - plen)
|
||||
|
||||
i = 512 - plen
|
||||
data[0:i] = b
|
||||
data[i:i+plen] = p
|
||||
data[512:516] = plen.to_bytes(4, byteorder='little')
|
||||
|
||||
return bytes(data)
|
||||
|
||||
# This is a test, so always allow to encrypt using RC4
|
||||
try:
|
||||
crypto.set_relax_mode()
|
||||
encrypted_blob = samba.arcfour_encrypt(session_key, encode_pw_buffer(password))
|
||||
finally:
|
||||
crypto.set_strict_mode()
|
||||
|
||||
out_blob = samr.CryptPassword()
|
||||
out_blob.data = list(encrypted_blob)
|
||||
|
||||
return out_blob
|
||||
|
||||
|
||||
def test_setUserInfo2_Password(self, password='P@ssw0rd'):
|
||||
self.conn = samr.samr(self.remote_binding_string,
|
||||
self.get_loadparm(),
|
||||
self.remote_creds)
|
||||
self.open_domain_handle()
|
||||
self.open_user_handle()
|
||||
|
||||
password='P@ssw0rd'
|
||||
|
||||
level = 24
|
||||
info = samr.UserInfo24()
|
||||
|
||||
info.password_expired = 0
|
||||
info.password = self.init_samr_CryptPassword(password, self.conn.session_key)
|
||||
|
||||
# If the server is in FIPS mode, it should reject the password change!
|
||||
try:
|
||||
self.conn.SetUserInfo2(self.user_handle, level, info)
|
||||
except samba.NTSTATUSError as e:
|
||||
code = ctypes.c_uint32(e.args[0]).value
|
||||
print(code)
|
||||
if ((code == ntstatus.NT_STATUS_ACCESS_DENIED) and
|
||||
(self.lp.weak_crypto == 'disallowed')):
|
||||
pass
|
||||
else:
|
||||
raise
|
||||
|
||||
|
||||
def test_setUserInfo2_Password_Encrypted(self, password='P@ssw0rd'):
|
||||
self.remote_creds.set_smb_encryption(SMB_ENCRYPTION_REQUIRED)
|
||||
|
||||
self.conn = samr.samr(self.remote_binding_string,
|
||||
self.get_loadparm(),
|
||||
self.remote_creds)
|
||||
self.open_domain_handle()
|
||||
self.open_user_handle()
|
||||
|
||||
password='P@ssw0rd'
|
||||
|
||||
level = 24
|
||||
info = samr.UserInfo24()
|
||||
|
||||
info.password_expired = 0
|
||||
info.password = self.init_samr_CryptPassword(password, self.conn.session_key)
|
||||
|
||||
self.conn.SetUserInfo2(self.user_handle, level, info)
|
@ -93,6 +93,8 @@ planpythontestsuite(
|
||||
os.path.join(samba4srcdir, "..", "third_party", "waf")])
|
||||
planpythontestsuite("fileserver", "samba.tests.smbd_fuzztest")
|
||||
planpythontestsuite("nt4_dc_smb1", "samba.tests.dcerpc.binding")
|
||||
for env in [ 'ad_dc:local', 'ad_dc_fips:local' ]:
|
||||
planpythontestsuite(env, "samba.tests.dcerpc.samr_change_password")
|
||||
|
||||
|
||||
def cmdline(script, *args):
|
||||
|
Loading…
x
Reference in New Issue
Block a user