The Samba-Bugzilla – Attachment 12155 Details for
Bug 11613
Samba-tool fsmo errors out if no fSMORoleOwner attribute found
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Additional patch for v4-4-test
tmp44.diff.txt (text/plain), 17.72 KB, created by
Stefan Metzmacher
on 2016-06-01 07:27:55 UTC
(
hide
)
Description:
Additional patch for v4-4-test
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2016-06-01 07:27:55 UTC
Size:
17.72 KB
patch
obsolete
>From 89fd43d8808f22ea8356b7e0909c96edb973f69c Mon Sep 17 00:00:00 2001 >From: Rowland Penny <rpenny@samba.org> >Date: Thu, 31 Mar 2016 12:07:00 +0100 >Subject: [PATCH] samba-too: Allow 'samba-tool fsmo' to cope with empty or > missing fsmo roles > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=11613 > >Signed-off-by: Rowland Penny <rpenny@samba.org> >Signed-off-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 7583377473ecd3d096c4f924e61a04a84be32a96) >--- > python/samba/netcmd/fsmo.py | 233 ++++++++++++++++++++-------------- > python/samba/tests/samba_tool/fsmo.py | 29 +++++ > source4/selftest/tests.py | 4 + > 3 files changed, 168 insertions(+), 98 deletions(-) > create mode 100644 python/samba/tests/samba_tool/fsmo.py > >diff --git a/python/samba/netcmd/fsmo.py b/python/samba/netcmd/fsmo.py >index 3904bcb..3d14939 100644 >--- a/python/samba/netcmd/fsmo.py >+++ b/python/samba/netcmd/fsmo.py >@@ -31,17 +31,26 @@ from samba.netcmd import ( > ) > from samba.samdb import SamDB > >-def get_fsmo_roleowner(samdb, roledn): >+def get_fsmo_roleowner(samdb, roledn, role): > """Gets the owner of an FSMO role > > :param roledn: The DN of the FSMO role >+ :param role: The FSMO role > """ >- res = samdb.search(roledn, >- scope=ldb.SCOPE_BASE, attrs=["fSMORoleOwner"]) >- if len(res) == 0: >- raise CommandError('"%s" does not have a FSMO roleowner' % roledn) >- master_owner = res[0]["fSMORoleOwner"][0] >- return master_owner >+ try: >+ res = samdb.search(roledn, >+ scope=ldb.SCOPE_BASE, attrs=["fSMORoleOwner"]) >+ except LdbError, (num, msg): >+ if num == ldb.ERR_NO_SUCH_OBJECT: >+ return "* The '%s' role is not present in this domain" % role >+ raise >+ >+ if 'fSMORoleOwner' in res[0]: >+ master_owner = res[0]["fSMORoleOwner"][0] >+ return master_owner >+ else: >+ master_owner = "* The '%s' role does not have an FSMO roleowner" % role >+ return master_owner > > > def transfer_dns_role(outf, sambaopts, credopts, role, samdb): >@@ -54,23 +63,23 @@ def transfer_dns_role(outf, sambaopts, credopts, role, samdb): > forest_dn = samba.dn_from_dns_name(samdb.forest_dns_name()) > role_object = "CN=Infrastructure,DC=ForestDnsZones," + forest_dn > >- try: >- res = samdb.search(role_object, >- attrs=["fSMORoleOwner"], >- scope=ldb.SCOPE_BASE, >- controls=["extended_dn:1:1"]) >+ res = samdb.search(role_object, >+ attrs=["fSMORoleOwner"], >+ scope=ldb.SCOPE_BASE, >+ controls=["extended_dn:1:1"]) > >- if 'fSMORoleOwner' in res[0]: >- try: >- master_guid = str(misc.GUID(ldb.Dn(samdb, >- res[0]['fSMORoleOwner'][0]) >- .get_extended_component('GUID'))) >- master_owner = str(ldb.Dn(samdb, res[0]['fSMORoleOwner'][0])) >- except LdbError, (num, msg): >- raise CommandError("GUID not found in partition naming master DN %s : %s \n" % >- (res[0]['fSMORoleOwner'][0], msg)) >- except LdbError, (num, msg): >- raise CommandError("DNS partion %s not found : %s" % (role, msg)) >+ if 'fSMORoleOwner' in res[0]: >+ try: >+ master_guid = str(misc.GUID(ldb.Dn(samdb, >+ res[0]['fSMORoleOwner'][0]) >+ .get_extended_component('GUID'))) >+ master_owner = str(ldb.Dn(samdb, res[0]['fSMORoleOwner'][0])) >+ except LdbError, (num, msg): >+ raise CommandError("No GUID found in naming master DN %s : %s \n" % >+ (res[0]['fSMORoleOwner'][0], msg)) >+ else: >+ outf.write("* The '%s' role does not have an FSMO roleowner\n" % role) >+ return False > > if role == "domaindns": > master_dns_name = '%s._msdcs.%s' % (master_guid, >@@ -150,12 +159,12 @@ def transfer_role(outf, role, samdb): > m = ldb.Message() > m.dn = ldb.Dn(samdb, "") > if role == "rid": >- master_owner = get_fsmo_roleowner(samdb, rid_dn) >+ master_owner = get_fsmo_roleowner(samdb, rid_dn, role) > m["becomeRidMaster"]= ldb.MessageElement( > "1", ldb.FLAG_MOD_REPLACE, > "becomeRidMaster") > elif role == "pdc": >- master_owner = get_fsmo_roleowner(samdb, domain_dn) >+ master_owner = get_fsmo_roleowner(samdb, domain_dn, role) > > res = samdb.search(domain_dn, > scope=ldb.SCOPE_BASE, attrs=["objectSid"]) >@@ -165,34 +174,38 @@ def transfer_role(outf, role, samdb): > sid, ldb.FLAG_MOD_REPLACE, > "becomePdc") > elif role == "naming": >- master_owner = get_fsmo_roleowner(samdb, naming_dn) >+ master_owner = get_fsmo_roleowner(samdb, naming_dn, role) > m["becomeDomainMaster"]= ldb.MessageElement( > "1", ldb.FLAG_MOD_REPLACE, > "becomeDomainMaster") > elif role == "infrastructure": >- master_owner = get_fsmo_roleowner(samdb, infrastructure_dn) >+ master_owner = get_fsmo_roleowner(samdb, infrastructure_dn, role) > m["becomeInfrastructureMaster"]= ldb.MessageElement( > "1", ldb.FLAG_MOD_REPLACE, > "becomeInfrastructureMaster") > elif role == "schema": >- master_owner = get_fsmo_roleowner(samdb, schema_dn) >+ master_owner = get_fsmo_roleowner(samdb, schema_dn, role) > m["becomeSchemaMaster"]= ldb.MessageElement( > "1", ldb.FLAG_MOD_REPLACE, > "becomeSchemaMaster") > else: > raise CommandError("Invalid FSMO role.") > >- if master_owner != new_owner: >- try: >- samdb.modify(m) >- except LdbError, (num, msg): >- raise CommandError("Transfer of '%s' role failed: %s" % >- (role, msg)) >+ if not '*' in master_owner: >+ if master_owner != new_owner: >+ try: >+ samdb.modify(m) >+ except LdbError, (num, msg): >+ raise CommandError("Transfer of '%s' role failed: %s" % >+ (role, msg)) > >- outf.write("FSMO transfer of '%s' role successful\n" % role) >- return True >+ outf.write("FSMO transfer of '%s' role successful\n" % role) >+ return True >+ else: >+ outf.write("This DC already has the '%s' FSMO role\n" % role) >+ return False > else: >- outf.write("This DC already has the '%s' FSMO role\n" % role) >+ outf.write("%s\n" % master_owner) > return False > > class cmd_fsmo_seize(Command): >@@ -210,7 +223,7 @@ class cmd_fsmo_seize(Command): > Option("-H", "--URL", help="LDB URL for database or target server", > type=str, metavar="URL", dest="H"), > Option("--force", >- help="Force seizing of the role without attempting to transfer first.", >+ help="Force seizing of role without attempting to transfer.", > action="store_true"), > Option("--role", type="choice", choices=["rid", "pdc", "infrastructure", > "schema", "naming", "domaindns", "forestdns", "all"], >@@ -253,32 +266,41 @@ You must provide an Admin user and password."""), > raise CommandError("Invalid FSMO role.") > #first try to transfer to avoid problem if the owner is still active > seize = False >- master_owner = get_fsmo_roleowner(samdb, m.dn) >- if master_owner != serviceName: >- if force is None: >- self.message("Attempting transfer...") >- if not transfer_role(self.outf, role, samdb): >- #transfer failed, use the big axe... >- seize = True >- self.message("Transfer unsuccessful, seizing...") >- else: >- self.message("Not seizing role as transfer was successful") >- >- if force is not None or seize == True: >- self.message("Seizing %s FSMO role..." % role) >- m["fSMORoleOwner"]= ldb.MessageElement( >- serviceName, ldb.FLAG_MOD_REPLACE, >- "fSMORoleOwner") >- try: >- samdb.modify(m) >- except LdbError, (num, msg): >- raise CommandError("Failed to seize '%s' role: %s" % >- (role, msg)) >- self.outf.write("FSMO seize of '%s' role successful\n" % role) >- return True >+ master_owner = get_fsmo_roleowner(samdb, m.dn, role) >+ if not '*' in master_owner: >+ # if there is a different owner >+ if master_owner != serviceName: >+ # if --force isn't given, attempt transfer >+ if force is None: >+ self.message("Attempting transfer...") >+ try: >+ transfer_role(self.outf, role, samdb) >+ except: >+ #transfer failed, use the big axe... >+ seize = True >+ self.message("Transfer unsuccessful, seizing...") >+ else: >+ self.message("Transfer successful, not seizing role") >+ return True >+ else: >+ self.outf.write("This DC already has the '%s' FSMO role\n" % >+ role) >+ return False > else: >- self.outf.write("This DC already has the '%s' FSMO role\n" % role) >- return False >+ seize = True >+ >+ if force is not None or seize == True: >+ self.message("Seizing %s FSMO role..." % role) >+ m["fSMORoleOwner"]= ldb.MessageElement( >+ serviceName, ldb.FLAG_MOD_REPLACE, >+ "fSMORoleOwner") >+ try: >+ samdb.modify(m) >+ except LdbError, (num, msg): >+ raise CommandError("Failed to seize '%s' role: %s" % >+ (role, msg)) >+ self.outf.write("FSMO seize of '%s' role successful\n" % role) >+ return True > > def seize_dns_role(self, role, samdb, credopts, sambaopts, > versionopts, force): >@@ -299,33 +321,43 @@ You must provide an Admin user and password."""), > raise CommandError("Invalid FSMO role.") > #first try to transfer to avoid problem if the owner is still active > seize = False >- master_owner = get_fsmo_roleowner(samdb, m.dn) >- if master_owner != serviceName: >- if force is None: >- self.message("Attempting transfer...") >- if not transfer_dns_role(self.outf, sambaopts, credopts, role, >- samdb): >- #transfer failed, use the big axe... >- seize = True >- self.message("Transfer unsuccessful, seizing...") >- else: >- self.message("Not seizing role as transfer was successful\n") >- >- if force is not None or seize == True: >- self.message("Seizing %s FSMO role..." % role) >- m["fSMORoleOwner"]= ldb.MessageElement( >- serviceName, ldb.FLAG_MOD_REPLACE, >- "fSMORoleOwner") >- try: >- samdb.modify(m) >- except LdbError, (num, msg): >- raise CommandError("Failed to seize '%s' role: %s" % >- (role, msg)) >- self.outf.write("FSMO seize of '%s' role successful\n" % role) >- return True >+ master_owner = get_fsmo_roleowner(samdb, m.dn, role) >+ if not '*' in master_owner: >+ # if there is a different owner >+ if master_owner != serviceName: >+ # if --force isn't given, attempt transfer >+ if force is None: >+ self.message("Attempting transfer...") >+ try: >+ transfer_dns_role(self.outf, sambaopts, credopts, role, >+ samdb) >+ except: >+ #transfer failed, use the big axe... >+ seize = True >+ self.message("Transfer unsuccessful, seizing...") >+ else: >+ self.message("Transfer successful, not seizing role\n") >+ return True >+ else: >+ self.outf.write("This DC already has the '%s' FSMO role\n" % >+ role) >+ return False > else: >- self.outf.write("This DC already has the '%s' FSMO role\n" % role) >- return False >+ seize = True >+ >+ if force is not None or seize == True: >+ self.message("Seizing %s FSMO role..." % role) >+ m["fSMORoleOwner"]= ldb.MessageElement( >+ serviceName, ldb.FLAG_MOD_REPLACE, >+ "fSMORoleOwner") >+ try: >+ samdb.modify(m) >+ except LdbError, (num, msg): >+ raise CommandError("Failed to seize '%s' role: %s" % >+ (role, msg)) >+ self.outf.write("FSMO seize of '%s' role successful\n" % role) >+ return True >+ > > def run(self, force=None, H=None, role=None, > credopts=None, sambaopts=None, versionopts=None): >@@ -388,13 +420,16 @@ class cmd_fsmo_show(Command): > domaindns_dn = "CN=Infrastructure,DC=DomainDnsZones," + domain_dn > forestdns_dn = "CN=Infrastructure,DC=ForestDnsZones," + forest_dn > >- infrastructureMaster = get_fsmo_roleowner(samdb, infrastructure_dn) >- pdcEmulator = get_fsmo_roleowner(samdb, domain_dn) >- namingMaster = get_fsmo_roleowner(samdb, naming_dn) >- schemaMaster = get_fsmo_roleowner(samdb, schema_dn) >- ridMaster = get_fsmo_roleowner(samdb, rid_dn) >- domaindnszonesMaster = get_fsmo_roleowner(samdb, domaindns_dn) >- forestdnszonesMaster = get_fsmo_roleowner(samdb, forestdns_dn) >+ infrastructureMaster = get_fsmo_roleowner(samdb, infrastructure_dn, >+ "infrastructure") >+ pdcEmulator = get_fsmo_roleowner(samdb, domain_dn, "pdc") >+ namingMaster = get_fsmo_roleowner(samdb, naming_dn, "naming") >+ schemaMaster = get_fsmo_roleowner(samdb, schema_dn, "schema") >+ ridMaster = get_fsmo_roleowner(samdb, rid_dn, "rid") >+ domaindnszonesMaster = get_fsmo_roleowner(samdb, domaindns_dn, >+ "domaindns") >+ forestdnszonesMaster = get_fsmo_roleowner(samdb, forestdns_dn, >+ "forestdns") > > self.message("SchemaMasterRole owner: " + schemaMaster) > self.message("InfrastructureMasterRole owner: " + infrastructureMaster) >@@ -449,8 +484,10 @@ You must provide an Admin user and password."""), > transfer_role(self.outf, "naming", samdb) > transfer_role(self.outf, "infrastructure", samdb) > transfer_role(self.outf, "schema", samdb) >- transfer_dns_role(self.outf, sambaopts, credopts, "domaindns", samdb) >- transfer_dns_role(self.outf, sambaopts, credopts, "forestdns", samdb) >+ transfer_dns_role(self.outf, sambaopts, credopts, >+ "domaindns", samdb) >+ transfer_dns_role(self.outf, sambaopts, credopts, "forestdns", >+ samdb) > else: > if role == "domaindns" or role == "forestdns": > transfer_dns_role(self.outf, sambaopts, credopts, role, samdb) >diff --git a/python/samba/tests/samba_tool/fsmo.py b/python/samba/tests/samba_tool/fsmo.py >new file mode 100644 >index 0000000..7058277 >--- /dev/null >+++ b/python/samba/tests/samba_tool/fsmo.py >@@ -0,0 +1,29 @@ >+# Unix SMB/CIFS implementation. >+# Copyright (C) Rowland Penny <rpenny@samba.org> 2016 >+# >+# 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 os >+from samba.tests.samba_tool.base import SambaToolCmdTest >+ >+class FsmoCmdTestCase(SambaToolCmdTest): >+ """Test for samba-tool fsmo show subcommand""" >+ >+ def test_fsmoget(self): >+ """Run fsmo show to see if it errors""" >+ (result, out, err) = self.runsubcmd("fsmo", "show") >+ >+ self.assertCmdSuccess(result) >+ self.assertEquals(err,"","Shouldn't be any error messages") >diff --git a/source4/selftest/tests.py b/source4/selftest/tests.py >index 979280b..03d206e 100755 >--- a/source4/selftest/tests.py >+++ b/source4/selftest/tests.py >@@ -537,6 +537,10 @@ planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.unix") > planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.dcerpc.srvsvc") > planpythontestsuite("ad_dc_ntvfs:local", "samba.tests.samba_tool.timecmd") > >+# test fsmo show >+for env in ["ad_dc_ntvfs", "fl2000dc", "fl2003dc", "fl2008r2dc"]: >+ planpythontestsuite(env + ":local", "samba.tests.samba_tool.fsmo") >+ > # We run this test against both AD DC implemetnations because it is > # the only test we have of GPO get/set behaviour, and this involves > # the file server as well as the LDAP server. >-- >1.9.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
jra
:
review+
metze
:
review?
(
abartlet
)
Actions:
View
Attachments on
bug 11613
:
11611
|
11675
| 12155 |
12156