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 = SamDB(paths.samdb, session_info, credentials)
437 samdb.set_domain_sid(subobj.domainsid)
438 load_schema(setup_dir, subobj, samdb)
440 samdb.transaction_start()
443 message("Adding DomainDN: %s (permitted to fail)" % subobj.domaindn)
444 setup_add_ldif(setup_dir, "provision_basedn.ldif", subobj, samdb)
445 message("Modifying DomainDN: " + subobj.domaindn + "")
446 setup_ldb_modify(setup_dir, "provision_basedn_modify.ldif", subobj, samdb)
448 message("Adding configuration container (permitted to fail)")
449 setup_add_ldif(setup_dir, "provision_configuration_basedn.ldif", subobj, samdb)
450 message("Modifying configuration container")
451 setup_ldb_modify(setup_dir, "provision_configuration_basedn_modify.ldif", subobj, samdb)
453 message("Adding schema container (permitted to fail)")
454 setup_add_ldif(setup_dir, "provision_schema_basedn.ldif", subobj, samdb)
455 message("Modifying schema container")
456 setup_ldb_modify(setup_dir, "provision_schema_basedn_modify.ldif", subobj, samdb)
457 message("Setting up sam.ldb Samba4 schema")
458 setup_add_ldif(setup_dir, "schema_samba4.ldif", subobj, samdb)
459 message("Setting up sam.ldb AD schema")
460 setup_add_ldif(setup_dir, "schema.ldif", subobj, samdb)
462 message("Setting up sam.ldb configuration data")
463 setup_add_ldif(setup_dir, "provision_configuration.ldif", subobj, samdb)
465 message("Setting up display specifiers")
466 setup_add_ldif(setup_dir, "display_specifiers.ldif", subobj, samdb)
468 message("Adding users container (permitted to fail)")
469 setup_add_ldif(setup_dir, "provision_users_add.ldif", subobj, samdb)
470 message("Modifying users container")
471 setup_ldb_modify(setup_dir, "provision_users_modify.ldif", subobj, samdb)
472 message("Adding computers container (permitted to fail)")
473 setup_add_ldif(setup_dir, "provision_computers_add.ldif", subobj, samdb)
474 message("Modifying computers container")
475 setup_ldb_modify(setup_dir, "provision_computers_modify.ldif", subobj, samdb)
476 message("Setting up sam.ldb data")
477 setup_add_ldif(setup_dir, "provision.ldif", subobj, samdb)
480 message("Setting up sam.ldb index")
481 setup_add_ldif(setup_dir, "provision_index.ldif", subobj, samdb)
483 message("Setting up sam.ldb rootDSE marking as syncronized")
484 setup_modify_ldif(setup_dir, "provision_rootdse_modify.ldif", subobj, samdb)
486 samdb.transaction_commit()
489 # message("Activate schema module")
490 # setup_modify_ldif("schema_activation.ldif", info, samdb, False)
492 # // (hack) Reload, now we have the schema loaded.
493 # commit_ok = samdb.transaction_commit()
495 # message("samdb commit failed: " + samdb.errstring() + "\n")
500 # samdb = open_ldb(info, paths.samdb, False)
502 message("Setting up sam.ldb users and groups")
503 setup_add_ldif(setup_dir, "provision_users.ldif", subobj, samdb)
505 setup_name_mappings(subobj, samdb)
507 message("Setting up sam.ldb index")
508 setup_add_ldif(setup_dir, "provision_index.ldif", subobj, samdb)
510 message("Setting up sam.ldb rootDSE marking as syncronized")
511 setup_modify_ldif(setup_dir, "provision_rootdse_modify.ldif", subobj, samdb)
513 samdb.transaction_cancel()
516 samdb.transaction_commit()
518 message("Setting up phpLDAPadmin configuration")
519 setup_file(setup_dir, "phpldapadmin-config.php", message,
520 paths.phpldapadminconfig, subobj)
521 message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig)
524 def provision_dns(setup_dir, subobj, message, paths, session_info, credentials):
525 """Write out a DNS zone file, from the info in the current database."""
526 message("Setting up DNS zone: %s" % subobj.dnsdomain)
528 ldb = SamDB(paths.samdb, session_info=session_info, credentials=credentials)
530 # These values may have changed, due to an incoming SamSync,
531 # or may not have been specified, so fetch them from the database
533 res = ldb.search(Dn(ldb, subobj.domaindn), SCOPE_BASE, "objectGUID=*",
535 assert(len(res) == 1)
536 assert(res[0]["objectGUID"] is not None)
537 subobj.domainguid = res[0]["objectGUID"]
539 subobj.host_guid = ldb.searchone(subobj.domaindn,
540 "(&(objectClass=computer)(cn=%s))" % subobj.netbiosname, "objectGUID")
541 assert subobj.host_guid is not None
543 setup_file(setup_dir, "provision.zone", message, paths.dns, subobj)
545 message("Please install the zone located in %s into your DNS server" % paths.dns)
548 def provision_ldapbase(setup_dir, subobj, message, paths):
549 """Write out a DNS zone file, from the info in the current database."""
550 message("Setting up LDAP base entry: %s" % subobj.domaindn)
551 rdns = subobj.domaindn.split(",")
552 subobj.extensibleobject = "objectClass: extensibleObject"
554 subobj.rdn_dc = rdns[0][len("DC="):]
556 setup_file(setup_dir, "provision_basedn.ldif",
557 message, paths.ldap_basedn_ldif,
560 setup_file(setup_dir, "provision_configuration_basedn.ldif",
561 message, paths.ldap_config_basedn_ldif,
564 setup_file(setup_dir, "provision_schema_basedn.ldif",
565 message, paths.ldap_schema_basedn_ldif,
568 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")
571 def provision_guess(lp):
572 """guess reasonably default options for provisioning."""
573 subobj = ProvisionSettings(realm=lp.get_string("realm").upper(),
574 domain=lp.get_string("workgroup"),
578 assert subobj.realm is not None
579 assert subobj.domain is not None
580 assert subobj.hostname is not None
582 subobj.domainsid = security.random_sid()
583 subobj.invocationid = uuid.random()
584 subobj.policyguid = uuid.random()
585 subobj.krbtgtpass = misc.random_password(12)
586 subobj.machinepass = misc.random_password(12)
587 subobj.adminpass = misc.random_password(12)
588 subobj.dnspass = misc.random_password(12)
589 subobj.datestring = time.strftime("%Y%m%d%H")
590 subobj.root = findnss(pwd.getpwnam, "root")[4]
591 subobj.nobody = findnss(pwd.getpwnam, "nobody")[4]
592 subobj.nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2]
593 subobj.wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[2]
594 subobj.backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[2]
595 subobj.users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", "usr")[2]
597 subobj.dnsdomain = subobj.realm.lower()
598 subobj.dnsname = "%s.%s" % (subobj.hostname.lower(), subobj.dnsdomain)
599 subobj.domaindn = "DC=" + subobj.dnsdomain.replace(".", ",DC=")
600 subobj.domaindn_ldb = "users.ldb"
601 subobj.rootdn = subobj.domaindn
602 subobj.configdn = "CN=Configuration," + subobj.rootdn
603 subobj.configdn_ldb = "configuration.ldb"
604 subobj.schemadn = "CN=Schema," + subobj.configdn
605 subobj.schemadn_ldb = "schema.ldb"
607 #Add modules to the list to activate them by default
608 #beware often order is important
610 # Some Known ordering constraints:
611 # - rootdse must be first, as it makes redirects from "" -> cn=rootdse
612 # - objectclass must be before password_hash, because password_hash checks
613 # that the objectclass is of type person (filled in by objectclass
614 # module when expanding the objectclass list)
615 # - partition must be last
616 # - each partition has its own module list then
617 subobj.modules_list = ["rootdse",
629 subobj.tdb_modules_list = [
633 subobj.modules_list2 = ["show_deleted",
636 subobj.extensibleobject = "# no objectClass: extensibleObject for local ldb"
637 subobj.aci = "# no aci for local ldb"
641 def load_schema(setup_dir, subobj, samdb):
643 src = os.path.join(setup_dir, "schema.ldif")
644 schema_data = open(src, 'r').read()
645 src = os.path.join(setup_dir, "schema_samba4.ldif")
646 schema_data += open(src, 'r').read()
647 schema_data = substitute_var(schema_data, subobj.subst_vars())
648 src = os.path.join(setup_dir, "provision_schema_basedn_modify.ldif")
649 head_data = open(src, 'r').read()
650 head_data = substitute_var(head_data, subobj.subst_vars())
651 samdb.attach_schema_from_ldif(head_data, schema_data)
654 def join_domain(domain, netbios_name, join_type, creds, message):
655 ctx = NetContext(creds)
657 joindom.domain = domain
658 joindom.join_type = join_type
659 joindom.netbios_name = netbios_name
660 if not ctx.JoinDomain(joindom):
661 raise Exception("Domain Join failed: " + joindom.error_string)
664 def vampire(domain, session_info, credentials, message):
665 """Vampire a remote domain.
667 Session info and credentials are required for for
668 access to our local database (might be remote ldap)
670 ctx = NetContext(credentials)
671 vampire_ctx = object()
672 machine_creds = credentials_init()
673 machine_creds.set_domain(form.domain)
674 if not machine_creds.set_machine_account():
675 raise Exception("Failed to access domain join information!")
676 vampire_ctx.machine_creds = machine_creds
677 vampire_ctx.session_info = session_info
678 if not ctx.SamSyncLdb(vampire_ctx):
679 raise Exception("Migration of remote domain to Samba failed: %s " % vampire_ctx.error_string)
682 def ldb_erase_partitions(subobj, message, ldb, ldapbackend):
683 """Erase an ldb, removing all records."""
684 assert ldb is not None
685 res = ldb.search(Dn(ldb, ""), SCOPE_BASE, "(objectClass=*)",
688 if not "namingContexts" in res[0]:
690 for basedn in res[0]["namingContexts"]:
691 anything = "(|(objectclass=*)(dn=*))"
692 previous_remaining = 1
693 current_remaining = 0
695 if ldapbackend and (basedn == subobj.domaindn):
696 # Only delete objects that were created by provision
697 anything = "(objectcategory=*)"
700 while ++k < 10 and (previous_remaining != current_remaining):
702 res2 = ldb.search(Dn(ldb, basedn), SCOPE_SUBTREE, anything, ["dn"])
703 previous_remaining = current_remaining
704 current_remaining = len(res2)
708 except LdbError, (_, text):
709 message("Unable to delete %s: %s" % (msg.dn, text))