1 # Changes a FSMO role owner
3 # Copyright Nadezhda Ivanova 2009
4 # Copyright Jelmer Vernooij 2009
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 3 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program. If not, see <http://www.gnu.org/licenses/>.
20 import samba
.getopt
as options
22 from ldb
import LdbError
24 from samba
.auth
import system_session
25 from samba
.netcmd
import (
31 from samba
.samdb
import SamDB
33 def transfer_role(outf
, role
, samdb
):
35 m
.dn
= ldb
.Dn(samdb
, "")
37 m
["becomeRidMaster"]= ldb
.MessageElement(
38 "1", ldb
.FLAG_MOD_REPLACE
,
41 domain_dn
= samdb
.domain_dn()
42 res
= samdb
.search(domain_dn
,
43 scope
=ldb
.SCOPE_BASE
, attrs
=["objectSid"])
45 sid
= res
[0]["objectSid"][0]
46 m
["becomePdc"]= ldb
.MessageElement(
47 sid
, ldb
.FLAG_MOD_REPLACE
,
49 elif role
== "naming":
50 m
["becomeDomainMaster"]= ldb
.MessageElement(
51 "1", ldb
.FLAG_MOD_REPLACE
,
54 elif role
== "infrastructure":
55 m
["becomeInfrastructureMaster"]= ldb
.MessageElement(
56 "1", ldb
.FLAG_MOD_REPLACE
,
57 "becomeInfrastructureMaster")
58 elif role
== "schema":
59 m
["becomeSchemaMaster"]= ldb
.MessageElement(
60 "1", ldb
.FLAG_MOD_REPLACE
,
63 raise CommandError("Invalid FSMO role.")
66 except LdbError
, (num
, msg
):
67 raise CommandError("Failed to initiate transfer of '%s' role: %s" % (role
, msg
))
68 outf
.write("FSMO transfer of '%s' role successful\n" % role
)
71 class cmd_fsmo_seize(Command
):
74 synopsis
= "%prog [options]"
76 takes_optiongroups
= {
77 "sambaopts": options
.SambaOptions
,
78 "credopts": options
.CredentialsOptions
,
79 "versionopts": options
.VersionOptions
,
83 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
84 metavar
="URL", dest
="H"),
85 Option("--force", help="Force seizing of the role without attempting to transfer first.", action
="store_true"),
86 Option("--role", type="choice", choices
=["rid", "pdc", "infrastructure","schema","naming","all"],
87 help="""The FSMO role to seize or transfer.\n
88 rid=RidAllocationMasterRole\n
89 schema=SchemaMasterRole\n
90 pdc=PdcEmulationMasterRole\n
91 naming=DomainNamingMasterRole\n
92 infrastructure=InfrastructureMasterRole\n
93 all=all of the above"""),
98 def seize_role(self
, role
, samdb
, force
):
99 res
= samdb
.search("",
100 scope
=ldb
.SCOPE_BASE
, attrs
=["dsServiceName"])
102 serviceName
= res
[0]["dsServiceName"][0]
103 domain_dn
= samdb
.domain_dn()
104 self
.infrastructure_dn
= "CN=Infrastructure," + domain_dn
105 self
.naming_dn
= "CN=Partitions,%s" % samdb
.get_config_basedn()
106 self
.schema_dn
= str(samdb
.get_schema_basedn())
107 self
.rid_dn
= "CN=RID Manager$,CN=System," + domain_dn
111 m
.dn
= ldb
.Dn(samdb
, self
.rid_dn
)
113 m
.dn
= ldb
.Dn(samdb
, domain_dn
)
114 elif role
== "naming":
115 m
.dn
= ldb
.Dn(samdb
, self
.naming_dn
)
116 elif role
== "infrastructure":
117 m
.dn
= ldb
.Dn(samdb
, self
.infrastructure_dn
)
118 elif role
== "schema":
119 m
.dn
= ldb
.Dn(samdb
, self
.schema_dn
)
121 raise CommandError("Invalid FSMO role.")
122 #first try to transfer to avoid problem if the owner is still active
124 self
.message("Attempting transfer...")
126 transfer_role(self
.outf
, role
, samdb
)
128 #transfer failed, use the big axe...
129 self
.message("Transfer unsuccessful, seizing...")
130 m
["fSMORoleOwner"]= ldb
.MessageElement(
131 serviceName
, ldb
.FLAG_MOD_REPLACE
,
134 self
.message("Will not attempt transfer, seizing...")
135 m
["fSMORoleOwner"]= ldb
.MessageElement(
136 serviceName
, ldb
.FLAG_MOD_REPLACE
,
140 except LdbError
, (num
, msg
):
141 raise CommandError("Failed to initiate role seize of '%s' role: %s" % (role
, msg
))
142 self
.outf
.write("FSMO transfer of '%s' role successful\n" % role
)
144 def run(self
, force
=None, H
=None, role
=None,
145 credopts
=None, sambaopts
=None, versionopts
=None):
147 lp
= sambaopts
.get_loadparm()
148 creds
= credopts
.get_credentials(lp
, fallback_machine
=True)
150 samdb
= SamDB(url
=H
, session_info
=system_session(),
151 credentials
=creds
, lp
=lp
)
154 self
.seize_role("rid", samdb
, force
)
155 self
.seize_role("pdc", samdb
, force
)
156 self
.seize_role("naming", samdb
, force
)
157 self
.seize_role("infrastructure", samdb
, force
)
158 self
.seize_role("schema", samdb
, force
)
160 self
.seize_role(role
, samdb
, force
)
163 class cmd_fsmo_show(Command
):
164 """Show the roles."""
166 synopsis
= "%prog [options]"
168 takes_optiongroups
= {
169 "sambaopts": options
.SambaOptions
,
170 "credopts": options
.CredentialsOptions
,
171 "versionopts": options
.VersionOptions
,
175 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
176 metavar
="URL", dest
="H"),
181 def run(self
, H
=None, credopts
=None, sambaopts
=None, versionopts
=None):
182 lp
= sambaopts
.get_loadparm()
183 creds
= credopts
.get_credentials(lp
, fallback_machine
=True)
185 samdb
= SamDB(url
=H
, session_info
=system_session(),
186 credentials
=creds
, lp
=lp
)
188 domain_dn
= samdb
.domain_dn()
189 self
.infrastructure_dn
= "CN=Infrastructure," + domain_dn
190 self
.naming_dn
= "CN=Partitions,%s" % samdb
.get_config_basedn()
191 self
.schema_dn
= samdb
.get_schema_basedn()
192 self
.rid_dn
= "CN=RID Manager$,CN=System," + domain_dn
194 res
= samdb
.search(self
.infrastructure_dn
,
195 scope
=ldb
.SCOPE_BASE
, attrs
=["fSMORoleOwner"])
197 self
.infrastructureMaster
= res
[0]["fSMORoleOwner"][0]
199 res
= samdb
.search(domain_dn
,
200 scope
=ldb
.SCOPE_BASE
, attrs
=["fSMORoleOwner"])
202 self
.pdcEmulator
= res
[0]["fSMORoleOwner"][0]
204 res
= samdb
.search(self
.naming_dn
,
205 scope
=ldb
.SCOPE_BASE
, attrs
=["fSMORoleOwner"])
207 self
.namingMaster
= res
[0]["fSMORoleOwner"][0]
209 res
= samdb
.search(self
.schema_dn
,
210 scope
=ldb
.SCOPE_BASE
, attrs
=["fSMORoleOwner"])
212 self
.schemaMaster
= res
[0]["fSMORoleOwner"][0]
214 res
= samdb
.search(self
.rid_dn
,
215 scope
=ldb
.SCOPE_BASE
, attrs
=["fSMORoleOwner"])
217 self
.ridMaster
= res
[0]["fSMORoleOwner"][0]
219 self
.message("InfrastructureMasterRole owner: " + self
.infrastructureMaster
)
220 self
.message("RidAllocationMasterRole owner: " + self
.ridMaster
)
221 self
.message("PdcEmulationMasterRole owner: " + self
.pdcEmulator
)
222 self
.message("DomainNamingMasterRole owner: " + self
.namingMaster
)
223 self
.message("SchemaMasterRole owner: " + self
.schemaMaster
)
226 class cmd_fsmo_transfer(Command
):
227 """Transfer the role."""
229 synopsis
= "%prog [options]"
231 takes_optiongroups
= {
232 "sambaopts": options
.SambaOptions
,
233 "credopts": options
.CredentialsOptions
,
234 "versionopts": options
.VersionOptions
,
238 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
239 metavar
="URL", dest
="H"),
240 Option("--role", type="choice", choices
=["rid", "pdc", "infrastructure","schema","naming","all"],
241 help="""The FSMO role to seize or transfer.\n
242 rid=RidAllocationMasterRole\n
243 schema=SchemaMasterRole\n
244 pdc=PdcEmulationMasterRole\n
245 naming=DomainNamingMasterRole\n
246 infrastructure=InfrastructureMasterRole\n
247 all=all of the above"""),
252 def run(self
, force
=None, H
=None, role
=None,
253 credopts
=None, sambaopts
=None, versionopts
=None):
255 lp
= sambaopts
.get_loadparm()
256 creds
= credopts
.get_credentials(lp
, fallback_machine
=True)
258 samdb
= SamDB(url
=H
, session_info
=system_session(),
259 credentials
=creds
, lp
=lp
)
262 transfer_role(self
.outf
, "rid", samdb
)
263 transfer_role(self
.outf
, "pdc", samdb
)
264 transfer_role(self
.outf
, "naming", samdb
)
265 transfer_role(self
.outf
, "infrastructure", samdb
)
266 transfer_role(self
.outf
, "schema", samdb
)
268 transfer_role(self
.outf
, role
, samdb
)
271 class cmd_fsmo(SuperCommand
):
272 """Flexible Single Master Operations (FSMO) roles management."""
275 subcommands
["seize"] = cmd_fsmo_seize()
276 subcommands
["show"] = cmd_fsmo_show()
277 subcommands
["transfer"] = cmd_fsmo_transfer()