upgrade: Add missing bits for the s3 to s4 upgrade script
authorAmitay Isaacs <amitay@gmail.com>
Fri, 12 Aug 2011 01:37:57 +0000 (11:37 +1000)
committerAndrew Bartlett <abartlet@samba.org>
Sat, 13 Aug 2011 10:18:40 +0000 (20:18 +1000)
Use passdb backend to import/export users

Remove unused options for upgrade_from_s3 command (--blank) and credentials options
Config file is specified with -s/--configfile option and no need to specify as an argument.

Pair-Programmed-With: Andrew Bartlett <abartlet@samba.org>

source4/scripting/python/samba/upgrade.py
source4/setup/upgrade_from_s3

index 1002af53ef733d2e1205f905c789f04a4e70fb03..e333174d13485ff35d375989474cae83c35740b1 100644 (file)
@@ -26,7 +26,9 @@ import pwd
 
 from samba import Ldb, registry
 from samba.param import LoadParm
-from samba.provision import provision
+from samba.provision import provision, FILL_FULL
+from samba.samba3 import passdb
+from samba.samba3 import param as s3param
 
 def import_sam_policy(samldb, policy, dn):
     """Import a Samba 3 policy database."""
@@ -375,11 +377,15 @@ def import_registry(samba4_registry, samba3_regdb):
             key_handle.set_value(value_name, value_type, value_data)
 
 
-def upgrade_from_passdb(samba3, logger, credentials, session_info,
-                        smbconf, targetdir):
-    oldconf = samba3.get_conf()
+def upgrade_from_samba3(samba3, logger, session_info, smbconf, targetdir):
+    """Upgrade from samba3 database to samba4 AD database
+    """
+
+    # Read samba3 smb.conf
+    oldconf = s3param.get_context();
+    oldconf.load(smbconf)
 
-    if oldconf.get("domain logons") == "True":
+    if oldconf.get("domain logons"):
         serverrole = "domain controller"
     else:
         if oldconf.get("security") == "user":
@@ -391,15 +397,16 @@ def upgrade_from_passdb(samba3, logger, credentials, session_info,
     realm = oldconf.get("realm")
     netbiosname = oldconf.get("netbios name")
 
+    # secrets db
     secrets_db = samba3.get_secrets_db()
 
-    if domainname is None:
+    if not domainname:
         domainname = secrets_db.domains()[0]
         logger.warning("No domain specified in smb.conf file, assuming '%s'",
                 domainname)
 
-    if realm is None:
-        if oldconf.get("domain logons") == "True":
+    if not realm:
+        if oldconf.get("domain logons"):
             logger.warning("No realm specified in smb.conf file and being a DC. That upgrade path doesn't work! Please add a 'realm' directive to your old smb.conf to let us know which one you want to use (generally it's the upcased DNS domainname).")
             return
         else:
@@ -407,23 +414,62 @@ def upgrade_from_passdb(samba3, logger, credentials, session_info,
             logger.warning("No realm specified in smb.conf file, assuming '%s'",
                     realm)
 
-    domainguid = secrets_db.get_domain_guid(domainname)
-    domainsid = secrets_db.get_sid(domainname)
+    # Find machine account and password
+    machinepass = None
+    machinerid = 2000
+    machinesid = None
+
+    try:
+        machinepass = secrets_db.get_machine_password(netbiosname)
+    except:
+        pass
+
+    # We must close the direct pytdb database before the C code loads it
+    secrets_db.close()
+
+    # We must load the group mapping into memory before the passdb code touches it
+    groupdb = samba3.get_groupmapping_db()
+    for sid in groupdb.groupsids():
+        (gid, sid_name_use, nt_name, comment) = groupdb.get_group(sid)
+        # FIXME: import_sam_group(samdb, sid, gid, sid_name_use, nt_name, comment, domaindn)
+    groupdb.close()
+
+    passdb.set_secrets_dir(samba3.libdir)
+
+    try:
+        domainsid = str(passdb.get_global_sam_sid())
+    except:
+        pass
+
+    try:
+        machineacct = old_passdb.getsampwnam('%s$' % netbiosname)
+        machinesid, machinerid = machineacct.user_sid.split()
+    except:
+        pass
+
     if domainsid is None:
         logger.warning("Can't find domain secrets for '%s'; using random SID",
             domainname)
 
-    if netbiosname is not None:
-        machinepass = secrets_db.get_machine_password(netbiosname)
-    else:
-        machinepass = None
-
-    result = provision(logger=logger,
-                       session_info=session_info, credentials=credentials,
+    # Import users from old passdb backend
+    old_passdb = passdb.PDB(oldconf.get('passdb backend'))
+    userlist = old_passdb.search_users(0)
+    userdata = {}
+    for entry in userlist:
+        if machinesid and machinerid == entry['rid']:
+            continue
+        username = entry['account_name']
+        if entry['rid'] < 1000:
+            print("Skipping wellknown rid=%d (for username=%s)\n" % (entry['rid'], username))
+            continue
+        userdata[username] = old_passdb.getsampwnam(username)
+
+    # Do full provision
+    result = provision(logger, session_info, None,
                        targetdir=targetdir, realm=realm, domain=domainname,
-                       domainguid=domainguid, domainsid=domainsid,
+                       domainsid=domainsid, next_rid=machinerid,
                        hostname=netbiosname, machinepass=machinepass,
-                       serverrole=serverrole)
+                       serverrole=serverrole, samdb_fill=FILL_FULL)
 
     import_wins(Ldb(result.paths.winsdb), samba3.get_wins_db())
 
@@ -431,20 +477,15 @@ def upgrade_from_passdb(samba3, logger, credentials, session_info,
 
     # FIXME: import_idmap(samdb,samba3.get_idmap_db(),domaindn)
 
-    groupdb = samba3.get_groupmapping_db()
-    for sid in groupdb.groupsids():
-        (gid, sid_name_use, nt_name, comment) = groupdb.get_group(sid)
-        # FIXME: import_sam_group(samdb, sid, gid, sid_name_use, nt_name, comment, domaindn)
-
     # FIXME: Aliases
 
-    passdb = samba3.get_sam_db()
-    for name in passdb:
-        user = passdb[name]
-        #FIXME: import_sam_account(result.samdb, user, domaindn, domainsid)
-
-    if hasattr(passdb, 'ldap_url'):
-        logger.info("Enabling Samba3 LDAP mappings for SAM database")
+    # Export users to samba4 backend
+    new_smbconf = result.lp.configfile
+    newconf = s3param.get_context()
+    newconf.load(new_smbconf)
 
-        enable_samba3sam(result.samdb, passdb.ldap_url)
+    new_passdb = passdb.PDB('samba4')
 
+    for username in userdata:
+        print "adding user %s" % username
+        new_passdb.add_sam_account(userdata[username])
index e3af2019e6f581f5ccf2b22bb94fa215afbe6412..6d7862171fc4dff14378e8dd5d648cd18f6cadc3 100755 (executable)
@@ -26,17 +26,13 @@ sys.path.insert(0, "bin/python")
 import samba
 import samba.getopt as options
 from samba.auth import system_session
-from samba.upgrade import upgrade_from_passdb
+from samba.upgrade import upgrade_from_samba3
 from samba.samba3 import Samba3
-parser = optparse.OptionParser("upgrade_from_s3 [options] <libdir> <smbconf>")
+parser = optparse.OptionParser("upgrade_from_s3 [options] <libdir>")
 sambaopts = options.SambaOptions(parser)
 parser.add_option_group(sambaopts)
 parser.add_option_group(options.VersionOptions(parser))
-credopts = options.CredentialsOptions(parser)
-parser.add_option_group(credopts)
 parser.add_option("--quiet", help="Be quiet")
-parser.add_option("--blank",
-                  help="do not add users or groups, just the structure")
 parser.add_option("--targetdir", type="string", metavar="DIR",
                   help="Set target directory")
 
@@ -60,19 +56,12 @@ if not os.path.isdir(libdir):
     print "error: %s is not a directory"
     sys.exit(1)
 
-if len(args) > 1:
-    smbconf = args[1]
-else:
-    smbconf = os.path.join(libdir, "smb.conf")
+lp = sambaopts.get_loadparm()
+smbconf = lp.configfile
 
 samba3 = Samba3(libdir, smbconf)
 
 logger.info("Provisioning")
 
-lp = sambaopts.get_loadparm()
-smbconf = lp.configfile
-creds = credopts.get_credentials(lp)
-
-upgrade_from_passdb(samba3, logger, credentials=creds,
-                   session_info=system_session(), smbconf=smbconf,
-                   targetdir=opts.targetdir)
+upgrade_from_samba3(samba3, logger, session_info=system_session(),
+            smbconf=smbconf, targetdir=opts.targetdir)