3
# Raises domain and forest function levels
5
# Copyright Matthias Dieter Wallnoefer 2009
7
# This program is free software; you can redistribute it and/or modify
8
# it under the terms of the GNU General Public License as published by
9
# the Free Software Foundation; either version 3 of the License, or
10
# (at your option) any later version.
12
# This program is distributed in the hope that it will be useful,
13
# but WITHOUT ANY WARRANTY; without even the implied warranty of
14
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
# GNU General Public License for more details.
17
# You should have received a copy of the GNU General Public License
18
# along with this program. If not, see <http://www.gnu.org/licenses/>.
23
# Find right directory when running from source tree
24
sys.path.insert(0, "bin/python")
26
import samba.getopt as options
30
from samba.auth import system_session
31
from samba.samdb import SamDB
32
from samba import DS_DOMAIN_FUNCTION_2000, DS_DOMAIN_FUNCTION_2003
33
from samba import DS_DOMAIN_FUNCTION_2003_MIXED, DS_DOMAIN_FUNCTION_2008
34
from samba import DS_DOMAIN_FUNCTION_2008_R2
36
parser = optparse.OptionParser("domainlevel (show | raise <options>)")
37
sambaopts = options.SambaOptions(parser)
38
parser.add_option_group(sambaopts)
39
parser.add_option_group(options.VersionOptions(parser))
40
credopts = options.CredentialsOptions(parser)
41
parser.add_option_group(credopts)
42
parser.add_option("-H", help="LDB URL for database or target server", type=str)
43
parser.add_option("--quiet", help="Be quiet", action="store_true")
44
parser.add_option("--forest",
45
help="The forest function level (2000 | 2003 | 2008 | 2008_R2). We don't support the 2003 with mixed domains (NT4 DC support) level.", type=str)
46
parser.add_option("--domain",
47
help="The domain function level (2000 | 2003 | 2008 | 2008_R2). We don't support mixed/interim (NT4 DC support) levels.", type=str)
48
opts, args = parser.parse_args()
51
# print a message if quiet is not set
61
lp = sambaopts.get_loadparm()
62
creds = credopts.get_credentials(lp)
64
if opts.H is not None:
67
url = lp.get("sam database")
69
samdb = SamDB(url=url, session_info=system_session(), credentials=creds, lp=lp)
71
domain_dn = SamDB.domain_dn(samdb)
73
res_forest = samdb.search("CN=Partitions,CN=Configuration," + domain_dn,
74
scope=ldb.SCOPE_BASE, attrs=["msDS-Behavior-Version"])
75
assert(len(res_forest) == 1)
77
res_domain = samdb.search(domain_dn, scope=ldb.SCOPE_BASE,
78
attrs=["msDS-Behavior-Version", "nTMixedDomain"])
79
assert(len(res_domain) == 1)
82
level_forest = int(res_forest[0]["msDS-Behavior-Version"][0])
83
level_domain = int(res_domain[0]["msDS-Behavior-Version"][0])
84
level_domain_mixed = int(res_domain[0]["nTMixedDomain"][0])
86
if level_forest < 0 or level_domain < 0:
87
print "ERROR: Domain and/or forest functional level(s) is/are invalid. Correct them or reprovision!"
89
if level_forest > level_domain:
90
print "ERROR: Forest function level is higher than the domain level(s). That can't be. Correct this or reprovision!"
93
print "ERROR: Could not retrieve the actual domain and/or forest level!"
95
print "So the levels can't be displayed!"
99
message("Domain and forest function level for domain '" + domain_dn + "'")
100
if level_forest == DS_DOMAIN_FUNCTION_2003_MIXED:
101
message("\nATTENTION: You run SAMBA 4 on the 2003 with mixed domains (NT4 DC support) forest level. This isn't supported! Please raise!")
102
if (level_domain == DS_DOMAIN_FUNCTION_2000 and level_domain_mixed != 0) or level_domain == DS_DOMAIN_FUNCTION_2003_MIXED:
103
message("\nATTENTION: You run SAMBA 4 on a mixed/interim (NT4 DC support) domain level. This isn't supported! Please raise!")
107
if level_forest == DS_DOMAIN_FUNCTION_2000:
109
elif level_forest == DS_DOMAIN_FUNCTION_2003_MIXED:
110
outstr = "2003 with mixed domains/interim (NT4 DC support)"
111
elif level_forest == DS_DOMAIN_FUNCTION_2003:
113
elif level_forest == DS_DOMAIN_FUNCTION_2008:
115
elif level_forest == DS_DOMAIN_FUNCTION_2008_R2:
118
outstr = "higher than 2008 R2"
119
message("Forest function level: (Windows) " + outstr)
121
if level_domain == DS_DOMAIN_FUNCTION_2000 and level_domain_mixed != 0:
122
outstr = "2000 mixed (NT4 DC support)"
123
elif level_domain == DS_DOMAIN_FUNCTION_2000 and level_domain_mixed == 0:
125
elif level_domain == DS_DOMAIN_FUNCTION_2003_MIXED:
126
outstr = "2003 with mixed domains/interim (NT4 DC support)"
127
elif level_domain == DS_DOMAIN_FUNCTION_2003:
129
elif level_domain == DS_DOMAIN_FUNCTION_2008:
131
elif level_domain == DS_DOMAIN_FUNCTION_2008_R2:
134
outstr = "higher than 2008 R2"
135
message("Domain function level: (Windows) " + outstr)
137
elif args[0] == "raise":
140
if opts.domain is not None:
144
new_level_domain = DS_DOMAIN_FUNCTION_2000
146
new_level_domain = DS_DOMAIN_FUNCTION_2003
148
new_level_domain = DS_DOMAIN_FUNCTION_2008
149
elif arg == "2008_R2":
150
new_level_domain = DS_DOMAIN_FUNCTION_2008_R2
152
print "ERROR: Wrong argument '" + arg + "'!"
155
if new_level_domain <= level_domain and level_domain_mixed == 0:
156
print "ERROR: Domain function level can't be smaller equal to the actual one!"
159
# Deactivate mixed/interim domain support
160
if level_domain_mixed != 0:
162
m.dn = ldb.Dn(samdb, domain_dn)
163
m["nTMixedDomain"] = ldb.MessageElement("0",
164
ldb.FLAG_MOD_REPLACE, "nTMixedDomain")
168
m.dn = ldb.Dn(samdb, domain_dn)
169
m["msDS-Behavior-Version"]= ldb.MessageElement(
170
str(new_level_domain), ldb.FLAG_MOD_REPLACE,
171
"msDS-Behavior-Version")
174
level_domain = new_level_domain
176
msgs.append("Domain function level changed!")
178
if opts.forest is not None:
182
new_level_forest = DS_DOMAIN_FUNCTION_2000
184
new_level_forest = DS_DOMAIN_FUNCTION_2003
186
new_level_forest = DS_DOMAIN_FUNCTION_2008
187
elif arg == "2008_R2":
188
new_level_forest = DS_DOMAIN_FUNCTION_2008_R2
190
print "ERROR: Wrong argument '" + arg + "'!"
193
if new_level_forest <= level_forest:
194
print "ERROR: Forest function level can't be smaller equal to the actual one!"
197
if new_level_forest > level_domain:
198
print "ERROR: Forest function level can't be higher than the domain function level(s). Please raise it/them first!"
202
m.dn = ldb.Dn(samdb, "CN=Partitions,CN=Configuration,"
204
m["msDS-Behavior-Version"]= ldb.MessageElement(
205
str(new_level_forest), ldb.FLAG_MOD_REPLACE,
206
"msDS-Behavior-Version")
209
msgs.append("Forest function level changed!")
211
msgs.append("All changes applied successfully!")
213
message("\n".join(msgs))
215
print "ERROR: Wrong argument '" + args[0] + "'!"