summaryrefslogtreecommitdiff
path: root/source4/scripting/bin
diff options
context:
space:
mode:
authorMatthieu Patou <mat@matws.net>2009-11-25 16:26:35 +0300
committerAndrew Tridgell <tridge@samba.org>2009-11-27 16:05:04 +1100
commit44bc8ac22c402e3d320e080f935636bf26e17500 (patch)
treed9ba80f39b6467ad2bba5d52c7574d67078ad508 /source4/scripting/bin
parent81a21cbc40821246f5e806fbb44826cef629bed2 (diff)
downloadsamba-44bc8ac22c402e3d320e080f935636bf26e17500.tar.gz
samba-44bc8ac22c402e3d320e080f935636bf26e17500.tar.bz2
samba-44bc8ac22c402e3d320e080f935636bf26e17500.zip
s4: Improve updateprovision
* Define a simple upgrade process mode (module storage change, file name change, copy of new file) * Move the schema, configuration and current object upgrade into full upgrade mode * Added the --full switch to select the full upgrade mode, and made simple upgrade mode the default * Make updateprovision works without any switch (update the provision in the default location) * Cleanup the messages * Create the reference provision in a subdirectory of the updated provision
Diffstat (limited to 'source4/scripting/bin')
-rwxr-xr-xsource4/scripting/bin/upgradeprovision85
1 files changed, 52 insertions, 33 deletions
diff --git a/source4/scripting/bin/upgradeprovision b/source4/scripting/bin/upgradeprovision
index 054b473438..74d9829376 100755
--- a/source4/scripting/bin/upgradeprovision
+++ b/source4/scripting/bin/upgradeprovision
@@ -53,10 +53,14 @@ replace=2^ldb.FLAG_MOD_REPLACE
add=2^ldb.FLAG_MOD_ADD
delete=2^ldb.FLAG_MOD_DELETE
-CHANGE = 0x01
-CHANGESD = 0x02
-GUESS = 0x04
-CHANGEALL = 0xff
+#Errors are always logged
+ERROR = -1
+SIMPLE = 0x00
+CHANGE = 0x01
+CHANGESD = 0x02
+GUESS = 0x04
+PROVISION = 0x08
+CHANGEALL = 0xff
# Attributes that not copied from the reference provision even if they do not exists in the destination object
# This is most probably because they are populated automatcally when object is created
@@ -82,12 +86,13 @@ def define_what_to_log(opts):
what = what | CHANGESD
if opts.debugguess:
what = what | GUESS
+ if opts.debugprovision:
+ what = what | PROVISION
if opts.debugall:
what = what | CHANGEALL
return what
-
parser = optparse.OptionParser("provision [options]")
sambaopts = options.SambaOptions(parser)
parser.add_option_group(sambaopts)
@@ -101,6 +106,7 @@ parser.add_option("--debugguess", help="Print information on what is different b
parser.add_option("--debugchange", help="Print information on what is different but won't be changed", action="store_true")
parser.add_option("--debugchangesd", help="Print information security descriptors differences", action="store_true")
parser.add_option("--debugall", help="Print all available information (very verbose)", action="store_true")
+parser.add_option("--full", help="Perform full upgrade of the samdb (schema, configuration, new objects, ...", action="store_true")
parser.add_option("--targetdir", type="string", metavar="DIR",
help="Set target directory")
@@ -115,7 +121,7 @@ def messageprovision(text):
def message(what,text):
"""print a message if quiet is not set."""
- if whatToLog & what:
+ if (whatToLog & what) or (what <= 0 ):
print text
if len(sys.argv) == 1:
@@ -146,7 +152,7 @@ def get_paths(targetdir=None,smbconf=None):
smbconf = param.default_path()
if not os.path.exists(smbconf):
- print >>sys.stderr, "Unable to find smb.conf .."
+ message(ERROR,"Unable to find smb.conf ..")
parser.print_usage()
sys.exit(1)
@@ -179,7 +185,7 @@ def guess_names_from_current_provision(credentials,session_info,paths):
names.smbconf = smbconf
#It's important here to let ldb load with the old module or it's quite certain that the LDB won't load ...
samdb = Ldb(paths.samdb, session_info=session_info,
- credentials=credentials, lp=lp)
+ credentials=credentials, lp=lp, options=["modules:samba_dsdb"])
# That's a bit simplistic but it's ok as long as we have only 3 partitions
attrs2 = ["schemaNamingContext","configurationNamingContext","rootDomainNamingContext"]
@@ -189,7 +195,7 @@ def guess_names_from_current_provision(credentials,session_info,paths):
configdn = str(names.configdn)
names.schemadn = res2[0]["schemaNamingContext"]
if not (rootdn == str(res2[0]["rootDomainNamingContext"])):
- print >>sys.stderr, "rootdn in sam.ldb and smb.conf is not the same ..."
+ message(ERROR, "rootdn in sam.ldb and smb.conf is not the same ...")
else:
names.rootdn=res2[0]["rootDomainNamingContext"]
# default site name
@@ -234,7 +240,6 @@ def guess_names_from_current_provision(credentials,session_info,paths):
# ntds guid
attrs9 = ["objectGUID" ]
exp = "(dn=CN=NTDS Settings,%s)"%(names.serverdn)
- print exp
res9 = samdb.search(expression="(dn=CN=NTDS Settings,%s)"%(names.serverdn),base=str(names.configdn), scope=SCOPE_SUBTREE, attrs=attrs9)
names.ntdsguid = str(ndr_unpack( misc.GUID,res9[0]["objectGUID"][0]))
@@ -264,12 +269,18 @@ def print_names(names):
# This provision will be the reference for knowing what has changed in the
# since the latest upgrade in the current provision
def newprovision(names,setup_dir,creds,session,smbconf):
- random.seed()
- provdir=os.path.join(os.environ["HOME"],"provision"+str(int(100000*random.random())))
+ message(SIMPLE, "Creating a reference provision")
+ provdir=os.path.join(paths.private_dir,"referenceprovision")
+ if os.path.isdir(provdir):
+ rmall(provdir)
logstd=os.path.join(provdir,"log.std")
os.chdir(os.path.join(setup_dir,".."))
os.mkdir(provdir)
-
+ os.close(2)
+ sys.stderr = open("%s/provision.log"%provdir, "w")
+ message(PROVISION, "Reference provision stored in %s"%provdir)
+ message(PROVISION, "STDERR message of provision will be logged in %s/provision.log"%provdir)
+ sys.stderr = open("/dev/stdout", "w")
provision(setup_dir, messageprovision,
session, creds, smbconf=smbconf, targetdir=provdir,
samdb_fill=FILL_FULL, realm=names.realm, domain=names.domain,
@@ -289,7 +300,6 @@ def newprovision(names,setup_dir,creds,session,smbconf):
setup_ds_path=None,
nosync=None,
ldap_dryrun_mode=None)
- print >>sys.stderr, "provisiondir: "+provdir
return provdir
# This function sorts two dn in the lexicographical order and put higher level DN before
@@ -317,7 +327,7 @@ def dn_sort(x,y):
else:
if(i==min-1):
if(len1==len2):
- print >>sys.stderr,"PB PB PB"+space.join(tab1)+" / "+space.join(tab2)
+ message(ERROR,"PB PB PB"+space.join(tab1)+" / "+space.join(tab2))
if(len1>len2):
return 1
else:
@@ -390,6 +400,7 @@ def handle_special_case(att,delta,new,old,ischema):
return 0
def update_secrets(newpaths,paths,creds,session):
+ message(SIMPLE,"update secrets.ldb")
newsecrets_ldb = Ldb(newpaths.secrets, session_info=session, credentials=creds,lp=lp)
secrets_ldb = Ldb(paths.secrets, session_info=session, credentials=creds,lp=lp, options=["modules:samba_secrets"])
res = newsecrets_ldb.search(expression="dn=@MODULES",base="", scope=SCOPE_SUBTREE)
@@ -505,7 +516,7 @@ def check_diff_name(newpaths,paths,creds,session,basedn,names,ischema):
sam_ldb.transaction_start()
empty = ldb.Message()
- print "There are %d missing objects"%(len(listMissing))
+ message(SIMPLE,"There are %d missing objects"%(len(listMissing)))
for dn in listMissing:
res = newsam_ldb.search(expression="dn=%s"%(str(dn)),base=basedn, scope=SCOPE_SUBTREE,controls=["search_options:1:2"])
delta = sam_ldb.msg_diff(empty,res[0])
@@ -555,7 +566,7 @@ def check_diff_name(newpaths,paths,creds,session,basedn,names,ischema):
sam_ldb.modify(delta)
sam_ldb.transaction_commit()
- print "There are %d changed objects"%(changed)
+ message(SIMPLE,"There are %d changed objects"%(changed))
return hashallSD
@@ -594,9 +605,9 @@ def update_sds(diffDefSD,diffSD,paths,creds,session,rootdn,domSIDTxt):
session = system_session_info
descr = security.descriptor.ntsd_from_defaultsd(defSD, domSID,session)
if descr.as_sddl(domSID) != oldSD:
- print "nTSecurity Descriptor for %s do not directly inherit from the defaultSecurityDescriptor and is different from the one of the reference provision, therefor I can't upgrade i"
- print "Old Descriptor: %s"%(oldSD)
- print "New Descriptor: %s"%(newSD)
+ message(SIMPLE, "nTSecurity Descriptor for %s do not directly inherit from the defaultSecurityDescriptor and is different from the one of the reference provision, therefor I can't upgrade i")
+ message(SIMPLE,"Old Descriptor: %s"%(oldSD))
+ message(SIMPLE,"New Descriptor: %s"%(newSD))
if diffDefSD.has_key(classObj):
# We have a pending modification for the defaultSecurityDescriptor of the class Object of the currently inspected object
# and we have a conflict so write down that we won't upgrade this defaultSD for this class object
@@ -611,7 +622,7 @@ def update_sds(diffDefSD,diffSD,paths,creds,session,rootdn,domSIDTxt):
sam_ldb.modify(delta)
sam_ldb.transaction_commit()
- print "%d nTSecurityDescriptor attribute(s) have been updated"%(upgrade)
+ message(SIMPLE,"%d nTSecurityDescriptor attribute(s) have been updated"%(upgrade))
sam_ldb.transaction_start()
upgrade = 0
for dn in diffDefSD:
@@ -626,7 +637,7 @@ def update_sds(diffDefSD,diffSD,paths,creds,session,rootdn,domSIDTxt):
message(CHANGESD,"Not updating the defaultSecurityDescriptor for class object %s as one or more dependant object hasn't been upgraded"%(dn))
sam_ldb.transaction_commit()
- print "%d defaultSecurityDescriptor attribute(s) have been updated"%(upgrade)
+ message(SIMPLE,"%d defaultSecurityDescriptor attribute(s) have been updated"%(upgrade))
def rmall(topdir):
for root, dirs, files in os.walk(topdir, topdown=False):
@@ -636,13 +647,12 @@ def rmall(topdir):
os.rmdir(os.path.join(root, name))
os.rmdir(topdir)
-# For each partition check the differences
-def check_diff(newpaths,paths,creds,session,names):
- print "Copy samdb"
+def update_basesamdb(newpaths,paths,names):
+ message(SIMPLE,"Copy samdb")
shutil.copy(newpaths.samdb,paths.samdb)
- print "Update ldb names if needed"
+ message(SIMPLE,"Update partitions filename if needed")
schemaldb=os.path.join(paths.private_dir,"schema.ldb")
configldb=os.path.join(paths.private_dir,"configuration.ldb")
usersldb=os.path.join(paths.private_dir,"users.ldb")
@@ -660,16 +670,20 @@ def check_diff(newpaths,paths,creds,session,names):
if os.path.isfile(configldb):
shutil.copy(configldb,os.path.join(samldbdir,"%s.ldb"%str(names.configdn).upper()))
os.remove(configldb)
+
+def update_privilege(newpaths,paths):
+ message(SIMPLE,"Copy privilege")
shutil.copy(os.path.join(newpaths.private_dir,"privilege.ldb"),os.path.join(paths.private_dir,"privilege.ldb"))
- print "Doing schema update"
+# For each partition check the differences
+def update_samdb(newpaths,paths,creds,session,names):
+
+ message(SIMPLE, "Doing schema update")
hashdef = check_diff_name(newpaths,paths,creds,session,str(names.schemadn),names,1)
- print "Done with schema update"
- print "Scanning whole provision for updates and additions"
+ message(SIMPLE,"Done with schema update")
+ message(SIMPLE,"Scanning whole provision for updates and additions")
hashSD = check_diff_name(newpaths,paths,creds,session,str(names.rootdn),names,0)
- print "Done with scanning"
- print "Updating secrets"
- update_secrets(newpaths,paths,creds,session)
+ message(SIMPLE,"Done with scanning")
# update_sds(hashdef,hashSD,paths,creds,session,str(names.rootdn),names.domainsid)
# From here start the big steps of the program
@@ -689,6 +703,11 @@ provisiondir = newprovision(names,setup_dir,creds,session,smbconf)
newpaths = get_paths(targetdir=provisiondir)
populate_backlink(newpaths,creds,session,names.schemadn)
# Check the difference
-check_diff(newpaths,paths,creds,session,names)
+update_basesamdb(newpaths,paths,names)
+update_secrets(newpaths,paths,creds,session)
+update_privilege(newpaths,paths)
+if opts.full:
+ update_samdb(newpaths,paths,creds,session,names)
+message(SIMPLE,"Upgrade finished !")
# remove reference provision now that everything is done !
rmall(provisiondir)