mirror of
https://github.com/samba-team/samba.git
synced 2024-12-27 03:21:53 +03:00
1b6d675feb
The smbconf library defines an enum of error codes that can be returned from the C calls. The error codes were getting stored in the python SMBConfError type but it was not easy to access or obvious what the integer code represented. This change makes it easier to get the returned error code: via a `error_code` attribute on the exception value. It also exposes the integer constants to the module. Simple tests for a few of the more obvious error codes check that this new error handling correctly exposes the error code values. Signed-off-by: John Mulligan <jmulligan@redhat.com> Reviewed-by: Andreas Schneider <asn@samba.org> Reviewed-by: Guenther Deschner <gd@samba.org> Autobuild-User(master): Günther Deschner <gd@samba.org> Autobuild-Date(master): Wed Jun 8 13:13:10 UTC 2022 on sn-devel-184
353 lines
11 KiB
Python
353 lines
11 KiB
Python
# Unix SMB/CIFS implementation.
|
|
# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007
|
|
# Copyright (C) John Mulligan <phlogistonjohn@asynchrono.us> 2022
|
|
#
|
|
# 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.smbconf module
|
|
"""
|
|
|
|
from samba.samba3 import param as s3param
|
|
import samba.tests
|
|
|
|
|
|
class SMBConfTests(samba.tests.TestCase):
|
|
_smbconf = None
|
|
_s3smbconf = None
|
|
|
|
@property
|
|
def smbconf(self):
|
|
"""Property to access module under test without
|
|
importing it at test module load-time.
|
|
"""
|
|
if self._smbconf is not None:
|
|
return self._smbconf
|
|
|
|
import samba.smbconf
|
|
|
|
self._smbconf = samba.smbconf
|
|
return self._smbconf
|
|
|
|
@property
|
|
def s3smbconf(self):
|
|
if self._s3smbconf is not None:
|
|
return self._s3smbconf
|
|
|
|
import samba.samba3.smbconf
|
|
|
|
self._s3smbconf = samba.samba3.smbconf
|
|
return self._s3smbconf
|
|
|
|
@property
|
|
def example_conf_default(self):
|
|
return "./testdata/samba3/smb.conf"
|
|
|
|
def setUp(self):
|
|
super().setUp()
|
|
# fetch the configuration in the same style as other test suites
|
|
self.lp_ctx = samba.tests.env_loadparm()
|
|
# apply the configuration to the samba3 configuration
|
|
# (because there are two... and they're independent!)
|
|
# this is needed to make use of the registry
|
|
s3_lp = s3param.get_context()
|
|
s3_lp.load(self.lp_ctx.configfile)
|
|
|
|
def test_uninitalized_smbconf(self):
|
|
sconf = self.smbconf.SMBConf()
|
|
self.assertRaises(RuntimeError, sconf.requires_messaging)
|
|
self.assertRaises(RuntimeError, sconf.is_writeable)
|
|
self.assertRaises(RuntimeError, sconf.share_names)
|
|
self.assertRaises(RuntimeError, sconf.get_share, "foo")
|
|
|
|
def test_txt_backend_properties(self):
|
|
sconf = self.smbconf.init_txt(self.example_conf_default)
|
|
self.assertFalse(sconf.requires_messaging())
|
|
self.assertFalse(sconf.is_writeable())
|
|
|
|
def test_share_names(self):
|
|
sconf = self.smbconf.init_txt(self.example_conf_default)
|
|
names = sconf.share_names()
|
|
self.assertEqual(names, ["global", "cd1", "cd2", "media", "tmp"])
|
|
|
|
def test_get_share_cd1(self):
|
|
sconf = self.smbconf.init_txt(self.example_conf_default)
|
|
s1 = sconf.get_share("cd1")
|
|
self.assertEqual(s1, ("cd1", [("path", "/mnt/cd1"), ("public", "yes")]))
|
|
|
|
def test_get_share_cd2(self):
|
|
sconf = self.smbconf.init_txt(self.example_conf_default)
|
|
s1 = sconf.get_share("cd2")
|
|
self.assertEqual(s1, ("cd2", [("path", "/mnt/cd2"), ("public", "yes")]))
|
|
|
|
def test_get_config(self):
|
|
sconf = self.smbconf.init_txt(self.example_conf_default)
|
|
services = sconf.get_config()
|
|
self.assertEqual(len(services), 5)
|
|
self.assertEqual(
|
|
services[0],
|
|
(
|
|
"global",
|
|
[
|
|
("workgroup", "SAMBA"),
|
|
("security", "user"),
|
|
(
|
|
"passdb backend",
|
|
"smbpasswd:../testdata/samba3/smbpasswd "
|
|
"tdbsam:../testdata/samba3/passdb.tdb ldapsam:tdb://samba3.ldb",
|
|
),
|
|
("debug level", "5"),
|
|
("netbios name", "BEDWYR"),
|
|
],
|
|
),
|
|
)
|
|
self.assertEqual(
|
|
services[1], ("cd1", [("path", "/mnt/cd1"), ("public", "yes")])
|
|
)
|
|
|
|
def test_init_reg(self):
|
|
sconf = self.s3smbconf.init_reg(None)
|
|
self.assertTrue(sconf.is_writeable())
|
|
|
|
def test_init_str_reg(self):
|
|
sconf = self.s3smbconf.init("registry:")
|
|
self.assertTrue(sconf.is_writeable())
|
|
|
|
def test_init_str_file(self):
|
|
sconf = self.s3smbconf.init(f"file:{self.example_conf_default}")
|
|
self.assertFalse(sconf.is_writeable())
|
|
|
|
def test_create_share(self):
|
|
sconf = self.s3smbconf.init_reg(None)
|
|
sconf.drop()
|
|
sconf.create_share("alice")
|
|
sconf.create_share("bob")
|
|
names = sconf.share_names()
|
|
self.assertEqual(names, ["alice", "bob"])
|
|
self.assertRaises(
|
|
self.smbconf.SMBConfError, sconf.create_share, "alice"
|
|
)
|
|
|
|
def test_create_share(self):
|
|
sconf = self.s3smbconf.init_reg(None)
|
|
sconf.drop()
|
|
sconf.create_share("alice")
|
|
sconf.drop()
|
|
names = sconf.share_names()
|
|
self.assertEqual(names, [])
|
|
|
|
def test_set_parameter(self):
|
|
sconf = self.s3smbconf.init_reg(None)
|
|
sconf.drop()
|
|
sconf.create_share("foobar")
|
|
sconf.set_parameter("foobar", "path", "/mnt/foobar")
|
|
sconf.set_parameter("foobar", "browseable", "no")
|
|
|
|
s1 = sconf.get_share("foobar")
|
|
self.assertEqual(
|
|
s1, ("foobar", [("path", "/mnt/foobar"), ("browseable", "no")])
|
|
)
|
|
|
|
def test_set_global_parameter(self):
|
|
sconf = self.s3smbconf.init_reg(None)
|
|
sconf.drop()
|
|
sconf.set_global_parameter("workgroup", "EXAMPLE")
|
|
sconf.set_global_parameter("x:custom", "fake")
|
|
|
|
s1 = sconf.get_share("global")
|
|
self.assertEqual(
|
|
s1, ("global", [("workgroup", "EXAMPLE"), ("x:custom", "fake")])
|
|
)
|
|
|
|
def test_delete_share(self):
|
|
sconf = self.s3smbconf.init_reg(None)
|
|
sconf.drop()
|
|
|
|
sconf.create_share("alice")
|
|
sconf.create_share("bob")
|
|
names = sconf.share_names()
|
|
self.assertEqual(names, ["alice", "bob"])
|
|
|
|
sconf.delete_share("alice")
|
|
names = sconf.share_names()
|
|
self.assertEqual(names, ["bob"])
|
|
|
|
def test_create_set_share(self):
|
|
sconf = self.s3smbconf.init_reg(None)
|
|
sconf.drop()
|
|
|
|
params = [
|
|
("path", "/mnt/baz"),
|
|
("browseable", "yes"),
|
|
("read only", "no"),
|
|
]
|
|
sconf.create_set_share("baz", params)
|
|
self.assertEqual(sconf.get_share("baz"), ("baz", params))
|
|
|
|
self.assertRaises(
|
|
self.smbconf.SMBConfError, sconf.create_set_share, "baz", params
|
|
)
|
|
self.assertRaises(TypeError, sconf.create_set_share, "baz", None)
|
|
self.assertRaises(
|
|
ValueError, sconf.create_set_share, "baz", [None, None]
|
|
)
|
|
self.assertRaises(
|
|
TypeError, sconf.create_set_share, "baz", [("hi", None)]
|
|
)
|
|
self.assertRaises(
|
|
ValueError, sconf.create_set_share, "baz", [("a", "b", "c")]
|
|
)
|
|
|
|
def test_delete_parameter(self):
|
|
sconf = self.s3smbconf.init_reg(None)
|
|
sconf.drop()
|
|
|
|
params = [
|
|
("path", "/mnt/baz"),
|
|
("browseable", "yes"),
|
|
("read only", "no"),
|
|
]
|
|
sconf.create_set_share("baz", params)
|
|
self.assertEqual(sconf.get_share("baz"), ("baz", params))
|
|
|
|
sconf.delete_parameter("baz", "browseable")
|
|
self.assertEqual(
|
|
sconf.get_share("baz"),
|
|
(
|
|
"baz",
|
|
[
|
|
("path", "/mnt/baz"),
|
|
("read only", "no"),
|
|
],
|
|
),
|
|
)
|
|
|
|
def test_delete_global_parameter(self):
|
|
sconf = self.s3smbconf.init_reg(None)
|
|
sconf.drop()
|
|
sconf.set_global_parameter("workgroup", "EXAMPLE")
|
|
sconf.set_global_parameter("client min protocol", "NT1")
|
|
sconf.set_global_parameter("server min protocol", "SMB2")
|
|
|
|
s1 = sconf.get_share("global")
|
|
self.assertEqual(
|
|
s1,
|
|
(
|
|
"global",
|
|
[
|
|
("workgroup", "EXAMPLE"),
|
|
("client min protocol", "NT1"),
|
|
("server min protocol", "SMB2"),
|
|
],
|
|
),
|
|
)
|
|
|
|
sconf.delete_global_parameter("server min protocol")
|
|
sconf.delete_global_parameter("client min protocol")
|
|
s1 = sconf.get_share("global")
|
|
self.assertEqual(s1, ("global", [("workgroup", "EXAMPLE")]))
|
|
|
|
def test_transaction_direct(self):
|
|
sconf = self.s3smbconf.init_reg(None)
|
|
sconf.drop()
|
|
sconf.set_global_parameter("workgroup", "EXAMPLE")
|
|
|
|
sconf.transaction_start()
|
|
sconf.set_global_parameter("client min protocol", "NT1")
|
|
sconf.set_global_parameter("server min protocol", "SMB2")
|
|
sconf.transaction_cancel()
|
|
|
|
s1 = sconf.get_share("global")
|
|
self.assertEqual(s1, ("global", [("workgroup", "EXAMPLE")]))
|
|
|
|
sconf.transaction_start()
|
|
sconf.set_global_parameter("client min protocol", "NT1")
|
|
sconf.set_global_parameter("server min protocol", "SMB2")
|
|
sconf.transaction_commit()
|
|
|
|
s1 = sconf.get_share("global")
|
|
self.assertEqual(
|
|
s1,
|
|
(
|
|
"global",
|
|
[
|
|
("workgroup", "EXAMPLE"),
|
|
("client min protocol", "NT1"),
|
|
("server min protocol", "SMB2"),
|
|
],
|
|
),
|
|
)
|
|
|
|
def test_transaction_tryexc(self):
|
|
sconf = self.s3smbconf.init_reg(None)
|
|
sconf.drop()
|
|
|
|
def _mkshares(shares):
|
|
sconf.transaction_start()
|
|
try:
|
|
for name, params in shares:
|
|
sconf.create_set_share(name, params)
|
|
sconf.transaction_commit()
|
|
except Exception:
|
|
sconf.transaction_cancel()
|
|
raise
|
|
|
|
_mkshares(
|
|
[
|
|
("hello", [("path", "/srv/world")]),
|
|
("goodnight", [("path", "/srv/moon")]),
|
|
]
|
|
)
|
|
# this call to _mkshares will fail the whole transaction because
|
|
# share name "goodnight" already exists
|
|
self.assertRaises(
|
|
self.smbconf.SMBConfError,
|
|
_mkshares,
|
|
[
|
|
("mars", [("path", "/srv/mars")]),
|
|
("goodnight", [("path", "/srv/phobos")]),
|
|
],
|
|
)
|
|
|
|
names = sconf.share_names()
|
|
self.assertEqual(names, ["hello", "goodnight"])
|
|
|
|
def test_error_badfile(self):
|
|
with self.assertRaises(self.smbconf.SMBConfError) as raised:
|
|
self.smbconf.init_txt("/foo/bar/baz/_I-dont/.exist/-ok-")
|
|
self.assertEqual(
|
|
self.smbconf.SBC_ERR_BADFILE, raised.exception.error_code)
|
|
|
|
def test_error_not_supported(self):
|
|
sconf = self.smbconf.init_txt(self.example_conf_default)
|
|
with self.assertRaises(self.smbconf.SMBConfError) as raised:
|
|
sconf.set_global_parameter("client min protocol", "NT1")
|
|
self.assertEqual(
|
|
self.smbconf.SBC_ERR_NOT_SUPPORTED, raised.exception.error_code)
|
|
|
|
def test_error_no_such_service(self):
|
|
sconf = self.smbconf.init_txt(self.example_conf_default)
|
|
with self.assertRaises(self.smbconf.SMBConfError) as raised:
|
|
sconf.get_share("zilch"),
|
|
self.assertEqual(
|
|
self.smbconf.SBC_ERR_NO_SUCH_SERVICE, raised.exception.error_code)
|
|
|
|
|
|
|
|
if __name__ == "__main__":
|
|
import unittest
|
|
|
|
unittest.main()
|