[SCM] Samba Shared Repository - branch master updated
Andrew Bartlett
abartlet at samba.org
Thu Dec 24 06:17:02 UTC 2015
The branch, master has been updated
via 5b1a87e dsdb subnets: warn when an IPv6 address is in IPv4 embedding range
via 906a53f samldb: ensure subnets have proper net ranges
via cbb9397 samba-tool: add sites subnet subcommands
via 8e6f2d9 samba-tool tests: Add command line tests for sites
via 12813ea python/sites: Rework site DN construction
via dbcb13c python.sites tests: remove excessive transaction management
via bdb03c5 selftest: Allow sites test to run against a remote ldap:// host
via 9ac5e3c samba.sites: reduce code duplication in Exception classes
via 358c0f2 dsdb.tests.sites: don't use global database, tidy long lines
via b27dcb5 samba.sites: improve grammar in an error message
via f26b227 dsdb.tests.sites: merge interdependent tests
via fa2c668 samba-tool sites: use -H to set URL with standard handling
via bb64abf sambatool sites: PEP8/flake8 improvements
via 149c075 torture/gentest time_skew(): don't use labs() on unsigned NTTIME
via d098e9c repl: Skip new subdomains and partitions when replicating
from 8091f84 s4:samba-tool domain raise tool - make it aware of newer domain function levels
https://git.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 5b1a87e344f192ae6c43e11c5e62e5cabf8520d3
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Wed Dec 23 12:44:31 2015 +1300
dsdb subnets: warn when an IPv6 address is in IPv4 embedding range
We fail on these ones, and it isn't immediately obvious why. Windows
also fails on *most* of them, but succeeds on "::ffff:0:0" which is a
bit strange but there you go.
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Pair-programmed-with: Garming Sam <garming at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Autobuild-User(master): Andrew Bartlett <abartlet at samba.org>
Autobuild-Date(master): Thu Dec 24 07:16:25 CET 2015 on sn-devel-144
commit 906a53f442797942e29c899fb7a54a92f970e67e
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Wed Sep 23 15:10:56 2015 +1200
samldb: ensure subnets have proper net ranges
A subnet name needs to be a valid CIDR address range -- that's the
ones that look like 10.9.8.0/22, where the number after the /
determines how many bits are in the address suffix. It can be IPv4 or
IPv6. There are a few odd constraints (see MS-ADTS v20150630
6.1.1.2.2.2.1 "Subnet Object") -- for example, with IPv4, the implied
bit mask can't equal the address. That is, you can't have a subnet
named "255.255.255.0/24" in a Windows subnet. This rule does not apply
to IPv6.
Windows and Samba both make some ensure that subnets have a unique
valid name, though unfortunately Windows 2008R2 is rather slack when
it comes to IPv6. We follow Windows 2012R2, which roughly follows
RFC5952 -- with one caveat: Windows will allow an address like
"::ffff:0:1:2", which translates to the IPv4 address "0.1.0.2" using
the SIIT translation scheme, and which inet_ntop() would render as
"::ffff:0:0.1.0.2". In the Samba implementation we use an inet_pton()/
inet_ntop() round-trip to establish canonicality, so these addresses
fail. Windows wisely does not allow the SIIT style addresses (the
acronym is widely agreed to be off-by-one in the second letter), and
it will regard "::ffff:0:1:2" as simply "::ffff:0:1:2" and allow it.
We would like to do that too.
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit cbb93977cd0e427ba83c2f3dff31668901ad4699
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Wed Oct 28 12:20:37 2015 +1300
samba-tool: add sites subnet subcommands
This allows you to add, remove, or shift subnets.
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 8e6f2d923c9fc4249d162c8731fbbf5b44e87936
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Thu Sep 17 18:16:49 2015 +1200
samba-tool tests: Add command line tests for sites
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 12813ea55518f7f953a80041e8d5dd1ae2107510
Author: Andrew Bartlett <abartlet at samba.org>
Date: Thu Oct 29 16:34:27 2015 +1300
python/sites: Rework site DN construction
This new routine is safe against escape characters and works
against Windows 2012R2.
The dn= filter in the old code was samba-specific.
Andrew Bartlett
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
commit dbcb13cb055f47926901e442d09ecb6fa77d1502
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Thu Oct 29 14:54:15 2015 +1300
python.sites tests: remove excessive transaction management
These are atomic anyway.
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
commit bdb03c52296ba2af20c2d8c1bd0f017d9f01b9cc
Author: Andrew Bartlett <abartlet at samba.org>
Date: Wed Oct 28 15:26:12 2015 +1300
selftest: Allow sites test to run against a remote ldap:// host
The previous code was just broken
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
commit 9ac5e3cf30c62d4a83122e5b9c1b3ef253f126e8
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Thu Sep 17 18:07:32 2015 +1200
samba.sites: reduce code duplication in Exception classes
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit 358c0f20ccad2063bfab1b4c05a0709951960389
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Thu Sep 17 18:28:09 2015 +1200
dsdb.tests.sites: don't use global database, tidy long lines
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit b27dcb5bcabf3289de6a81b4a6e740e3c4f7d469
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Thu Sep 17 18:10:03 2015 +1200
samba.sites: improve grammar in an error message
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit f26b227041e90b48c3ad659b461b82fed4fe0bfe
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Thu Sep 17 11:35:55 2015 +1200
dsdb.tests.sites: merge interdependent tests
The delete test deleted the site made by the create test, which worked
because "delete" sorts after "create" alphabetically. By themselves,
"delete" would fail and "create" would neglect its duty to clean up.
This would be an issue if the order of tests changes, if one of the
tests is not run, or if another test appears in between. Everything is
fine if they give up the pretense of independence.
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit fa2c6685c933e44bd504ff98200dc21d3167285a
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Wed Sep 16 14:17:25 2015 +1200
samba-tool sites: use -H to set URL with standard handling
samba-tool sites was defaulting to the local database, but we might
want to use another URL. This allows that case while defaulting to
the old behaviour.
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit bb64abf9540118b739ac981eb7f7f2537aceafdd
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Thu Sep 17 18:30:28 2015 +1200
sambatool sites: PEP8/flake8 improvements
We were nearly there, so lets make the jump. This involves removing
some unused variables.
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
commit 149c0756b47bbf39a87545caabbb16866319871e
Author: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Date: Tue Dec 22 14:18:19 2015 +1300
torture/gentest time_skew(): don't use labs() on unsigned NTTIME
Signed-off-by: Douglas Bagnall <douglas.bagnall at catalyst.net.nz>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet at samba.org>
commit d098e9c4ba90f23589611efbe38c6f5ac4368e16
Author: Andrew Bartlett <abartlet at samba.org>
Date: Mon Dec 21 16:40:28 2015 +1300
repl: Skip new subdomains and partitions when replicating
These will need to be handled later, but probably via reading the cross-ref objects.
This avoids total failure when cloning a DC that has
subdomains.
Signed-off-by: Andrew Bartlett <abartlet at samba.org>
Reviewed-by: Garming Sam <garming at catalyst.net.nz>
-----------------------------------------------------------------------
Summary of changes:
python/samba/netcmd/sites.py | 163 ++++++++++--
python/samba/sites.py | 52 ++--
python/samba/subnets.py | 186 +++++++++++++
python/samba/tests/samba_tool/sites.py | 136 ++++++++++
source4/dsdb/repl/replicated_objects.c | 49 +++-
source4/dsdb/samdb/ldb_modules/samldb.c | 279 ++++++++++++++++++++
source4/dsdb/tests/python/sites.py | 447 +++++++++++++++++++++++++++++---
source4/selftest/tests.py | 2 +
source4/torture/gentest.c | 7 +-
9 files changed, 1236 insertions(+), 85 deletions(-)
create mode 100644 python/samba/subnets.py
create mode 100644 python/samba/tests/samba_tool/sites.py
Changeset truncated at 500 lines:
diff --git a/python/samba/netcmd/sites.py b/python/samba/netcmd/sites.py
index 09df55e..f0c792d 100644
--- a/python/samba/netcmd/sites.py
+++ b/python/samba/netcmd/sites.py
@@ -16,15 +16,15 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
-import os
-from samba import sites
+from samba import sites, subnets
from samba.samdb import SamDB
import samba.getopt as options
from samba.auth import system_session
from samba.netcmd import (
Command,
CommandError,
- SuperCommand
+ SuperCommand,
+ Option,
)
@@ -41,26 +41,30 @@ class cmd_sites_create(Command):
"credopts": options.CredentialsOptions,
}
- def run(self, sitename, sambaopts=None, credopts=None, versionopts=None):
+ takes_options = [
+ Option("-H", "--URL", help="LDB URL for database or target server",
+ type=str, metavar="URL", dest="H"),
+ ]
+
+ def run(self, sitename, H=None, sambaopts=None, credopts=None,
+ versionopts=None):
lp = sambaopts.get_loadparm()
creds = credopts.get_credentials(lp, fallback_machine=True)
- url = lp.private_path("sam.ldb")
-
- if not os.path.exists(url):
- raise CommandError("secret database not found at %s " % url)
- samdb = SamDB(url=url, session_info=system_session(),
+ samdb = SamDB(url=H, session_info=system_session(),
credentials=creds, lp=lp)
samdb.transaction_start()
try:
- ok = sites.create_site(samdb, samdb.get_config_basedn(), sitename)
+ sites.create_site(samdb, samdb.get_config_basedn(), sitename)
samdb.transaction_commit()
except sites.SiteAlreadyExistsException, e:
samdb.transaction_cancel()
- raise CommandError("Error while creating site %s, error: %s" % (sitename, str(e)))
+ raise CommandError("Error while creating site %s, error: %s" %
+ (sitename, str(e)))
self.outf.write("Site %s created !\n" % sitename)
+
class cmd_sites_delete(Command):
"""Delete an existing site."""
@@ -74,19 +78,21 @@ class cmd_sites_delete(Command):
"credopts": options.CredentialsOptions,
}
- def run(self, sitename, sambaopts=None, credopts=None, versionopts=None):
+ takes_options = [
+ Option("-H", "--URL", help="LDB URL for database or target server",
+ type=str, metavar="URL", dest="H"),
+ ]
+
+ def run(self, sitename, H=None, sambaopts=None, credopts=None,
+ versionopts=None):
lp = sambaopts.get_loadparm()
creds = credopts.get_credentials(lp, fallback_machine=True)
- url = lp.private_path("sam.ldb")
-
- if not os.path.exists(url):
- raise CommandError("secret database not found at %s " % url)
- samdb = SamDB(url=url, session_info=system_session(),
- credentials=creds, lp=lp)
+ samdb = SamDB(url=H, session_info=system_session(),
+ credentials=creds, lp=lp)
samdb.transaction_start()
try:
- ok = sites.delete_site(samdb, samdb.get_config_basedn(), sitename)
+ sites.delete_site(samdb, samdb.get_config_basedn(), sitename)
samdb.transaction_commit()
except sites.SiteException, e:
samdb.transaction_cancel()
@@ -96,10 +102,127 @@ class cmd_sites_delete(Command):
self.outf.write("Site %s removed!\n" % sitename)
+class cmd_sites_subnet_create(Command):
+ """Create a new subnet."""
+ synopsis = "%prog <subnet> <site-of-subnet> [options]"
+ takes_args = ["subnetname", "site_of_subnet"]
+
+ takes_optiongroups = {
+ "sambaopts": options.SambaOptions,
+ "versionopts": options.VersionOptions,
+ "credopts": options.CredentialsOptions,
+ }
+
+ takes_options = [
+ Option("-H", "--URL", help="LDB URL for database or target server",
+ type=str, metavar="URL", dest="H"),
+ ]
+
+ def run(self, subnetname, site_of_subnet, H=None, sambaopts=None,
+ credopts=None, versionopts=None):
+ lp = sambaopts.get_loadparm()
+ creds = credopts.get_credentials(lp)
+ samdb = SamDB(url=H, session_info=system_session(),
+ credentials=creds, lp=lp)
+
+ samdb.transaction_start()
+ try:
+ subnets.create_subnet(samdb, samdb.get_config_basedn(), subnetname,
+ site_of_subnet)
+ samdb.transaction_commit()
+ except subnets.SubnetException, e:
+ samdb.transaction_cancel()
+ raise CommandError("Error while creating subnet %s: %s" %
+ (subnetname, e))
+
+ self.outf.write("Subnet %s created !\n" % subnetname)
+
+
+class cmd_sites_subnet_delete(Command):
+ """Delete an existing subnet."""
+
+ synopsis = "%prog <subnet> [options]"
+
+ takes_args = ["subnetname"]
+
+ takes_optiongroups = {
+ "sambaopts": options.SambaOptions,
+ "versionopts": options.VersionOptions,
+ "credopts": options.CredentialsOptions,
+ }
+
+ takes_options = [
+ Option("-H", "--URL", help="LDB URL for database or target server",
+ type=str, metavar="URL", dest="H"),
+ ]
+
+ def run(self, subnetname, H=None, sambaopts=None, credopts=None,
+ versionopts=None):
+ lp = sambaopts.get_loadparm()
+ creds = credopts.get_credentials(lp)
+ samdb = SamDB(url=H, session_info=system_session(),
+ credentials=creds, lp=lp)
+
+ samdb.transaction_start()
+ try:
+ subnets.delete_subnet(samdb, samdb.get_config_basedn(), subnetname)
+ samdb.transaction_commit()
+ except subnets.SubnetException, e:
+ samdb.transaction_cancel()
+ raise CommandError("Error while removing subnet %s, error: %s" %
+ (subnetname, e))
+
+ self.outf.write("Subnet %s removed!\n" % subnetname)
+
+
+class cmd_sites_subnet_set_site(Command):
+ """Assign a subnet to a site."""
+ synopsis = "%prog <subnet> <site-of-subnet> [options]"
+ takes_args = ["subnetname", "site_of_subnet"]
+
+ takes_optiongroups = {
+ "sambaopts": options.SambaOptions,
+ "versionopts": options.VersionOptions,
+ "credopts": options.CredentialsOptions,
+ }
+
+ takes_options = [
+ Option("-H", "--URL", help="LDB URL for database or target server",
+ type=str, metavar="URL", dest="H"),
+ ]
+
+ def run(self, subnetname, site_of_subnet, H=None, sambaopts=None,
+ credopts=None, versionopts=None):
+ lp = sambaopts.get_loadparm()
+ creds = credopts.get_credentials(lp)
+ samdb = SamDB(url=H, session_info=system_session(),
+ credentials=creds, lp=lp)
+
+ samdb.transaction_start()
+ try:
+ subnets.set_subnet_site(samdb, samdb.get_config_basedn(),
+ subnetname, site_of_subnet)
+ samdb.transaction_commit()
+ except subnets.SubnetException, e:
+ samdb.transaction_cancel()
+ raise CommandError("Error assigning subnet %s to site %s: %s" %
+ (subnetname, site_of_subnet, e))
+
+ print >> self.outf, ("Subnet %s shifted to site %s" %
+ (subnet_name, site_of_subnet))
+
+
+class cmd_sites_subnet(SuperCommand):
+ """Subnet management subcommands."""
+ subcommands = {
+ "create": cmd_sites_subnet_create(),
+ "remove": cmd_sites_subnet_delete(),
+ "set-site": cmd_sites_subnet_set_site(),
+ }
class cmd_sites(SuperCommand):
"""Sites management."""
-
subcommands = {}
subcommands["create"] = cmd_sites_create()
subcommands["remove"] = cmd_sites_delete()
+ subcommands["subnet"] = cmd_sites_subnet()
diff --git a/python/samba/sites.py b/python/samba/sites.py
index 76c57dd..7111cfa 100644
--- a/python/samba/sites.py
+++ b/python/samba/sites.py
@@ -18,7 +18,7 @@
"""Manipulating sites."""
import ldb
-from ldb import FLAG_MOD_ADD
+from ldb import FLAG_MOD_ADD, LdbError
class SiteException(Exception):
@@ -28,35 +28,20 @@ class SiteException(Exception):
self.value = value
def __str__(self):
- return "SiteException: " + self.value
+ return "%s: %s" % (self.__class__.__name__, self.value)
class SiteNotFoundException(SiteException):
"""Raised when the site is not found and it's expected to exists."""
- def __init__(self, value):
- self.value = value
-
- def __str__(self):
- return "SiteNotFoundException: " + self.value
class SiteAlreadyExistsException(SiteException):
"""Raised when the site is not found and it's expected not to exists."""
- def __init__(self, value):
- self.value = value
-
- def __str__(self):
- return "SiteAlreadyExists: " + self.value
class SiteServerNotEmptyException(SiteException):
"""Raised when the site still has servers attached."""
- def __init__(self, value):
- self.value = value
-
- def __str__(self):
- return "SiteServerNotEmpty: " + self.value
def create_site(samdb, configDn, siteName):
"""
@@ -94,6 +79,7 @@ def create_site(samdb, configDn, siteName):
return True
+
def delete_site(samdb, configDn, siteName):
"""
Delete a site
@@ -106,17 +92,27 @@ def delete_site(samdb, configDn, siteName):
:raise SiteServerNotEmpty: if the site has still servers in it.
"""
- dnsites = ldb.Dn(samdb, "CN=Sites,%s" % (str(configDn)))
- dnsite = ldb.Dn(samdb, "Cn=%s,CN=Sites,%s" % (siteName, str(configDn)))
- dnserver = ldb.Dn(samdb, "Cn=Servers,%s" % str(dnsite))
-
- ret = samdb.search(base=dnsites, scope=ldb.SCOPE_ONELEVEL,
- expression='(dn=%s)' % str(dnsite))
- if len(ret) != 1:
- raise SiteNotFoundException('Site %s do not exists' % siteName)
-
- ret = samdb.search(base=dnserver, scope=ldb.SCOPE_ONELEVEL,
- expression='(objectclass=server)')
+ dnsite = ldb.Dn(samdb, "CN=Sites")
+ if dnsite.add_base(configDn) == False:
+ raise SiteException("dnsites.add_base() failed")
+ if dnsite.add_child("CN=X") == False:
+ raise SiteException("dnsites.add_child() failed")
+ dnsite.set_component(0, "CN", siteName)
+
+ dnservers = ldb.Dn(samdb, "CN=Servers")
+ dnservers.add_base(dnsite)
+
+ try:
+ ret = samdb.search(base=dnsite, scope=ldb.SCOPE_BASE,
+ expression="objectClass=site")
+ if len(ret) != 1:
+ raise SiteNotFoundException('Site %s does not exist' % siteName)
+ except LdbError as (enum, estr):
+ if enum == ldb.ERR_NO_SUCH_OBJECT:
+ raise SiteNotFoundException('Site %s does not exist' % siteName)
+
+ ret = samdb.search(base=dnservers, scope=ldb.SCOPE_ONELEVEL,
+ expression='(objectclass=server)')
if len(ret) != 0:
raise SiteServerNotEmptyException('Site %s still has servers in it, move them before removal' % siteName)
diff --git a/python/samba/subnets.py b/python/samba/subnets.py
new file mode 100644
index 0000000..e859f06
--- /dev/null
+++ b/python/samba/subnets.py
@@ -0,0 +1,186 @@
+# Add/remove subnets to sites.
+#
+# Copyright (C) Catalyst.Net Ltd 2015
+# Copyright Matthieu Patou <mat at matws.net> 2011
+#
+# Catalyst.Net's contribution was written by Douglas Bagnall
+# <douglas.bagnall at catalyst.net.nz>.
+#
+# 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/>.
+#
+
+import ldb
+from ldb import FLAG_MOD_ADD, FLAG_MOD_REPLACE, LdbError
+from sites import SiteNotFoundException
+
+class SubnetException(Exception):
+ """Base element for Subnet errors"""
+ pass
+
+
+class SubnetNotFound(SubnetException):
+ """The subnet requested does not exist."""
+ pass
+
+
+class SubnetAlreadyExists(SubnetException):
+ """The subnet being added already exists."""
+ pass
+
+
+class SubnetInvalid(SubnetException):
+ """The subnet CIDR is invalid."""
+ pass
+
+
+class SiteNotFound(SubnetException):
+ """The site to be used for the subnet does not exist."""
+ pass
+
+
+def create_subnet(samdb, configDn, subnet_name, site_name):
+ """Create a subnet and associate it with a site.
+
+ :param samdb: A samdb connection
+ :param configDn: The DN of the configuration partition
+ :param subnet_name: name of the subnet to create (a CIDR range)
+ :return: None
+ :raise SubnetAlreadyExists: if the subnet to be created already exists.
+ :raise SiteNotFound: if the site does not exist.
+ """
+ ret = samdb.search(base=configDn, scope=ldb.SCOPE_SUBTREE,
+ expression='(&(objectclass=Site)(cn=%s))' %
+ ldb.binary_encode(site_name))
+ if len(ret) != 1:
+ raise SiteNotFound('A site with the name %s does not exist' %
+ site_name)
+ dn_site = ret[0].dn
+
+ if not isinstance(subnet_name, str):
+ raise SubnetInvalid("%s is not a valid subnet (not a string)" % subnet_name)
+
+ 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)
+
+ try:
+ m = ldb.Message()
+ m.dn = dnsubnet
+ m["objectclass"] = ldb.MessageElement("subnet", FLAG_MOD_ADD,
+ "objectclass")
+ m["siteObject"] = ldb.MessageElement(str(dn_site), FLAG_MOD_ADD,
+ "siteObject")
+ samdb.add(m)
+ except ldb.LdbError as (enum, estr):
+ if enum == ldb.ERR_INVALID_DN_SYNTAX:
+ raise SubnetInvalid("%s is not a valid subnet: %s" % (subnet_name, estr))
+ elif enum == ldb.ERR_ENTRY_ALREADY_EXISTS:
+ # Subnet collisions are checked by exact match only, not
+ # overlapping range. This won't stop you creating
+ # 10.1.1.0/24 when there is already 10.1.0.0/16, or
+ # prevent you from having numerous IPv6 subnets that refer
+ # to the same range (e.g 5::0/16, 5::/16, 5:0:0::/16).
+ raise SubnetAlreadyExists('A subnet with the CIDR %s already exists'
+ % subnet_name)
+ else:
+ raise
+
+
+def delete_subnet(samdb, configDn, subnet_name):
+ """Delete a subnet.
+
+ :param samdb: A samdb connection
+ :param configDn: The DN of the configuration partition
+ :param subnet_name: Name of the subnet to delete
+ :return: None
+ :raise SubnetNotFound: if the subnet to be deleted does not exist.
+ """
+ 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)
+
+ try:
+ ret = samdb.search(base=dnsubnet, scope=ldb.SCOPE_BASE,
+ expression="objectClass=subnet")
+ if len(ret) != 1:
+ raise SubnetNotFound('Subnet %s does not exist' % subnet_name)
+ except LdbError as (enum, estr):
+ if enum == ldb.ERR_NO_SUCH_OBJECT:
+ raise SubnetNotFound('Subnet %s does not exist' % subnet_name)
+
+ samdb.delete(dnsubnet)
+
+
+def set_subnet_site(samdb, configDn, subnet_name, site_name):
+ """Assign a subnet to a site.
+
+ This dissociates the subnet from its previous site.
+
+ :param samdb: A samdb connection
+ :param configDn: The DN of the configuration partition
+ :param subnet_name: Name of the subnet
+ :param site_name: Name of the site
+ :return: None
+ :raise SubnetNotFound: if the subnet does not exist.
+ :raise SiteNotFound: if the site does not exist.
+ """
+
+ 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)
+
+ try:
+ ret = samdb.search(base=dnsubnet, scope=ldb.SCOPE_BASE,
+ expression="objectClass=subnet")
+ if len(ret) != 1:
+ raise SubnetNotFound('Subnet %s does not exist' % subnet_name)
+ except LdbError as (enum, estr):
+ if enum == ldb.ERR_NO_SUCH_OBJECT:
+ raise SubnetNotFound('Subnet %s does not exist' % subnet_name)
+
+ dnsite = ldb.Dn(samdb, "CN=Sites")
+ if dnsite.add_base(configDn) == False:
+ raise SubnetException("dnsites.add_base() failed")
+ if dnsite.add_child("CN=X") == False:
+ raise SubnetException("dnsites.add_child() failed")
+ dnsite.set_component(0, "CN", site_name)
+
+ dnservers = ldb.Dn(samdb, "CN=Servers")
+ dnservers.add_base(dnsite)
+
+ try:
+ ret = samdb.search(base=dnsite, scope=ldb.SCOPE_BASE,
+ expression="objectClass=site")
+ if len(ret) != 1:
+ raise SiteNotFoundException('Site %s does not exist' % site_name)
+ except LdbError as (enum, estr):
--
Samba Shared Repository
More information about the samba-cvs
mailing list