2 # backend code for provisioning a Samba4 server
3 # Copyright Andrew Tridgell 2005
4 # Copyright Jelmer Vernooij 2007
5 # Released under the GNU GPL v2 or later
8 from base64 import b64encode
14 from socket import gethostname, gethostbyname
17 from samba import Ldb, substitute_var, valid_netbios_name
18 from samba.samdb import SamDB
20 from ldb import Dn, SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \
21 LDB_ERR_NO_SUCH_OBJECT, timestring
24 class InvalidNetbiosName(Exception):
25 def __init__(self, name):
26 super(InvalidNetbiosName, self).__init__("The name '%r' is not a valid NetBIOS name" % name)
29 class ProvisionSettings(object):
30 def __init__(self, realm=None, domain=None, hostname=None, hostip=None):
33 self.hostname = hostname
36 self.invocationid = None
37 self.krbtgtpass = None
38 self.machinepass = None
40 self.defaultsite = "Default-First-Site-Name"
41 self.datestring = None
51 self.domaindn_ldb = None
54 self.configdn_ldb = None
56 self.schemedn_ldb = None
57 self.s4_ldapi_path = None
58 self.policyguid = None
61 return {"SCHEMADN": self.schemadn,
62 "SCHEMADN_LDB": self.schemadn_ldb,
63 "SCHEMADN_MOD": "schema_fsmo",
64 "SCHEMADN_MOD2": ",objectguid",
65 "CONFIGDN": self.configdn,
66 "TDB_MODULES_LIST": ","+",".join(self.tdb_modules_list),
67 "MODULES_LIST2": ",".join(self.modules_list2),
68 "CONFIGDN_LDB": self.configdn_ldb,
69 "DOMAINDN": self.domaindn,
70 "DOMAINDN_LDB": self.domaindn_ldb,
71 "DOMAINDN_MOD": "pdc_fsmo,password_hash",
72 "DOMAINDN_MOD2": ",objectguid",
73 "DOMAINSID": str(self.domainsid),
74 "MODULES_LIST": ",".join(self.modules_list),
75 "CONFIGDN_MOD": "naming_fsmo",
76 "CONFIGDN_MOD2": ",objectguid",
77 "NETBIOSNAME": self.netbiosname,
78 "DNSNAME": self.dnsname,
79 "ROOTDN": self.rootdn,
80 "DNSDOMAIN": self.dnsdomain,
82 "DEFAULTSITE": self.defaultsite,
83 "MACHINEPASS_B64": b64encode(self.machinepass),
84 "ADMINPASS_B64": b64encode(self.adminpass),
85 "DNSPASS_B64": b64encode(self.dnspass),
86 "KRBTGTPASS_B64": b64encode(self.krbtgtpass),
87 "S4_LDAPI_URI": "ldapi://%s" % self.s4_ldapi_path.replace("/", "%2F"),
88 "LDAPTIME": timestring(int(time.time())),
89 "POLICYGUID": self.policyguid,
90 "RDN_DC": self.rdn_dc,
91 "DOMAINGUID_MOD": self.domainguid_mod,
95 self.realm = self.realm.upper()
96 self.hostname = self.hostname.lower()
97 self.domain = self.domain.upper()
98 if not valid_netbios_name(self.domain):
99 raise InvalidNetbiosName(self.domain)
100 self.netbiosname = self.hostname.upper()
101 if not valid_netbios_name(self.netbiosname):
102 raise InvalidNetbiosName(self.netbiosname)
103 rdns = self.domaindn.split(",")
104 self.rdn_dc = rdns[0][len("DC="):]
106 self.sam_ldb = paths.samdb
107 self.secrets_ldb = paths.secrets
108 self.secrets_keytab = paths.keytab
110 self.s4_ldapi_path = paths.s4_ldapi_path
112 def validate(self, lp):
113 if not valid_netbios_name(self.domain):
114 raise InvalidNetbiosName(self.domain)
116 if not valid_netbios_name(self.netbiosname):
117 raise InvalidNetbiosName(self.netbiosname)
119 if lp.get_string("workgroup").upper() != self.domain.upper():
120 raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'\n",
121 lp.get_string("workgroup"), self.domain)
123 if lp.get_string("realm").upper() != self.realm.upper():
124 raise Error("realm '%s' in smb.conf must match chosen realm '%s'\n" %
125 (lp.get_string("realm"), self.realm))
128 class ProvisionPaths:
131 self.shareconf = None
143 self.ldap_basedn_ldif = None
144 self.ldap_config_basedn_ldif = None
145 self.ldap_schema_basedn_ldif = None
146 self.s4_ldapi_path = None
149 def install_ok(lp, session_info, credentials):
150 """Check whether the current install seems ok."""
151 if lp.get_string("realm") == "":
153 ldb = Ldb(lp.get_string("sam database"), session_info=session_info,
154 credentials=credentials)
155 if len(ldb.search("(cn=Administrator)")) != 1:
160 def findnss(nssfn, *names):
161 """Find a user or group from a list of possibilities."""
167 raise Exception("Unable to find user/group for %s" % arguments[1])
171 """return first host IP."""
172 return gethostbyname(hostname())
176 """return first part of hostname."""
177 return gethostname().split(".")[0]
181 """Delete a LDB file.
183 This may be necessary if the ldb is in bad shape, possibly due to being
184 built from an incompatible previous version of the code, so delete it
187 print "Deleting %s\n" % ldb.filename
188 os.unlink(ldb.filename)
189 ldb.connect(ldb.filename)
192 def open_ldb(session_info, credentials, dbname):
193 assert session_info is not None
195 return Ldb(dbname, session_info=session_info, credentials=credentials)
199 return Ldb(dbname, session_info=session_info, credentials=credentials)
202 def setup_add_ldif(setup_dir, ldif, subobj, ldb):
203 """Setup a ldb in the private dir."""
204 assert isinstance(ldif, str)
205 assert isinstance(setup_dir, str)
206 src = os.path.join(setup_dir, ldif)
208 data = open(src, 'r').read()
209 data = substitute_var(data, subobj.subst_vars())
211 for msg in ldb.parse_ldif(data):
215 def setup_modify_ldif(setup_dir, ldif, subobj, ldb):
216 src = os.path.join(setup_dir, ldif)
218 data = open(src, 'r').read()
219 data = substitute_var(data, subobj.subst_vars())
221 for (changetype, msg) in ldb.parse_ldif(data):
225 def setup_ldb(setup_dir, ldif, session_info, credentials, subobj, dbname,
227 assert dbname is not None
228 ldb = open_ldb(session_info, credentials, dbname)
229 assert ldb is not None
230 ldb.transaction_start()
234 setup_add_ldif(setup_dir, ldif, subobj, ldb)
236 ldb.transaction_cancel()
238 ldb.transaction_commit()
241 def setup_ldb_modify(setup_dir, ldif, subobj, ldb):
242 """Modify a ldb in the private dir."""
243 src = os.path.join(setup_dir, ldif)
245 data = open(src, 'r').read()
246 data = substitute_var(data, subobj.subst_vars())
247 assert not "${" in data
249 for (changetype, msg) in ldb.parse_ldif(data):
253 def setup_file(setup_dir, template, message, fname, subobj):
254 """Setup a file in the private dir."""
256 src = os.path.join(setup_dir, template)
260 data = open(src, 'r').read()
261 data = substitute_var(data, subobj.subst_vars())
262 assert not "${" in data
264 open(f, 'w').write(data)
267 def provision_default_paths(lp, subobj):
268 """Set the default paths for provisioning.
270 :param lp: Loadparm context.
271 :param subobj: Object
273 paths = ProvisionPaths()
274 private_dir = lp.get_string("private dir")
275 paths.shareconf = os.path.join(private_dir, "share.ldb")
276 paths.samdb = lp.get_string("sam database") or os.path.join(private_dir, "samdb.ldb")
277 paths.secrets = lp.get_string("secrets database") or os.path.join(private_dir, "secrets.ldb")
278 paths.templates = os.path.join(private_dir, "templates.ldb")
279 paths.keytab = os.path.join(private_dir, "secrets.keytab")
280 paths.dns = os.path.join(private_dir, subobj.dnsdomain + ".zone")
281 paths.winsdb = os.path.join(private_dir, "wins.ldb")
282 paths.ldap_basedn_ldif = os.path.join(private_dir, subobj.dnsdomain + ".ldif")
283 paths.ldap_config_basedn_ldif = os.path.join(private_dir, subobj.dnsdomain + "-config.ldif")
284 paths.ldap_schema_basedn_ldif = os.path.join(private_dir, subobj.dnsdomain + "-schema.ldif")
285 paths.s4_ldapi_path = os.path.join(private_dir, "ldapi")
286 paths.phpldapadminconfig = os.path.join(private_dir, "phpldapadmin-config.php")
287 paths.hklm = os.path.join(private_dir, "hklm.ldb")
291 def setup_name_mappings(subobj, ldb):
292 """setup reasonable name mappings for sam names to unix names."""
293 res = ldb.search(Dn(ldb, subobj.domaindn), SCOPE_BASE, "objectSid=*",
296 assert "objectSid" in res[0]
297 sid = list(res[0]["objectSid"])[0]
299 # add some foreign sids if they are not present already
300 ldb.add_foreign(subobj.domaindn, "S-1-5-7", "Anonymous")
301 ldb.add_foreign(subobj.domaindn, "S-1-1-0", "World")
302 ldb.add_foreign(subobj.domaindn, "S-1-5-2", "Network")
303 ldb.add_foreign(subobj.domaindn, "S-1-5-18", "System")
304 ldb.add_foreign(subobj.domaindn, "S-1-5-11", "Authenticated Users")
306 # some well known sids
307 ldb.setup_name_mapping(subobj.domaindn, "S-1-5-7", subobj.nobody)
308 ldb.setup_name_mapping(subobj.domaindn, "S-1-1-0", subobj.nogroup)
309 ldb.setup_name_mapping(subobj.domaindn, "S-1-5-2", subobj.nogroup)
310 ldb.setup_name_mapping(subobj.domaindn, "S-1-5-18", subobj.root)
311 ldb.setup_name_mapping(subobj.domaindn, "S-1-5-11", subobj.users)
312 ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-544", subobj.wheel)
313 ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-545", subobj.users)
314 ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-546", subobj.nogroup)
315 ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-551", subobj.backup)
317 # and some well known domain rids
318 ldb.setup_name_mapping(subobj.domaindn, sid + "-500", subobj.root)
319 ldb.setup_name_mapping(subobj.domaindn, sid + "-518", subobj.wheel)
320 ldb.setup_name_mapping(subobj.domaindn, sid + "-519", subobj.wheel)
321 ldb.setup_name_mapping(subobj.domaindn, sid + "-512", subobj.wheel)
322 ldb.setup_name_mapping(subobj.domaindn, sid + "-513", subobj.users)
323 ldb.setup_name_mapping(subobj.domaindn, sid + "-520", subobj.wheel)
326 def provision_become_dc(setup_dir, subobj, message, paths, session_info,
328 assert session_info is not None
331 message("Setting up templates into %s" % paths.templates)
332 setup_ldb(setup_dir, "provision_templates.ldif", session_info,
333 credentials, subobj, paths.templates)
335 # Also wipes the database
336 message("Setting up %s partitions" % paths.samdb)
337 setup_ldb(setup_dir, "provision_partitions.ldif", session_info,
338 credentials, subobj, paths.samdb)
340 samdb = SamDB(paths.samdb, session_info=session_info,
341 credentials=credentials)
342 ldb.transaction_start()
344 message("Setting up %s attributes" % paths.samdb)
345 setup_add_ldif(setup_dir, "provision_init.ldif", subobj, samdb)
347 message("Setting up %s rootDSE" % paths.samdb)
348 setup_add_ldif(setup_dir, "provision_rootdse_add.ldif", subobj, samdb)
350 message("Erasing data from partitions")
351 ldb_erase_partitions(subobj, message, samdb, None)
353 message("Setting up %s indexes" % paths.samdb)
354 setup_add_ldif(setup_dir, "provision_index.ldif", subobj, samdb)
356 samdb.transaction_cancel()
359 samdb.transaction_commit()
361 message("Setting up %s" % paths.secrets)
362 setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials,
363 subobj, paths.secrets)
365 setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj,
366 paths.secrets, False)
369 def provision(lp, setup_dir, subobj, message, blank, paths, session_info,
370 credentials, ldapbackend):
373 :note: caution, this wipes all existing data!
377 if subobj.domain_guid is not None:
378 subobj.domainguid_mod = "replace: objectGUID\nobjectGUID: %s\n-" % subobj.domain_guid
380 subobj.domainguid_mod = ""
382 if subobj.host_guid is not None:
383 subobj.hostguid_add = "objectGUID: %s" % subobj.host_guid
385 subobj.hostguid_add = ""
387 assert paths.smbconf is not None
389 # only install a new smb.conf if there isn't one there already
390 if not os.path.exists(paths.smbconf):
391 message("Setting up smb.conf")
392 setup_file(setup_dir, "provision.smb.conf", message, paths.smbconf, subobj)
395 # only install a new shares config db if there is none
396 if not os.path.exists(paths.shareconf):
397 message("Setting up share.ldb")
398 setup_ldb(setup_dir, "share.ldif", session_info, credentials, subobj, paths.shareconf)
400 message("Setting up %s" % paths.secrets)
401 setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, subobj, paths.secrets)
402 setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, paths.secrets, False)
404 message("Setting up registry")
405 reg = registry.Registry()
406 # FIXME: Still fails for some reason:
407 #reg.mount(paths.hklm, registry.HKEY_LOCAL_MACHINE, [])
408 #reg.apply_patchfile(os.path.join(setup_dir, "provision.reg"))
410 message("Setting up templates into %s" % paths.templates)
411 setup_ldb(setup_dir, "provision_templates.ldif", session_info, credentials, subobj, paths.templates)
413 message("Setting up sam.ldb partitions")
414 setup_ldb(setup_dir, "provision_partitions.ldif", session_info,
415 credentials, subobj, paths.samdb)
417 samdb = open_ldb(session_info, credentials, paths.samdb)
418 samdb.transaction_start()
420 message("Setting up sam.ldb attributes")
421 setup_add_ldif(setup_dir, "provision_init.ldif", subobj, samdb)
423 message("Setting up sam.ldb rootDSE")
424 setup_add_ldif(setup_dir, "provision_rootdse_add.ldif", subobj, samdb)
426 message("Erasing data from partitions")
427 ldb_erase_partitions(subobj, message, samdb, ldapbackend)
429 samdb.transaction_cancel()
432 samdb.transaction_commit()
434 message("Pre-loading the Samba 4 and AD schema")
436 samdb = open_ldb(session_info, credentials, paths.samdb)
438 samdb.set_domain_sid(subobj.domainsid)
440 load_schema(setup_dir, subobj, samdb)
442 samdb.transaction_start()
445 message("Adding DomainDN: %s (permitted to fail)" % subobj.domaindn)
446 setup_add_ldif(setup_dir, "provision_basedn.ldif", subobj, samdb)
447 message("Modifying DomainDN: " + subobj.domaindn + "")
448 setup_ldb_modify(setup_dir, "provision_basedn_modify.ldif", subobj, samdb)
450 message("Adding configuration container (permitted to fail)")
451 setup_add_ldif(setup_dir, "provision_configuration_basedn.ldif", subobj, samdb)
452 message("Modifying configuration container")
453 setup_ldb_modify(setup_dir, "provision_configuration_basedn_modify.ldif", subobj, samdb)
455 message("Adding schema container (permitted to fail)")
456 setup_add_ldif(setup_dir, "provision_schema_basedn.ldif", subobj, samdb)
457 message("Modifying schema container")
458 setup_ldb_modify(setup_dir, "provision_schema_basedn_modify.ldif", subobj, samdb)
459 message("Setting up sam.ldb Samba4 schema")
460 setup_add_ldif(setup_dir, "schema_samba4.ldif", subobj, samdb)
461 message("Setting up sam.ldb AD schema")
462 setup_add_ldif(setup_dir, "schema.ldif", subobj, samdb)
464 message("Setting up sam.ldb configuration data")
465 setup_add_ldif(setup_dir, "provision_configuration.ldif", subobj, samdb)
467 message("Setting up display specifiers")
468 setup_add_ldif(setup_dir, "display_specifiers.ldif", subobj, samdb)
470 message("Adding users container (permitted to fail)")
471 setup_add_ldif(setup_dir, "provision_users_add.ldif", subobj, samdb)
472 message("Modifying users container")
473 setup_ldb_modify(setup_dir, "provision_users_modify.ldif", subobj, samdb)
474 message("Adding computers container (permitted to fail)")
475 setup_add_ldif(setup_dir, "provision_computers_add.ldif", subobj, samdb)
476 message("Modifying computers container")
477 setup_ldb_modify(setup_dir, "provision_computers_modify.ldif", subobj, samdb)
478 message("Setting up sam.ldb data")
479 setup_add_ldif(setup_dir, "provision.ldif", subobj, samdb)
482 message("Setting up sam.ldb index")
483 setup_add_ldif(setup_dir, "provision_index.ldif", subobj, samdb)
485 message("Setting up sam.ldb rootDSE marking as syncronized")
486 setup_modify_ldif(setup_dir, "provision_rootdse_modify.ldif", subobj, samdb)
488 samdb.transaction_commit()
491 # message("Activate schema module")
492 # setup_modify_ldif("schema_activation.ldif", info, samdb, False)
494 # // (hack) Reload, now we have the schema loaded.
495 # commit_ok = samdb.transaction_commit()
497 # message("samdb commit failed: " + samdb.errstring() + "\n")
502 # samdb = open_ldb(info, paths.samdb, False)
504 message("Setting up sam.ldb users and groups")
505 setup_add_ldif(setup_dir, "provision_users.ldif", subobj, samdb)
507 setup_name_mappings(subobj, samdb)
509 message("Setting up sam.ldb index")
510 setup_add_ldif(setup_dir, "provision_index.ldif", subobj, samdb)
512 message("Setting up sam.ldb rootDSE marking as syncronized")
513 setup_modify_ldif(setup_dir, "provision_rootdse_modify.ldif", subobj, samdb)
515 samdb.transaction_cancel()
518 samdb.transaction_commit()
520 message("Setting up phpLDAPadmin configuration")
521 setup_file(setup_dir, "phpldapadmin-config.php", message,
522 paths.phpldapadminconfig, subobj)
523 message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig)
526 def provision_dns(setup_dir, subobj, message, paths, session_info, credentials):
527 """Write out a DNS zone file, from the info in the current database."""
528 message("Setting up DNS zone: %s" % subobj.dnsdomain)
530 ldb = SamDB(paths.samdb, session_info=session_info, credentials=credentials)
532 # These values may have changed, due to an incoming SamSync,
533 # or may not have been specified, so fetch them from the database
535 res = ldb.search(Dn(ldb, subobj.domaindn), SCOPE_BASE, "objectGUID=*",
537 assert(len(res) == 1)
538 assert(res[0]["objectGUID"] is not None)
539 subobj.domainguid = res[0]["objectGUID"]
541 subobj.host_guid = ldb.searchone(subobj.domaindn,
542 "(&(objectClass=computer)(cn=%s))" % subobj.netbiosname, "objectGUID")
543 assert subobj.host_guid is not None
545 setup_file(setup_dir, "provision.zone", message, paths.dns, subobj)
547 message("Please install the zone located in %s into your DNS server" % paths.dns)
550 def provision_ldapbase(setup_dir, subobj, message, paths):
551 """Write out a DNS zone file, from the info in the current database."""
552 message("Setting up LDAP base entry: %s" % subobj.domaindn)
553 rdns = subobj.domaindn.split(",")
554 subobj.extensibleobject = "objectClass: extensibleObject"
556 subobj.rdn_dc = rdns[0][len("DC="):]
558 setup_file(setup_dir, "provision_basedn.ldif",
559 message, paths.ldap_basedn_ldif,
562 setup_file(setup_dir, "provision_configuration_basedn.ldif",
563 message, paths.ldap_config_basedn_ldif,
566 setup_file(setup_dir, "provision_schema_basedn.ldif",
567 message, paths.ldap_schema_basedn_ldif,
570 message("Please install the LDIF located in " + paths.ldap_basedn_ldif + ", " + paths.ldap_config_basedn_ldif + " and " + paths.ldap_schema_basedn_ldif + " into your LDAP server, and re-run with --ldap-backend=ldap://my.ldap.server")
573 def provision_guess(lp):
574 """guess reasonably default options for provisioning."""
575 subobj = ProvisionSettings(realm=lp.get_string("realm").upper(),
576 domain=lp.get_string("workgroup"),
580 assert subobj.realm is not None
581 assert subobj.domain is not None
582 assert subobj.hostname is not None
584 subobj.domainsid = security.random_sid()
585 subobj.invocationid = uuid.random()
586 subobj.policyguid = uuid.random()
587 subobj.krbtgtpass = misc.random_password(12)
588 subobj.machinepass = misc.random_password(12)
589 subobj.adminpass = misc.random_password(12)
590 subobj.dnspass = misc.random_password(12)
591 subobj.datestring = time.strftime("%Y%m%d%H")
592 subobj.root = findnss(pwd.getpwnam, "root")[4]
593 subobj.nobody = findnss(pwd.getpwnam, "nobody")[4]
594 subobj.nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2]
595 subobj.wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[2]
596 subobj.backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[2]
597 subobj.users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", "usr")[2]
599 subobj.dnsdomain = subobj.realm.lower()
600 subobj.dnsname = "%s.%s" % (subobj.hostname.lower(), subobj.dnsdomain)
601 subobj.domaindn = "DC=" + subobj.dnsdomain.replace(".", ",DC=")
602 subobj.domaindn_ldb = "users.ldb"
603 subobj.rootdn = subobj.domaindn
604 subobj.configdn = "CN=Configuration," + subobj.rootdn
605 subobj.configdn_ldb = "configuration.ldb"
606 subobj.schemadn = "CN=Schema," + subobj.configdn
607 subobj.schemadn_ldb = "schema.ldb"
609 #Add modules to the list to activate them by default
610 #beware often order is important
612 # Some Known ordering constraints:
613 # - rootdse must be first, as it makes redirects from "" -> cn=rootdse
614 # - objectclass must be before password_hash, because password_hash checks
615 # that the objectclass is of type person (filled in by objectclass
616 # module when expanding the objectclass list)
617 # - partition must be last
618 # - each partition has its own module list then
619 subobj.modules_list = ["rootdse",
631 subobj.tdb_modules_list = [
635 subobj.modules_list2 = ["show_deleted",
638 subobj.extensibleobject = "# no objectClass: extensibleObject for local ldb"
639 subobj.aci = "# no aci for local ldb"
643 def load_schema(setup_dir, subobj, samdb):
645 src = os.path.join(setup_dir, "schema.ldif")
646 schema_data = open(src, 'r').read()
647 src = os.path.join(setup_dir, "schema_samba4.ldif")
648 schema_data += open(src, 'r').read()
649 schema_data = substitute_var(schema_data, subobj.subst_vars())
650 src = os.path.join(setup_dir, "provision_schema_basedn_modify.ldif")
651 head_data = open(src, 'r').read()
652 head_data = substitute_var(head_data, subobj.subst_vars())
653 samdb.attach_dsdb_schema_from_ldif(head_data, schema_data)
656 def join_domain(domain, netbios_name, join_type, creds, message):
657 ctx = NetContext(creds)
659 joindom.domain = domain
660 joindom.join_type = join_type
661 joindom.netbios_name = netbios_name
662 if not ctx.JoinDomain(joindom):
663 raise Exception("Domain Join failed: " + joindom.error_string)
666 def vampire(domain, session_info, credentials, message):
667 """Vampire a remote domain.
669 Session info and credentials are required for for
670 access to our local database (might be remote ldap)
672 ctx = NetContext(credentials)
673 vampire_ctx = object()
674 machine_creds = credentials_init()
675 machine_creds.set_domain(form.domain)
676 if not machine_creds.set_machine_account():
677 raise Exception("Failed to access domain join information!")
678 vampire_ctx.machine_creds = machine_creds
679 vampire_ctx.session_info = session_info
680 if not ctx.SamSyncLdb(vampire_ctx):
681 raise Exception("Migration of remote domain to Samba failed: %s " % vampire_ctx.error_string)
684 def ldb_erase_partitions(subobj, message, ldb, ldapbackend):
685 """Erase an ldb, removing all records."""
686 assert ldb is not None
687 res = ldb.search(Dn(ldb, ""), SCOPE_BASE, "(objectClass=*)",
690 if not "namingContexts" in res[0]:
692 for basedn in res[0]["namingContexts"]:
693 anything = "(|(objectclass=*)(dn=*))"
694 previous_remaining = 1
695 current_remaining = 0
697 if ldapbackend and (basedn == subobj.domaindn):
698 # Only delete objects that were created by provision
699 anything = "(objectcategory=*)"
702 while ++k < 10 and (previous_remaining != current_remaining):
704 res2 = ldb.search(Dn(ldb, basedn), SCOPE_SUBTREE, anything, ["dn"])
705 previous_remaining = current_remaining
706 current_remaining = len(res2)
710 except LdbError, (_, text):
711 message("Unable to delete %s: %s" % (msg.dn, text))