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
,
53 elif role
== "infrastructure":
54 m
["becomeInfrastructureMaster"]= ldb
.MessageElement(
55 "1", ldb
.FLAG_MOD_REPLACE
,
56 "becomeInfrastructureMaster")
57 elif role
== "schema":
58 m
["becomeSchemaMaster"]= ldb
.MessageElement(
59 "1", ldb
.FLAG_MOD_REPLACE
,
62 raise CommandError("Invalid FSMO role.")
65 except LdbError
, (num
, msg
):
66 raise CommandError("Failed to initiate transfer of '%s' role: %s" % (role
, msg
))
67 outf
.write("FSMO transfer of '%s' role successful\n" % role
)
70 class cmd_fsmo_seize(Command
):
73 synopsis
= "%prog [options]"
75 takes_optiongroups
= {
76 "sambaopts": options
.SambaOptions
,
77 "credopts": options
.CredentialsOptions
,
78 "versionopts": options
.VersionOptions
,
82 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
83 metavar
="URL", dest
="H"),
84 Option("--force", help="Force seizing of the role without attempting to transfer first.", action
="store_true"),
85 Option("--role", type="choice", choices
=["rid", "pdc", "infrastructure","schema","naming","all"],
86 help="""The FSMO role to seize or transfer.\n
87 rid=RidAllocationMasterRole\n
88 schema=SchemaMasterRole\n
89 pdc=PdcEmulationMasterRole\n
90 naming=DomainNamingMasterRole\n
91 infrastructure=InfrastructureMasterRole\n
92 all=all of the above"""),
97 def seize_role(self
, role
, samdb
, force
):
98 res
= samdb
.search("",
99 scope
=ldb
.SCOPE_BASE
, attrs
=["dsServiceName"])
101 serviceName
= res
[0]["dsServiceName"][0]
102 domain_dn
= samdb
.domain_dn()
103 self
.infrastructure_dn
= "CN=Infrastructure," + domain_dn
104 self
.naming_dn
= "CN=Partitions,%s" % samdb
.get_config_basedn()
105 self
.schema_dn
= str(samdb
.get_schema_basedn())
106 self
.rid_dn
= "CN=RID Manager$,CN=System," + domain_dn
110 m
.dn
= ldb
.Dn(samdb
, self
.rid_dn
)
112 m
.dn
= ldb
.Dn(samdb
, domain_dn
)
113 elif role
== "naming":
114 m
.dn
= ldb
.Dn(samdb
, self
.naming_dn
)
115 elif role
== "infrastructure":
116 m
.dn
= ldb
.Dn(samdb
, self
.infrastructure_dn
)
117 elif role
== "schema":
118 m
.dn
= ldb
.Dn(samdb
, self
.schema_dn
)
120 raise CommandError("Invalid FSMO role.")
121 #first try to transfer to avoid problem if the owner is still active
123 self
.message("Attempting transfer...")
125 transfer_role(self
.outf
, role
, samdb
)
126 self
.outf
.write("FSMO seize was not required, as transfer of '%s' role was successful\n" % role
)
129 #transfer failed, use the big axe...
130 self
.message("Transfer unsuccessful, seizing...")
132 self
.message("Will not attempt transfer, seizing...")
134 m
["fSMORoleOwner"]= ldb
.MessageElement(
135 serviceName
, ldb
.FLAG_MOD_REPLACE
,
139 except LdbError
, (num
, msg
):
140 raise CommandError("Failed to initiate role seize of '%s' role: %s" % (role
, msg
))
141 self
.outf
.write("FSMO seize of '%s' role successful\n" % role
)
143 def run(self
, force
=None, H
=None, role
=None,
144 credopts
=None, sambaopts
=None, versionopts
=None):
146 lp
= sambaopts
.get_loadparm()
147 creds
= credopts
.get_credentials(lp
, fallback_machine
=True)
149 samdb
= SamDB(url
=H
, session_info
=system_session(),
150 credentials
=creds
, lp
=lp
)
153 self
.seize_role("rid", samdb
, force
)
154 self
.seize_role("pdc", samdb
, force
)
155 self
.seize_role("naming", samdb
, force
)
156 self
.seize_role("infrastructure", samdb
, force
)
157 self
.seize_role("schema", samdb
, force
)
159 self
.seize_role(role
, samdb
, force
)
162 class cmd_fsmo_show(Command
):
163 """Show the roles."""
165 synopsis
= "%prog [options]"
167 takes_optiongroups
= {
168 "sambaopts": options
.SambaOptions
,
169 "credopts": options
.CredentialsOptions
,
170 "versionopts": options
.VersionOptions
,
174 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
175 metavar
="URL", dest
="H"),
180 def run(self
, H
=None, credopts
=None, sambaopts
=None, versionopts
=None):
181 lp
= sambaopts
.get_loadparm()
182 creds
= credopts
.get_credentials(lp
, fallback_machine
=True)
184 samdb
= SamDB(url
=H
, session_info
=system_session(),
185 credentials
=creds
, lp
=lp
)
187 domain_dn
= samdb
.domain_dn()
188 self
.infrastructure_dn
= "CN=Infrastructure," + domain_dn
189 self
.naming_dn
= "CN=Partitions,%s" % samdb
.get_config_basedn()
190 self
.schema_dn
= samdb
.get_schema_basedn()
191 self
.rid_dn
= "CN=RID Manager$,CN=System," + domain_dn
193 res
= samdb
.search(self
.infrastructure_dn
,
194 scope
=ldb
.SCOPE_BASE
, attrs
=["fSMORoleOwner"])
196 self
.infrastructureMaster
= res
[0]["fSMORoleOwner"][0]
198 res
= samdb
.search(domain_dn
,
199 scope
=ldb
.SCOPE_BASE
, attrs
=["fSMORoleOwner"])
201 self
.pdcEmulator
= res
[0]["fSMORoleOwner"][0]
203 res
= samdb
.search(self
.naming_dn
,
204 scope
=ldb
.SCOPE_BASE
, attrs
=["fSMORoleOwner"])
206 self
.namingMaster
= res
[0]["fSMORoleOwner"][0]
208 res
= samdb
.search(self
.schema_dn
,
209 scope
=ldb
.SCOPE_BASE
, attrs
=["fSMORoleOwner"])
211 self
.schemaMaster
= res
[0]["fSMORoleOwner"][0]
213 res
= samdb
.search(self
.rid_dn
,
214 scope
=ldb
.SCOPE_BASE
, attrs
=["fSMORoleOwner"])
216 self
.ridMaster
= res
[0]["fSMORoleOwner"][0]
218 self
.message("InfrastructureMasterRole owner: " + self
.infrastructureMaster
)
219 self
.message("RidAllocationMasterRole owner: " + self
.ridMaster
)
220 self
.message("PdcEmulationMasterRole owner: " + self
.pdcEmulator
)
221 self
.message("DomainNamingMasterRole owner: " + self
.namingMaster
)
222 self
.message("SchemaMasterRole owner: " + self
.schemaMaster
)
225 class cmd_fsmo_transfer(Command
):
226 """Transfer the role."""
228 synopsis
= "%prog [options]"
230 takes_optiongroups
= {
231 "sambaopts": options
.SambaOptions
,
232 "credopts": options
.CredentialsOptions
,
233 "versionopts": options
.VersionOptions
,
237 Option("-H", "--URL", help="LDB URL for database or target server", type=str,
238 metavar
="URL", dest
="H"),
239 Option("--role", type="choice", choices
=["rid", "pdc", "infrastructure","schema","naming","all"],
240 help="""The FSMO role to seize or transfer.\n
241 rid=RidAllocationMasterRole\n
242 schema=SchemaMasterRole\n
243 pdc=PdcEmulationMasterRole\n
244 naming=DomainNamingMasterRole\n
245 infrastructure=InfrastructureMasterRole\n
246 all=all of the above"""),
251 def run(self
, force
=None, H
=None, role
=None,
252 credopts
=None, sambaopts
=None, versionopts
=None):
254 lp
= sambaopts
.get_loadparm()
255 creds
= credopts
.get_credentials(lp
, fallback_machine
=True)
257 samdb
= SamDB(url
=H
, session_info
=system_session(),
258 credentials
=creds
, lp
=lp
)
261 transfer_role(self
.outf
, "rid", samdb
)
262 transfer_role(self
.outf
, "pdc", samdb
)
263 transfer_role(self
.outf
, "naming", samdb
)
264 transfer_role(self
.outf
, "infrastructure", samdb
)
265 transfer_role(self
.outf
, "schema", samdb
)
267 transfer_role(self
.outf
, role
, samdb
)
270 class cmd_fsmo(SuperCommand
):
271 """Flexible Single Master Operations (FSMO) roles management."""
274 subcommands
["seize"] = cmd_fsmo_seize()
275 subcommands
["show"] = cmd_fsmo_show()
276 subcommands
["transfer"] = cmd_fsmo_transfer()