mirror of
https://github.com/samba-team/samba.git
synced 2025-02-08 05:57:51 +03:00
subnet: Avoid a segfault when renaming subnet objects
BUG: https://bugzilla.samba.org/show_bug.cgi?id=13031 Signed-off-by: Garming Sam <garming@catalyst.net.nz> Reviewed-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
This commit is contained in:
parent
f2e21e6926
commit
670af37291
@ -127,6 +127,39 @@ def delete_subnet(samdb, configDn, subnet_name):
|
||||
|
||||
samdb.delete(dnsubnet)
|
||||
|
||||
def rename_subnet(samdb, configDn, subnet_name, new_name):
|
||||
"""Rename a subnet.
|
||||
|
||||
:param samdb: A samdb connection
|
||||
:param configDn: The DN of the configuration partition
|
||||
:param subnet_name: Name of the subnet to rename
|
||||
:param new_name: New name for the subnet
|
||||
:return: None
|
||||
:raise SubnetNotFound: if the subnet to be renamed does not exist.
|
||||
:raise SubnetExists: if the subnet to be created already exists.
|
||||
"""
|
||||
dnsubnet = ldb.Dn(samdb, "CN=Subnets,CN=Sites")
|
||||
if dnsubnet.add_base(configDn) == False:
|
||||
raise SubnetException("dnsubnet.add_base() failed")
|
||||
if dnsubnet.add_child("CN=X") == False:
|
||||
raise SubnetException("dnsubnet.add_child() failed")
|
||||
dnsubnet.set_component(0, "CN", subnet_name)
|
||||
|
||||
newdnsubnet = ldb.Dn(samdb, str(dnsubnet))
|
||||
newdnsubnet.set_component(0, "CN", new_name)
|
||||
try:
|
||||
samdb.rename(dnsubnet, newdnsubnet)
|
||||
except LdbError as (enum, estr):
|
||||
if enum == ldb.ERR_NO_SUCH_OBJECT:
|
||||
raise SubnetNotFound('Subnet %s does not exist' % subnet)
|
||||
elif enum == ldb.ERR_ENTRY_ALREADY_EXISTS:
|
||||
raise SubnetAlreadyExists('A subnet with the CIDR %s already exists'
|
||||
% new_name)
|
||||
elif enum == ldb.ERR_INVALID_DN_SYNTAX:
|
||||
raise SubnetInvalid("%s is not a valid subnet: %s" % (new_name,
|
||||
estr))
|
||||
else:
|
||||
raise
|
||||
|
||||
def set_subnet_site(samdb, configDn, subnet_name, site_name):
|
||||
"""Assign a subnet to a site.
|
||||
|
@ -3072,13 +3072,13 @@ static int verify_cidr(const char *cidr)
|
||||
}
|
||||
|
||||
|
||||
static int samldb_verify_subnet(struct samldb_ctx *ac)
|
||||
static int samldb_verify_subnet(struct samldb_ctx *ac, struct ldb_dn *dn)
|
||||
{
|
||||
struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
|
||||
const char *cidr = NULL;
|
||||
const struct ldb_val *rdn_value = NULL;
|
||||
|
||||
rdn_value = ldb_dn_get_rdn_val(ac->msg->dn);
|
||||
rdn_value = ldb_dn_get_rdn_val(dn);
|
||||
if (rdn_value == NULL) {
|
||||
ldb_set_errstring(ldb, "samldb: ldb_dn_get_rdn_val "
|
||||
"failed");
|
||||
@ -3240,7 +3240,7 @@ static int samldb_add(struct ldb_module *module, struct ldb_request *req)
|
||||
|
||||
if (samdb_find_attribute(ldb, ac->msg,
|
||||
"objectclass", "subnet") != NULL) {
|
||||
ret = samldb_verify_subnet(ac);
|
||||
ret = samldb_verify_subnet(ac, ac->msg->dn);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
talloc_free(ac);
|
||||
return ret;
|
||||
@ -3633,7 +3633,7 @@ static int check_rename_constraints(struct ldb_message *msg,
|
||||
|
||||
/* subnet objects */
|
||||
if (samdb_find_attribute(ldb, msg, "objectclass", "subnet") != NULL) {
|
||||
ret = samldb_verify_subnet(ac);
|
||||
ret = samldb_verify_subnet(ac, newdn);
|
||||
if (ret != LDB_SUCCESS) {
|
||||
talloc_free(ac);
|
||||
return ret;
|
||||
|
@ -183,6 +183,51 @@ class SimpleSubnetTests(SitesBaseTests):
|
||||
self.assertRaises(subnets.SubnetNotFound,
|
||||
subnets.delete_subnet, self.ldb, basedn, cidr)
|
||||
|
||||
def test_rename_good_subnet_to_good_subnet(self):
|
||||
"""Make sure that we can rename subnets"""
|
||||
basedn = self.ldb.get_config_basedn()
|
||||
cidr = "10.16.0.0/24"
|
||||
new_cidr = "10.16.1.0/24"
|
||||
|
||||
subnets.create_subnet(self.ldb, basedn, cidr, self.sitename)
|
||||
|
||||
subnets.rename_subnet(self.ldb, basedn, cidr, new_cidr)
|
||||
|
||||
ret = self.ldb.search(base=basedn, scope=SCOPE_SUBTREE,
|
||||
expression='(&(objectclass=subnet)(cn=%s))' % new_cidr)
|
||||
|
||||
self.assertEqual(len(ret), 1, 'Failed to rename subnet %s' % cidr)
|
||||
|
||||
ret = self.ldb.search(base=basedn, scope=SCOPE_SUBTREE,
|
||||
expression='(&(objectclass=subnet)(cn=%s))' % cidr)
|
||||
|
||||
self.assertEqual(len(ret), 0, 'Failed to remove old subnet during rename %s' % cidr)
|
||||
|
||||
subnets.delete_subnet(self.ldb, basedn, new_cidr)
|
||||
|
||||
def test_rename_good_subnet_to_bad_subnet(self):
|
||||
"""Make sure that the CIDR checking runs during rename"""
|
||||
basedn = self.ldb.get_config_basedn()
|
||||
cidr = "10.17.0.0/24"
|
||||
bad_cidr = "10.11.12.0/14"
|
||||
|
||||
subnets.create_subnet(self.ldb, basedn, cidr, self.sitename)
|
||||
|
||||
self.assertRaises(subnets.SubnetInvalid, subnets.rename_subnet,
|
||||
self.ldb, basedn, cidr, bad_cidr)
|
||||
|
||||
ret = self.ldb.search(base=basedn, scope=SCOPE_SUBTREE,
|
||||
expression='(&(objectclass=subnet)(cn=%s))' % bad_cidr)
|
||||
|
||||
self.assertEqual(len(ret), 0, 'Failed to rename subnet %s' % cidr)
|
||||
|
||||
ret = self.ldb.search(base=basedn, scope=SCOPE_SUBTREE,
|
||||
expression='(&(objectclass=subnet)(cn=%s))' % cidr)
|
||||
|
||||
self.assertEqual(len(ret), 1, 'Failed to remove old subnet during rename %s' % cidr)
|
||||
|
||||
subnets.delete_subnet(self.ldb, basedn, cidr)
|
||||
|
||||
def test_create_bad_ranges(self):
|
||||
"""These CIDR ranges all have something wrong with them, and they
|
||||
should all fail."""
|
||||
|
Loading…
x
Reference in New Issue
Block a user