samba-tool: Expanded acronym descriptions
[Samba.git] / source4 / scripting / python / samba / netcmd / fsmo.py
blobc2b0101a46f214238789f70d4fee8d90f7588b81
1 #!/usr/bin/env python
3 # Changes a FSMO role owner
5 # Copyright Nadezhda Ivanova 2009
6 # Copyright Jelmer Vernooij 2009
7 # Copyright Giampaolo Lauria 2011 <lauria2@yahoo.com>
9 # This program is free software; you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation; either version 3 of the License, or
12 # (at your option) any later version.
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License
20 # along with this program. If not, see <http://www.gnu.org/licenses/>.
23 import samba.getopt as options
24 import ldb
25 from ldb import LdbError
27 from samba.auth import system_session
28 from samba.netcmd import (
29 Command,
30 CommandError,
31 Option,
33 from samba.samdb import SamDB
35 class cmd_fsmo(Command):
36 """Flexible Single Master Operations (FSMO) roles management *"""
38 synopsis = "(show | transfer <options> | seize <options>)"
40 takes_options = [
41 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
42 metavar="URL", dest="H"),
43 Option("--force", help="Force seizing of the role without attempting to transfer first.", action="store_true"),
44 Option("--role", type="choice", choices=["rid", "pdc", "infrastructure","schema","naming","all"],
45 help="""The FSMO role to seize or transfer.\n
46 rid=RidAllocationMasterRole\n
47 schema=SchemaMasterRole\n
48 pdc=PdcEmulationMasterRole\n
49 naming=DomainNamingMasterRole\n
50 infrastructure=InfrastructureMasterRole\n
51 all=all of the above"""),
54 takes_args = ["subcommand"]
56 def transfer_role(self, role, samdb):
57 m = ldb.Message()
58 m.dn = ldb.Dn(samdb, "")
59 if role == "rid":
60 m["becomeRidMaster"]= ldb.MessageElement(
61 "1", ldb.FLAG_MOD_REPLACE,
62 "becomeRidMaster")
63 elif role == "pdc":
64 domain_dn = samdb.domain_dn()
65 res = samdb.search(domain_dn,
66 scope=ldb.SCOPE_BASE, attrs=["objectSid"])
67 assert len(res) == 1
68 sid = res[0]["objectSid"][0]
69 m["becomePdc"]= ldb.MessageElement(
70 sid, ldb.FLAG_MOD_REPLACE,
71 "becomePdc")
72 elif role == "naming":
73 m["becomeDomainMaster"]= ldb.MessageElement(
74 "1", ldb.FLAG_MOD_REPLACE,
75 "becomeDomainMaster")
76 samdb.modify(m)
77 elif role == "infrastructure":
78 m["becomeInfrastructureMaster"]= ldb.MessageElement(
79 "1", ldb.FLAG_MOD_REPLACE,
80 "becomeInfrastructureMaster")
81 elif role == "schema":
82 m["becomeSchemaMaster"]= ldb.MessageElement(
83 "1", ldb.FLAG_MOD_REPLACE,
84 "becomeSchemaMaster")
85 else:
86 raise CommandError("Invalid FSMO role.")
87 try:
88 samdb.modify(m)
89 except LdbError, (num, msg):
90 raise CommandError("Failed to initiate transfer of '%s' role: %s" % (role, msg))
91 print("FSMO transfer of '%s' role successful" % role)
94 def seize_role(self, role, samdb, force):
95 res = samdb.search("",
96 scope=ldb.SCOPE_BASE, attrs=["dsServiceName"])
97 assert len(res) == 1
98 serviceName = res[0]["dsServiceName"][0]
99 domain_dn = samdb.domain_dn()
100 m = ldb.Message()
101 if role == "rid":
102 m.dn = ldb.Dn(samdb, self.rid_dn)
103 elif role == "pdc":
104 m.dn = ldb.Dn(samdb, domain_dn)
105 elif role == "naming":
106 m.dn = ldb.Dn(samdb, self.naming_dn)
107 elif role == "infrastructure":
108 m.dn = ldb.Dn(samdb, self.infrastructure_dn)
109 elif role == "schema":
110 m.dn = ldb.Dn(samdb, self.schema_dn)
111 else:
112 raise CommandError("Invalid FSMO role.")
113 #first try to transfer to avoid problem if the owner is still active
114 if force is None:
115 self.message("Attempting transfer...")
116 try:
117 self.transfer_role(role, samdb)
118 except LdbError, (num, _):
119 #transfer failed, use the big axe...
120 self.message("Transfer unsuccessful, seizing...")
121 m["fSMORoleOwner"]= ldb.MessageElement(
122 serviceName, ldb.FLAG_MOD_REPLACE,
123 "fSMORoleOwner")
124 else:
125 self.message("Will not attempt transfer, seizing...")
126 m["fSMORoleOwner"]= ldb.MessageElement(
127 serviceName, ldb.FLAG_MOD_REPLACE,
128 "fSMORoleOwner")
129 try:
130 samdb.modify(m)
131 except LdbError, (num, msg):
132 raise CommandError("Failed to initiate role seize of '%s' role: %s" % (role, msg))
133 print("FSMO transfer of '%s' role successful" % role)
136 def run(self, subcommand, force=None, H=None, role=None,
137 credopts=None, sambaopts=None, versionopts=None):
138 lp = sambaopts.get_loadparm()
139 creds = credopts.get_credentials(lp, fallback_machine=True)
141 samdb = SamDB(url=H, session_info=system_session(),
142 credentials=creds, lp=lp)
144 domain_dn = samdb.domain_dn()
145 self.infrastructure_dn = "CN=Infrastructure," + domain_dn
146 self.naming_dn = "CN=Partitions,CN=Configuration," + domain_dn
147 self.schema_dn = "CN=Schema,CN=Configuration," + domain_dn
148 self.rid_dn = "CN=RID Manager$,CN=System," + domain_dn
150 res = samdb.search(self.infrastructure_dn,
151 scope=ldb.SCOPE_BASE, attrs=["fSMORoleOwner"])
152 assert len(res) == 1
153 self.infrastructureMaster = res[0]["fSMORoleOwner"][0]
155 res = samdb.search(domain_dn,
156 scope=ldb.SCOPE_BASE, attrs=["fSMORoleOwner"])
157 assert len(res) == 1
158 self.pdcEmulator = res[0]["fSMORoleOwner"][0]
160 res = samdb.search(self.naming_dn,
161 scope=ldb.SCOPE_BASE, attrs=["fSMORoleOwner"])
162 assert len(res) == 1
163 self.namingMaster = res[0]["fSMORoleOwner"][0]
165 res = samdb.search(self.schema_dn,
166 scope=ldb.SCOPE_BASE, attrs=["fSMORoleOwner"])
167 assert len(res) == 1
168 self.schemaMaster = res[0]["fSMORoleOwner"][0]
170 res = samdb.search(self.rid_dn,
171 scope=ldb.SCOPE_BASE, attrs=["fSMORoleOwner"])
172 assert len(res) == 1
173 self.ridMaster = res[0]["fSMORoleOwner"][0]
175 if subcommand == "show":
176 self.message("InfrastructureMasterRole owner: " + self.infrastructureMaster)
177 self.message("RidAllocationMasterRole owner: " + self.ridMaster)
178 self.message("PdcEmulationMasterRole owner: " + self.pdcEmulator)
179 self.message("DomainNamingMasterRole owner: " + self.namingMaster)
180 self.message("SchemaMasterRole owner: " + self.schemaMaster)
181 elif subcommand == "transfer":
182 if role == "all":
183 self.transfer_role("rid", samdb)
184 self.transfer_role("pdc", samdb)
185 self.transfer_role("naming", samdb)
186 self.transfer_role("infrastructure", samdb)
187 self.transfer_role("schema", samdb)
188 else:
189 self.transfer_role(role, samdb)
190 elif subcommand == "seize":
191 if role == "all":
192 self.seize_role("rid", samdb, force)
193 self.seize_role("pdc", samdb, force)
194 self.seize_role("naming", samdb, force)
195 self.seize_role("infrastructure", samdb, force)
196 self.seize_role("schema", samdb, force)
197 else:
198 self.seize_role(role, samdb, force)
199 else:
200 raise CommandError("Wrong argument '%s'!" % subcommand)