From c926cddfad97713ca017c03e61c6e90414c1ad62 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 09:29:00 +0100 Subject: r26366: Import provision scripts in Python. (This used to be commit 090c799f98adf2c4186daca445c81b4e26e91f2f) --- source4/scripting/python/samba/provision.py | 842 ++++++++++++++++++++++++++++ 1 file changed, 842 insertions(+) create mode 100644 source4/scripting/python/samba/provision.py (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py new file mode 100644 index 0000000000..3d391863da --- /dev/null +++ b/source4/scripting/python/samba/provision.py @@ -0,0 +1,842 @@ +# +# backend code for provisioning a Samba4 server +# Copyright Andrew Tridgell 2005 +# Copyright Jelmer Vernooij 2007 +# Released under the GNU GPL v2 or later +# + +from base64 import b64encode +import os +import pwd +import grp +import time +import uuid, sid, misc +from socket import gethostname, gethostbyname +import param +import registry +from samba import Ldb, substitute_var +from ldb import Dn, SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ + LDB_ERR_NO_SUCH_OBJECT, timestring + + +class InvalidNetbiosName(Exception): + def __init__(self, name): + super(InvalidNetbiosName, self).__init__("The name '%r' is not a valid NetBIOS name" % name) + + +class ProvisionSettings(object): + def __init__(self, realm=None, domain=None, hostname=None, hostip=None): + self.realm = realm + self.domain = domain + self.hostname = hostname + self.hostip = hostip + self.domainsid = None + self.invocationid = None + self.krbtgtpass = None + self.machinepass = None + self.adminpass = None + self.defaultsite = "Default-First-Site-Name" + self.datestring = None + self.root = None + self.nobody = None + self.nogroup = None + self.wheel = None + self.backup = None + self.users = None + self.dnsdomain = None + self.dnsname = None + self.domaindn = None + self.domaindn_ldb = None + self.rootdn = None + self.configdn = None + self.configdn_ldb = None + self.schemedn = None + self.schemedn_ldb = None + self.s4_ldapi_path = None + self.policyguid = None + + def subst_vars(self): + return {"SCHEMADN": self.schemadn, + "SCHEMADN_LDB": self.schemadn_ldb, + "SCHEMADN_MOD": "schema_fsmo", + "SCHEMADN_MOD2": ",objectguid", + "CONFIGDN": self.configdn, + "TDB_MODULES_LIST": ","+",".join(self.tdb_modules_list) + "MODULES_LIST2": ",".join(self.modules_list2) + "CONFIGDN_LDB": self.configdn_ldb, + "DOMAINDN": self.domaindn, + "DOMAINDN_LDB": self.domaindn_ldb, + "DOMAINDN_MOD": "pdc_fsmo,password_hash", + "DOMAINDN_MOD2": ",objectguid", + "DOMAINSID": self.domainsid, + "MODULES_LIST": ",".join(self.modules_list), + "CONFIGDN_MOD": "naming_fsmo", + "CONFIGDN_MOD2": ",objectguid", + "NETBIOSNAME": self.netbiosname, + "DNSNAME": self.dnsname, + "ROOTDN": self.rootdn, + "DNSDOMAIN": self.dnsdomain, + "REALM": self.realm, + "DEFAULTSITE": self.defaultsite, + "MACHINEPASS_B64": b64encode(self.machinepass), + "ADMINPASS_B64": b64encode(self.adminpass), + "DNSPASS_B64": b64encode(self.dnspass), + "KRBTGTPASS_B64": b64encode(self.krbtgtpass), + "S4_LDAPI_URI": "ldapi://%s" % self.s4_ldapi_path.replace("/", "%2F"), + "LDAPTIME": timestring(int(time.time())), + "POLICYGUID": self.policyguid, + "RDN_DC": self.rdn_dc, + "DOMAINGUID_MOD": self.domainguid_mod, + } + + def fix(self, paths): + self.realm = self.realm.upper() + self.hostname = self.hostname.lower() + self.domain = self.domain.upper() + if not valid_netbios_name(self.domain): + raise InvalidNetbiosName(self.domain) + self.netbiosname = self.hostname.upper() + if not valid_netbios_name(self.netbiosname): + raise InvalidNetbiosName(self.netbiosname) + rdns = self.domaindn.split(",") + self.rdn_dc = rdns[0][len("DC="):] + + self.sam_ldb = paths.samdb + self.secrets_ldb = paths.secrets + self.secrets_keytab = paths.keytab + + self.s4_ldapi_path = paths.s4_ldapi_path + + def validate(self, lp): + if not valid_netbios_name(self.domain): + raise InvalidNetbiosName(self.domain) + + if not valid_netbios_name(self.netbiosname): + raise InvalidNetbiosName(self.netbiosname) + + if lp.get("workgroup").upper() != self.domain.upper(): + raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'\n", + lp.get("workgroup"), self.domain) + + if lp.get("realm").upper() != self.realm.upper(): + raise Error("realm '%s' in smb.conf must match chosen realm '%s'\n" % + (lp.get("realm"), self.realm)) + + +class ProvisionPaths: + def __init__(self): + self.smbconf = None + self.shareconf = None + self.hklm = None + self.hkcu = None + self.hkcr = None + self.hku = None + self.hkpd = None + self.hkpt = None + self.samdb = None + self.secrets = None + self.keytab = None + self.dns = None + self.winsdb = None + self.ldap_basedn_ldif = None + self.ldap_config_basedn_ldif = None + self.ldap_schema_basedn_ldif = None + self.s4_ldapi_path = None + + +def install_ok(lp, session_info, credentials): + """Check whether the current install seems ok.""" + if lp.get("realm") == "": + return False + ldb = Ldb(lp.get("sam database"), session_info=session_info, + credentials=credentials) + if len(ldb.search("(cn=Administrator)")) != 1: + return False + return True + + +def findnss(nssfn, *names): + """Find a user or group from a list of possibilities.""" + for name in names: + try: + return nssfn(name) + except KeyError: + pass + raise Exception("Unable to find user/group for %s" % arguments[1]) + +def add_foreign(ldb, subobj, sid, desc): + """Add a foreign security principle.""" + add = """ +dn: CN=%s,CN=ForeignSecurityPrincipals,%s +objectClass: top +objectClass: foreignSecurityPrincipal +description: %s +""" % (sid, subobj.domaindn, desc) + # deliberately ignore errors from this, as the records may + # already exist + for msg in ldb.parse_ldif(add): + ldb.add(msg[1]) + +def setup_name_mapping(subobj, ldb, sid, unixname): + """Setup a mapping between a sam name and a unix name.""" + res = ldb.search(Dn(ldb, subobj.domaindn), SCOPE_SUBTREE, + "objectSid=%s" % sid, ["dn"]) + assert len(res) == 1, "Failed to find record for objectSid %s" % sid + + mod = """ +dn: %s +changetype: modify +replace: unixName +unixName: %s +""" % (res[0].dn, unixname) + ldb.modify(ldb.parse_ldif(mod).next()[1]) + +def hostip(): + """return first host IP.""" + return gethostbyname(hostname()) + +def hostname(): + """return first part of hostname.""" + return gethostname().split(".")[0] + +def ldb_delete(ldb): + """Delete a LDB file. + + This may be necessary if the ldb is in bad shape, possibly due to being + built from an incompatible previous version of the code, so delete it + completely. + """ + print "Deleting %s\n" % ldb.filename + os.unlink(ldb.filename) + ldb.connect(ldb.filename) + + +def ldb_erase(ldb): + """Erase an ldb, removing all records.""" + # delete the specials + for attr in ["@INDEXLIST", "@ATTRIBUTES", "@SUBCLASSES", "@MODULES", + "@OPTIONS", "@PARTITION", "@KLUDGEACL"]: + try: + ldb.delete(Dn(ldb, attr)) + except LdbError, (LDB_ERR_NO_SUCH_OBJECT, _): + # Ignore missing dn errors + pass + + basedn = Dn(ldb, "") + # and the rest + for msg in ldb.search(basedn, SCOPE_SUBTREE, + "(&(|(objectclass=*)(dn=*))(!(dn=@BASEINFO)))", + ["dn"]): + ldb.delete(msg.dn) + + res = ldb.search(basedn, SCOPE_SUBTREE, "(&(|(objectclass=*)(dn=*))(!(dn=@BASEINFO)))", ["dn"]) + assert len(res) == 0 + + +def ldb_erase_partitions(subobj, message, ldb, ldapbackend): + """Erase an ldb, removing all records.""" + assert ldb is not None + res = ldb.search(Dn(ldb, ""), SCOPE_BASE, "(objectClass=*)", + ["namingContexts"]) + assert len(res) == 1 + if not "namingContexts" in res[0]: + return + for basedn in res[0]["namingContexts"]: + anything = "(|(objectclass=*)(dn=*))" + previous_remaining = 1 + current_remaining = 0 + + if ldapbackend and (basedn == subobj.domaindn): + # Only delete objects that were created by provision + anything = "(objectcategory=*)" + + k = 0 + while ++k < 10 and (previous_remaining != current_remaining): + # and the rest + res2 = ldb.search(Dn(ldb, basedn), SCOPE_SUBTREE, anything, ["dn"]) + previous_remaining = current_remaining + current_remaining = len(res2) + for msg in res2: + try: + ldb.delete(msg.dn) + except LdbError, (_, text): + message("Unable to delete %s: %s" % (msg.dn, text)) + + +def open_ldb(session_info, credentials, dbname): + assert session_info is not None + try: + return Ldb(dbname, session_info=session_info, credentials=credentials) + except LdbError, e: + print e + os.unlink(dbname) + return Ldb(dbname, session_info=session_info, credentials=credentials) + + +def setup_add_ldif(setup_dir, ldif, subobj, ldb): + """Setup a ldb in the private dir.""" + assert isinstance(ldif, str) + assert isinstance(setup_dir, str) + src = os.path.join(setup_dir, ldif) + + data = open(src, 'r').read() + data = substitute_var(data, subobj.subst_vars()) + + for msg in ldb.parse_ldif(data): + ldb.add(msg[1]) + + +def setup_modify_ldif(setup_dir, ldif, subobj, ldb): + src = os.path.join(setup_dir, ldif) + + data = open(src, 'r').read() + data = substitute_var(data, subobj.subst_vars()) + + for (changetype, msg) in ldb.parse_ldif(data): + ldb.modify(msg) + + +def setup_ldb(setup_dir, ldif, session_info, credentials, subobj, dbname, + erase=True): + assert dbname is not None + ldb = open_ldb(session_info, credentials, dbname) + assert ldb is not None + ldb.transaction_start() + try: + if erase: + ldb_erase(ldb); + setup_add_ldif(setup_dir, ldif, subobj, ldb) + except: + ldb.transaction_cancel() + raise + ldb.transaction_commit() + + +def setup_ldb_modify(setup_dir, ldif, subobj, ldb): + """Modify a ldb in the private dir.""" + src = os.path.join(setup_dir, ldif) + + data = open(src, 'r').read() + data = substitute_var(data, subobj.subst_vars()) + assert not "${" in data + + for (changetype, msg) in ldb.parse_ldif(data): + ldb.modify(msg) + + +def setup_file(setup_dir, template, message, fname, subobj): + """Setup a file in the private dir.""" + f = fname + src = os.path.join(setup_dir, template) + + os.unlink(f) + + data = open(src, 'r').read() + data = substitute_var(data, subobj.subst_vars()) + assert not "${" in data + + open(f, 'w').write(data) + + +def provision_default_paths(lp, subobj): + """Set the default paths for provisioning. + + :param lp: Loadparm context. + :param subobj: Object + """ + paths = ProvisionPaths() + private_dir = lp.get("private dir") + paths.shareconf = os.path.join(private_dir, "share.ldb") + paths.samdb = lp.get("sam database") or os.path.join(private_dir, "samdb.ldb") + paths.secrets = lp.get("secrets database") or os.path.join(private_dir, "secrets.ldb") + paths.templates = os.path.join(private_dir, "templates.ldb") + paths.keytab = os.path.join(private_dir, "secrets.keytab") + paths.dns = os.path.join(private_dir, subobj.dnsdomain + ".zone") + paths.winsdb = os.path.join(private_dir, "wins.ldb") + paths.ldap_basedn_ldif = os.path.join(private_dir, subobj.dnsdomain + ".ldif") + paths.ldap_config_basedn_ldif = os.path.join(private_dir, subobj.dnsdomain + "-config.ldif") + paths.ldap_schema_basedn_ldif = os.path.join(private_dir, subobj.dnsdomain + "-schema.ldif") + paths.s4_ldapi_path = os.path.join(private_dir, "ldapi") + paths.phpldapadminconfig = os.path.join(private_dir, "phpldapadmin-config.php") + paths.hklm = os.path.join(private_dir, "hklm.ldb") + return paths + + +def setup_name_mappings(subobj, ldb): + """setup reasonable name mappings for sam names to unix names.""" + res = ldb.search(Dn(ldb, subobj.domaindn), SCOPE_BASE, "objectSid=*", + ["objectSid"]) + assert len(res) == 1 + assert "objectSid" in res[0] + sid = list(res[0]["objectSid"])[0] + + # add some foreign sids if they are not present already + add_foreign(ldb, subobj, "S-1-5-7", "Anonymous") + add_foreign(ldb, subobj, "S-1-1-0", "World") + add_foreign(ldb, subobj, "S-1-5-2", "Network") + add_foreign(ldb, subobj, "S-1-5-18", "System") + add_foreign(ldb, subobj, "S-1-5-11", "Authenticated Users") + + # some well known sids + setup_name_mapping(subobj, ldb, "S-1-5-7", subobj.nobody) + setup_name_mapping(subobj, ldb, "S-1-1-0", subobj.nogroup) + setup_name_mapping(subobj, ldb, "S-1-5-2", subobj.nogroup) + setup_name_mapping(subobj, ldb, "S-1-5-18", subobj.root) + setup_name_mapping(subobj, ldb, "S-1-5-11", subobj.users) + setup_name_mapping(subobj, ldb, "S-1-5-32-544", subobj.wheel) + setup_name_mapping(subobj, ldb, "S-1-5-32-545", subobj.users) + setup_name_mapping(subobj, ldb, "S-1-5-32-546", subobj.nogroup) + setup_name_mapping(subobj, ldb, "S-1-5-32-551", subobj.backup) + + # and some well known domain rids + setup_name_mapping(subobj, ldb, sid + "-500", subobj.root) + setup_name_mapping(subobj, ldb, sid + "-518", subobj.wheel) + setup_name_mapping(subobj, ldb, sid + "-519", subobj.wheel) + setup_name_mapping(subobj, ldb, sid + "-512", subobj.wheel) + setup_name_mapping(subobj, ldb, sid + "-513", subobj.users) + setup_name_mapping(subobj, ldb, sid + "-520", subobj.wheel) + + +def provision_become_dc(setup_dir, subobj, message, paths, session_info, + credentials): + assert session_info is not None + subobj.fix(paths) + + message("Setting up templates into %s" % paths.templates) + setup_ldb(setup_dir, "provision_templates.ldif", session_info, + credentials, subobj, paths.templates) + + # Also wipes the database + message("Setting up %s partitions" % paths.samdb) + setup_ldb(setup_dir, "provision_partitions.ldif", session_info, + credentials, subobj, paths.samdb) + + samdb = open_ldb(session_info, credentials, paths.samdb) + ldb.transaction_start() + try: + message("Setting up %s attributes" % paths.samdb) + setup_add_ldif(setup_dir, "provision_init.ldif", subobj, samdb) + + message("Setting up %s rootDSE" % paths.samdb) + setup_add_ldif(setup_dir, "provision_rootdse_add.ldif", subobj, samdb) + + message("Erasing data from partitions") + ldb_erase_partitions(subobj, message, samdb, undefined) + + message("Setting up %s indexes" % paths.samdb) + setup_add_ldif(setup_dir, "provision_index.ldif", subobj, samdb) + except: + samdb.transaction_cancel() + raise + + samdb.transaction_commit() + + message("Setting up %s" % paths.secrets) + setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, + subobj, paths.secrets) + + setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, + paths.secrets, False) + + +def provision(lp, setup_dir, subobj, message, blank, paths, session_info, + credentials, ldapbackend): + """Provision samba4 + + :note: caution, this wipes all existing data! + """ + subobj.fix(paths) + + if subobj.domain_guid is not None: + subobj.domainguid_mod = "replace: objectGUID\nobjectGUID: %s\n-" % subobj.domain_guid + else: + subobj.domainguid_mod = "" + + if subobj.host_guid is not None: + subobj.hostguid_add = "objectGUID: %s" % subobj.host_guid + else: + subobj.hostguid_add = "" + + assert paths.smbconf is not None + + # only install a new smb.conf if there isn't one there already + if not os.path.exists(paths.smbconf): + message("Setting up smb.conf") + setup_file(setup_dir, "provision.smb.conf", message, paths.smbconf, subobj) + lp.reload() + + # only install a new shares config db if there is none + if not os.path.exists(paths.shareconf): + message("Setting up share.ldb") + setup_ldb(setup_dir, "share.ldif", session_info, credentials, subobj, paths.shareconf) + + message("Setting up %s" % paths.secrets) + setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, subobj, paths.secrets) + setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, paths.secrets, False) + + message("Setting up registry") + reg = registry.Registry() + # FIXME: Still fails for some reason: + #reg.mount(paths.hklm, registry.HKEY_LOCAL_MACHINE, []) + #reg.apply_patchfile(os.path.join(setup_dir, "provision.reg")) + + message("Setting up templates into %s" % paths.templates) + setup_ldb(setup_dir, "provision_templates.ldif", session_info, credentials, subobj, paths.templates) + + message("Setting up sam.ldb partitions") + setup_ldb(setup_dir, "provision_partitions.ldif", session_info, + credentials, subobj, paths.samdb) + + samdb = open_ldb(session_info, credentials, paths.samdb) + samdb.transaction_start() + try: + message("Setting up sam.ldb attributes") + setup_add_ldif(setup_dir, "provision_init.ldif", subobj, samdb) + + message("Setting up sam.ldb rootDSE") + setup_add_ldif(setup_dir, "provision_rootdse_add.ldif", subobj, samdb) + + message("Erasing data from partitions") + ldb_erase_partitions(subobj, message, samdb, ldapbackend) + except: + samdb.transaction_cancel() + raise + + samdb.transaction_commit() + + message("Pre-loading the Samba 4 and AD schema") + + samdb = open_ldb(session_info, credentials, paths.samdb) + + samdb.set_domain_sid(subobj.domainsid) + + load_schema(setup_dir, subobj, samdb) + + samdb.transaction_start() + + try: + message("Adding DomainDN: %s (permitted to fail)" % subobj.domaindn) + setup_add_ldif(setup_dir, "provision_basedn.ldif", subobj, samdb) + message("Modifying DomainDN: " + subobj.domaindn + "") + setup_ldb_modify(setup_dir, "provision_basedn_modify.ldif", subobj, samdb) + + message("Adding configuration container (permitted to fail)") + setup_add_ldif(setup_dir, "provision_configuration_basedn.ldif", subobj, samdb) + message("Modifying configuration container") + setup_ldb_modify(setup_dir, "provision_configuration_basedn_modify.ldif", subobj, samdb) + + message("Adding schema container (permitted to fail)") + setup_add_ldif(setup_dir, "provision_schema_basedn.ldif", subobj, samdb) + message("Modifying schema container") + setup_ldb_modify(setup_dir, "provision_schema_basedn_modify.ldif", subobj, samdb) + message("Setting up sam.ldb Samba4 schema") + setup_add_ldif(setup_dir, "schema_samba4.ldif", subobj, samdb) + message("Setting up sam.ldb AD schema") + setup_add_ldif(setup_dir, "schema.ldif", subobj, samdb) + + message("Setting up sam.ldb configuration data") + setup_add_ldif(setup_dir, "provision_configuration.ldif", subobj, samdb) + + message("Setting up display specifiers") + setup_add_ldif(setup_dir, "display_specifiers.ldif", subobj, samdb) + + message("Adding users container (permitted to fail)") + setup_add_ldif(setup_dir, "provision_users_add.ldif", subobj, samdb) + message("Modifying users container") + setup_ldb_modify(setup_dir, "provision_users_modify.ldif", subobj, samdb) + message("Adding computers container (permitted to fail)") + setup_add_ldif(setup_dir, "provision_computers_add.ldif", subobj, samdb) + message("Modifying computers container") + setup_ldb_modify(setup_dir, "provision_computers_modify.ldif", subobj, samdb) + message("Setting up sam.ldb data") + setup_add_ldif(setup_dir, "provision.ldif", subobj, samdb) + + if blank: + message("Setting up sam.ldb index") + setup_add_ldif(setup_dir, "provision_index.ldif", subobj, samdb) + + message("Setting up sam.ldb rootDSE marking as syncronized") + setup_modify_ldif(setup_dir, "provision_rootdse_modify.ldif", subobj, samdb) + + samdb.transaction_commit() + return + + # message("Activate schema module") + # setup_modify_ldif("schema_activation.ldif", info, samdb, False) + # + # // (hack) Reload, now we have the schema loaded. + # commit_ok = samdb.transaction_commit() + # if (!commit_ok) { + # message("samdb commit failed: " + samdb.errstring() + "\n") + # assert(commit_ok) + # } + # samdb.close() + # + # samdb = open_ldb(info, paths.samdb, False) + # + message("Setting up sam.ldb users and groups") + setup_add_ldif(setup_dir, "provision_users.ldif", subobj, samdb) + + setup_name_mappings(subobj, samdb) + + message("Setting up sam.ldb index") + setup_add_ldif(setup_dir, "provision_index.ldif", subobj, samdb) + + message("Setting up sam.ldb rootDSE marking as syncronized") + setup_modify_ldif(setup_dir, "provision_rootdse_modify.ldif", subobj, samdb) + except: + samdb.transaction_cancel() + raise + + samdb.transaction_commit() + + message("Setting up phpLDAPadmin configuration") + setup_file(setup_dir, "phpldapadmin-config.php", message, + paths.phpldapadminconfig, subobj) + message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) + + +def provision_dns(setup_dir, subobj, message, paths, session_info, credentials): + """Write out a DNS zone file, from the info in the current database.""" + message("Setting up DNS zone: %s" % subobj.dnsdomain) + # connect to the sam + ldb = Ldb(paths.samdb, session_info=session_info, credentials=credentials) + + # These values may have changed, due to an incoming SamSync, + # or may not have been specified, so fetch them from the database + + res = ldb.search(Dn(ldb, subobj.domaindn), SCOPE_BASE, "objectGUID=*", + ["objectGUID"]) + assert(len(res) == 1) + assert(res[0]["objectGUID"] is not None) + subobj.domainguid = res[0]["objectGUID"] + + subobj.host_guid = searchone(ldb, subobj.domaindn, + "(&(objectClass=computer)(cn=%s))" % subobj.netbiosname, "objectGUID") + assert subobj.host_guid is not None + + setup_file(setup_dir, "provision.zone", message, paths.dns, subobj) + + message("Please install the zone located in %s into your DNS server" % paths.dns) + + +def provision_ldapbase(setup_dir, subobj, message, paths): + """Write out a DNS zone file, from the info in the current database.""" + message("Setting up LDAP base entry: %s" % subobj.domaindn) + rdns = subobj.domaindn.split(",") + subobj.extensibleobject = "objectClass: extensibleObject" + + subobj.rdn_dc = rdns[0][len("DC="):] + + setup_file(setup_dir, "provision_basedn.ldif", + message, paths.ldap_basedn_ldif, + subobj) + + setup_file(setup_dir, "provision_configuration_basedn.ldif", + message, paths.ldap_config_basedn_ldif, + subobj) + + setup_file(setup_dir, "provision_schema_basedn.ldif", + message, paths.ldap_schema_basedn_ldif, + subobj) + + 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") + + +def provision_guess(lp): + """guess reasonably default options for provisioning.""" + subobj = ProvisionSettings(realm=lp.get("realm").upper(), + domain=lp.get("workgroup"), + hostname=hostname(), + hostip=hostip()) + + assert subobj.realm is not None + assert subobj.domain is not None + assert subobj.hostname is not None + + subobj.domainsid = sid.random() + subobj.invocationid = uuid.random() + subobj.policyguid = uuid.random() + subobj.krbtgtpass = misc.random_password(12) + subobj.machinepass = misc.random_password(12) + subobj.adminpass = misc.random_password(12) + subobj.dnspass = misc.random_password(12) + subobj.datestring = time.strftime("%Y%m%d%H") + subobj.root = findnss(pwd.getpwnam, "root")[4] + subobj.nobody = findnss(pwd.getpwnam, "nobody")[4] + subobj.nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] + subobj.wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[2] + subobj.backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[2] + subobj.users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", "usr")[2] + + subobj.dnsdomain = subobj.realm.lower() + subobj.dnsname = "%s.%s" % (subobj.hostname.lower(), subobj.dnsdomain) + subobj.domaindn = "DC=" + subobj.dnsdomain.replace(".", ",DC=") + subobj.domaindn_ldb = "users.ldb" + subobj.rootdn = subobj.domaindn + subobj.configdn = "CN=Configuration," + subobj.rootdn + subobj.configdn_ldb = "configuration.ldb" + subobj.schemadn = "CN=Schema," + subobj.configdn + subobj.schemadn_ldb = "schema.ldb" + + #Add modules to the list to activate them by default + #beware often order is important + # + # Some Known ordering constraints: + # - rootdse must be first, as it makes redirects from "" -> cn=rootdse + # - objectclass must be before password_hash, because password_hash checks + # that the objectclass is of type person (filled in by objectclass + # module when expanding the objectclass list) + # - partition must be last + # - each partition has its own module list then + subobj.modules_list = ["rootdse", + "paged_results", + "ranged_results", + "server_sort", + "extended_dn", + "asq", + "samldb", + "rdn_name", + "objectclass", + "kludge_acl", + "operational"] + subobj.tdb_modules_list = [ + "subtree_rename", + "subtree_delete", + "linked_attributes"] + subobj.modules_list2 = ["show_deleted", + "partition"] + + subobj.extensibleobject = "# no objectClass: extensibleObject for local ldb" + subobj.aci = "# no aci for local ldb" + return subobj + + +def searchone(ldb, basedn, expression, attribute): + """search for one attribute as a string.""" + res = ldb.search(basedn, SCOPE_SUBTREE, expression, [attribute]) + if len(res) != 1 or res[0][attribute] is None: + return None + return res[0][attribute] + + +def load_schema(setup_dir, subobj, samdb): + """Load schema.""" + src = os.path.join(setup_dir, "schema.ldif") + + schema_data = open(src, 'r').read() + + src = os.path.join(setup_dir, "schema_samba4.ldif") + + schema_data += open(src, 'r').read() + + schema_data = substitute_var(schema_data, subobj.subst_vars()) + + src = os.path.join(setup_dir, "provision_schema_basedn_modify.ldif") + + head_data = open(src, 'r').read() + + head_data = substitute_var(head_data, subobj.subst_vars()) + + samdb.attach_dsdb_schema_from_ldif(head_data, schema_data) + + +def enable_account(ldb, user_dn): + """enable the account.""" + res = ldb.search(user_dn, SCOPE_ONELEVEL, None, ["userAccountControl"]) + assert len(res) == 1 + userAccountControl = res[0].userAccountControl + userAccountControl = userAccountControl - 2 # remove disabled bit + mod = """ +dn: %s +changetype: modify +replace: userAccountControl +userAccountControl: %u +""" % (user_dn, userAccountControl) + ldb.modify(mod) + + +def newuser(sam, username, unixname, password, message, session_info, + credentials): + """add a new user record""" + # connect to the sam + ldb.transaction_start() + + # find the DNs for the domain and the domain users group + res = ldb.search("", SCOPE_BASE, "defaultNamingContext=*", + ["defaultNamingContext"]) + assert(len(res) == 1 and res[0].defaultNamingContext is not None) + domain_dn = res[0].defaultNamingContext + assert(domain_dn is not None) + dom_users = searchone(ldb, domain_dn, "name=Domain Users", "dn") + assert(dom_users is not None) + + user_dn = "CN=%s,CN=Users,%s" % (username, domain_dn) + + # + # the new user record. note the reliance on the samdb module to fill + # in a sid, guid etc + # + ldif = """ +dn: %s +sAMAccountName: %s +unixName: %s +sambaPassword: %s +objectClass: user +""" % (user_dn, username, unixname, password) + # add the user to the users group as well + modgroup = """ +dn: %s +changetype: modify +add: member +member: %s +""" % (dom_users, user_dn) + + + # now the real work + message("Adding user %s" % user_dn) + ldb.add(ldif) + + message("Modifying group %s" % dom_users) + ldb.modify(modgroup) + + # modify the userAccountControl to remove the disabled bit + enable_account(ldb, user_dn) + ldb.transaction_commit() + + +def valid_netbios_name(name): + """Check whether a name is valid as a NetBIOS name. """ + # FIXME: There are probably more constraints here. + # crh has a paragraph on this in his book (1.4.1.1) + if len(name) > 13: + return False + return True + + +def join_domain(domain, netbios_name, join_type, creds, message): + ctx = NetContext(creds) + joindom = object() + joindom.domain = domain + joindom.join_type = join_type + joindom.netbios_name = netbios_name + if not ctx.JoinDomain(joindom): + raise Exception("Domain Join failed: " + joindom.error_string) + + +def vampire(domain, session_info, credentials, message): + """Vampire a remote domain. + + Session info and credentials are required for for + access to our local database (might be remote ldap) + """ + ctx = NetContext(credentials) + vampire_ctx = object() + machine_creds = credentials_init() + machine_creds.set_domain(form.domain) + if not machine_creds.set_machine_account(): + raise Exception("Failed to access domain join information!") + vampire_ctx.machine_creds = machine_creds + vampire_ctx.session_info = session_info + if not ctx.SamSyncLdb(vampire_ctx): + raise Exception("Migration of remote domain to Samba failed: %s " % vampire_ctx.error_string) -- cgit From eba25f5d1897fbe61e8d7c623fcacb647629bf07 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 10 Dec 2007 10:29:45 +0100 Subject: r26375: Move provision-independent utility function to main samba python module. (This used to be commit 9d0ff47be069422de7ef2794357c6f3e9c540e67) --- source4/scripting/python/samba/provision.py | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 3d391863da..692e49b095 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -14,7 +14,7 @@ import uuid, sid, misc from socket import gethostname, gethostbyname import param import registry -from samba import Ldb, substitute_var +from samba import Ldb, substitute_var, valid_netbios_name from ldb import Dn, SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ LDB_ERR_NO_SUCH_OBJECT, timestring @@ -191,14 +191,17 @@ unixName: %s """ % (res[0].dn, unixname) ldb.modify(ldb.parse_ldif(mod).next()[1]) + def hostip(): """return first host IP.""" return gethostbyname(hostname()) + def hostname(): """return first part of hostname.""" return gethostname().split(".")[0] + def ldb_delete(ldb): """Delete a LDB file. @@ -805,15 +808,6 @@ member: %s ldb.transaction_commit() -def valid_netbios_name(name): - """Check whether a name is valid as a NetBIOS name. """ - # FIXME: There are probably more constraints here. - # crh has a paragraph on this in his book (1.4.1.1) - if len(name) > 13: - return False - return True - - def join_domain(domain, netbios_name, join_type, creds, message): ctx = NetContext(creds) joindom = object() -- cgit From eb2c71912baceb1a6884ce143ae91f1e3d2a69fb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 16 Dec 2007 14:50:18 +0100 Subject: r26471: Sync with js version. (This used to be commit c0eea26e8e8eb326112e1833d137751fb7e900d2) --- source4/scripting/python/samba/provision.py | 1 + 1 file changed, 1 insertion(+) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 692e49b095..df40c2fb7a 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -695,6 +695,7 @@ def provision_guess(lp): subobj.modules_list = ["rootdse", "paged_results", "ranged_results", + "anr", "server_sort", "extended_dn", "asq", -- cgit From be999912671de052af909bb88f13c956f12b30e1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 04:56:54 +0100 Subject: r26484: Don't rely on removed header. (This used to be commit 6ca2b350858c0747449671234d54584635512705) --- source4/scripting/python/samba/provision.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index df40c2fb7a..ce496a8bc1 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -10,7 +10,7 @@ import os import pwd import grp import time -import uuid, sid, misc +import uuid, misc from socket import gethostname, gethostbyname import param import registry @@ -61,8 +61,8 @@ class ProvisionSettings(object): "SCHEMADN_MOD": "schema_fsmo", "SCHEMADN_MOD2": ",objectguid", "CONFIGDN": self.configdn, - "TDB_MODULES_LIST": ","+",".join(self.tdb_modules_list) - "MODULES_LIST2": ",".join(self.modules_list2) + "TDB_MODULES_LIST": ","+",".join(self.tdb_modules_list), + "MODULES_LIST2": ",".join(self.modules_list2), "CONFIGDN_LDB": self.configdn_ldb, "DOMAINDN": self.domaindn, "DOMAINDN_LDB": self.domaindn_ldb, -- cgit From b0360e3a8617c59661d0b0fd805666e6cefcd811 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 08:20:20 +0100 Subject: r26496: Move some provision functions to a new SamDB class, support setting session_info on a ldb context from python. (This used to be commit 75cfb0d609687538048a7d72a499a5205af46a34) --- source4/scripting/python/samba/provision.py | 230 +++++++--------------------- 1 file changed, 58 insertions(+), 172 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index ce496a8bc1..63e50897fe 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -15,6 +15,7 @@ from socket import gethostname, gethostbyname import param import registry from samba import Ldb, substitute_var, valid_netbios_name +from samba.samdb import SamDB from ldb import Dn, SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ LDB_ERR_NO_SUCH_OBJECT, timestring @@ -164,32 +165,6 @@ def findnss(nssfn, *names): pass raise Exception("Unable to find user/group for %s" % arguments[1]) -def add_foreign(ldb, subobj, sid, desc): - """Add a foreign security principle.""" - add = """ -dn: CN=%s,CN=ForeignSecurityPrincipals,%s -objectClass: top -objectClass: foreignSecurityPrincipal -description: %s -""" % (sid, subobj.domaindn, desc) - # deliberately ignore errors from this, as the records may - # already exist - for msg in ldb.parse_ldif(add): - ldb.add(msg[1]) - -def setup_name_mapping(subobj, ldb, sid, unixname): - """Setup a mapping between a sam name and a unix name.""" - res = ldb.search(Dn(ldb, subobj.domaindn), SCOPE_SUBTREE, - "objectSid=%s" % sid, ["dn"]) - assert len(res) == 1, "Failed to find record for objectSid %s" % sid - - mod = """ -dn: %s -changetype: modify -replace: unixName -unixName: %s -""" % (res[0].dn, unixname) - ldb.modify(ldb.parse_ldif(mod).next()[1]) def hostip(): @@ -214,57 +189,6 @@ def ldb_delete(ldb): ldb.connect(ldb.filename) -def ldb_erase(ldb): - """Erase an ldb, removing all records.""" - # delete the specials - for attr in ["@INDEXLIST", "@ATTRIBUTES", "@SUBCLASSES", "@MODULES", - "@OPTIONS", "@PARTITION", "@KLUDGEACL"]: - try: - ldb.delete(Dn(ldb, attr)) - except LdbError, (LDB_ERR_NO_SUCH_OBJECT, _): - # Ignore missing dn errors - pass - - basedn = Dn(ldb, "") - # and the rest - for msg in ldb.search(basedn, SCOPE_SUBTREE, - "(&(|(objectclass=*)(dn=*))(!(dn=@BASEINFO)))", - ["dn"]): - ldb.delete(msg.dn) - - res = ldb.search(basedn, SCOPE_SUBTREE, "(&(|(objectclass=*)(dn=*))(!(dn=@BASEINFO)))", ["dn"]) - assert len(res) == 0 - - -def ldb_erase_partitions(subobj, message, ldb, ldapbackend): - """Erase an ldb, removing all records.""" - assert ldb is not None - res = ldb.search(Dn(ldb, ""), SCOPE_BASE, "(objectClass=*)", - ["namingContexts"]) - assert len(res) == 1 - if not "namingContexts" in res[0]: - return - for basedn in res[0]["namingContexts"]: - anything = "(|(objectclass=*)(dn=*))" - previous_remaining = 1 - current_remaining = 0 - - if ldapbackend and (basedn == subobj.domaindn): - # Only delete objects that were created by provision - anything = "(objectcategory=*)" - - k = 0 - while ++k < 10 and (previous_remaining != current_remaining): - # and the rest - res2 = ldb.search(Dn(ldb, basedn), SCOPE_SUBTREE, anything, ["dn"]) - previous_remaining = current_remaining - current_remaining = len(res2) - for msg in res2: - try: - ldb.delete(msg.dn) - except LdbError, (_, text): - message("Unable to delete %s: %s" % (msg.dn, text)) - def open_ldb(session_info, credentials, dbname): assert session_info is not None @@ -374,30 +298,30 @@ def setup_name_mappings(subobj, ldb): sid = list(res[0]["objectSid"])[0] # add some foreign sids if they are not present already - add_foreign(ldb, subobj, "S-1-5-7", "Anonymous") - add_foreign(ldb, subobj, "S-1-1-0", "World") - add_foreign(ldb, subobj, "S-1-5-2", "Network") - add_foreign(ldb, subobj, "S-1-5-18", "System") - add_foreign(ldb, subobj, "S-1-5-11", "Authenticated Users") + ldb.add_foreign(subobj.domaindn, "S-1-5-7", "Anonymous") + ldb.add_foreign(subobj.domaindn, "S-1-1-0", "World") + ldb.add_foreign(subobj.domaindn, "S-1-5-2", "Network") + ldb.add_foreign(subobj.domaindn, "S-1-5-18", "System") + ldb.add_foreign(subobj.domaindn, "S-1-5-11", "Authenticated Users") # some well known sids - setup_name_mapping(subobj, ldb, "S-1-5-7", subobj.nobody) - setup_name_mapping(subobj, ldb, "S-1-1-0", subobj.nogroup) - setup_name_mapping(subobj, ldb, "S-1-5-2", subobj.nogroup) - setup_name_mapping(subobj, ldb, "S-1-5-18", subobj.root) - setup_name_mapping(subobj, ldb, "S-1-5-11", subobj.users) - setup_name_mapping(subobj, ldb, "S-1-5-32-544", subobj.wheel) - setup_name_mapping(subobj, ldb, "S-1-5-32-545", subobj.users) - setup_name_mapping(subobj, ldb, "S-1-5-32-546", subobj.nogroup) - setup_name_mapping(subobj, ldb, "S-1-5-32-551", subobj.backup) + ldb.setup_name_mapping(subobj.domaindn, "S-1-5-7", subobj.nobody) + ldb.setup_name_mapping(subobj.domaindn, "S-1-1-0", subobj.nogroup) + ldb.setup_name_mapping(subobj.domaindn, "S-1-5-2", subobj.nogroup) + ldb.setup_name_mapping(subobj.domaindn, "S-1-5-18", subobj.root) + ldb.setup_name_mapping(subobj.domaindn, "S-1-5-11", subobj.users) + ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-544", subobj.wheel) + ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-545", subobj.users) + ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-546", subobj.nogroup) + ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-551", subobj.backup) # and some well known domain rids - setup_name_mapping(subobj, ldb, sid + "-500", subobj.root) - setup_name_mapping(subobj, ldb, sid + "-518", subobj.wheel) - setup_name_mapping(subobj, ldb, sid + "-519", subobj.wheel) - setup_name_mapping(subobj, ldb, sid + "-512", subobj.wheel) - setup_name_mapping(subobj, ldb, sid + "-513", subobj.users) - setup_name_mapping(subobj, ldb, sid + "-520", subobj.wheel) + ldb.setup_name_mapping(subobj.domaindn, sid + "-500", subobj.root) + ldb.setup_name_mapping(subobj.domaindn, sid + "-518", subobj.wheel) + ldb.setup_name_mapping(subobj.domaindn, sid + "-519", subobj.wheel) + ldb.setup_name_mapping(subobj.domaindn, sid + "-512", subobj.wheel) + ldb.setup_name_mapping(subobj.domaindn, sid + "-513", subobj.users) + ldb.setup_name_mapping(subobj.domaindn, sid + "-520", subobj.wheel) def provision_become_dc(setup_dir, subobj, message, paths, session_info, @@ -414,7 +338,8 @@ def provision_become_dc(setup_dir, subobj, message, paths, session_info, setup_ldb(setup_dir, "provision_partitions.ldif", session_info, credentials, subobj, paths.samdb) - samdb = open_ldb(session_info, credentials, paths.samdb) + samdb = SamDB(paths.samdb, session_info=session_info, + credentials=credentials) ldb.transaction_start() try: message("Setting up %s attributes" % paths.samdb) @@ -424,7 +349,7 @@ def provision_become_dc(setup_dir, subobj, message, paths, session_info, setup_add_ldif(setup_dir, "provision_rootdse_add.ldif", subobj, samdb) message("Erasing data from partitions") - ldb_erase_partitions(subobj, message, samdb, undefined) + ldb_erase_partitions(subobj, message, samdb, None) message("Setting up %s indexes" % paths.samdb) setup_add_ldif(setup_dir, "provision_index.ldif", subobj, samdb) @@ -603,7 +528,7 @@ def provision_dns(setup_dir, subobj, message, paths, session_info, credentials): """Write out a DNS zone file, from the info in the current database.""" message("Setting up DNS zone: %s" % subobj.dnsdomain) # connect to the sam - ldb = Ldb(paths.samdb, session_info=session_info, credentials=credentials) + ldb = SamDB(paths.samdb, session_info=session_info, credentials=credentials) # These values may have changed, due to an incoming SamSync, # or may not have been specified, so fetch them from the database @@ -614,7 +539,7 @@ def provision_dns(setup_dir, subobj, message, paths, session_info, credentials): assert(res[0]["objectGUID"] is not None) subobj.domainguid = res[0]["objectGUID"] - subobj.host_guid = searchone(ldb, subobj.domaindn, + subobj.host_guid = ldb.searchone(subobj.domaindn, "(&(objectClass=computer)(cn=%s))" % subobj.netbiosname, "objectGUID") assert subobj.host_guid is not None @@ -716,13 +641,6 @@ def provision_guess(lp): return subobj -def searchone(ldb, basedn, expression, attribute): - """search for one attribute as a string.""" - res = ldb.search(basedn, SCOPE_SUBTREE, expression, [attribute]) - if len(res) != 1 or res[0][attribute] is None: - return None - return res[0][attribute] - def load_schema(setup_dir, subobj, samdb): """Load schema.""" @@ -745,70 +663,6 @@ def load_schema(setup_dir, subobj, samdb): samdb.attach_dsdb_schema_from_ldif(head_data, schema_data) -def enable_account(ldb, user_dn): - """enable the account.""" - res = ldb.search(user_dn, SCOPE_ONELEVEL, None, ["userAccountControl"]) - assert len(res) == 1 - userAccountControl = res[0].userAccountControl - userAccountControl = userAccountControl - 2 # remove disabled bit - mod = """ -dn: %s -changetype: modify -replace: userAccountControl -userAccountControl: %u -""" % (user_dn, userAccountControl) - ldb.modify(mod) - - -def newuser(sam, username, unixname, password, message, session_info, - credentials): - """add a new user record""" - # connect to the sam - ldb.transaction_start() - - # find the DNs for the domain and the domain users group - res = ldb.search("", SCOPE_BASE, "defaultNamingContext=*", - ["defaultNamingContext"]) - assert(len(res) == 1 and res[0].defaultNamingContext is not None) - domain_dn = res[0].defaultNamingContext - assert(domain_dn is not None) - dom_users = searchone(ldb, domain_dn, "name=Domain Users", "dn") - assert(dom_users is not None) - - user_dn = "CN=%s,CN=Users,%s" % (username, domain_dn) - - # - # the new user record. note the reliance on the samdb module to fill - # in a sid, guid etc - # - ldif = """ -dn: %s -sAMAccountName: %s -unixName: %s -sambaPassword: %s -objectClass: user -""" % (user_dn, username, unixname, password) - # add the user to the users group as well - modgroup = """ -dn: %s -changetype: modify -add: member -member: %s -""" % (dom_users, user_dn) - - - # now the real work - message("Adding user %s" % user_dn) - ldb.add(ldif) - - message("Modifying group %s" % dom_users) - ldb.modify(modgroup) - - # modify the userAccountControl to remove the disabled bit - enable_account(ldb, user_dn) - ldb.transaction_commit() - - def join_domain(domain, netbios_name, join_type, creds, message): ctx = NetContext(creds) joindom = object() @@ -835,3 +689,35 @@ def vampire(domain, session_info, credentials, message): vampire_ctx.session_info = session_info if not ctx.SamSyncLdb(vampire_ctx): raise Exception("Migration of remote domain to Samba failed: %s " % vampire_ctx.error_string) + + +def ldb_erase_partitions(subobj, message, ldb, ldapbackend): + """Erase an ldb, removing all records.""" + assert ldb is not None + res = ldb.search(Dn(ldb, ""), SCOPE_BASE, "(objectClass=*)", + ["namingContexts"]) + assert len(res) == 1 + if not "namingContexts" in res[0]: + return + for basedn in res[0]["namingContexts"]: + anything = "(|(objectclass=*)(dn=*))" + previous_remaining = 1 + current_remaining = 0 + + if ldapbackend and (basedn == subobj.domaindn): + # Only delete objects that were created by provision + anything = "(objectcategory=*)" + + k = 0 + while ++k < 10 and (previous_remaining != current_remaining): + # and the rest + res2 = ldb.search(Dn(ldb, basedn), SCOPE_SUBTREE, anything, ["dn"]) + previous_remaining = current_remaining + current_remaining = len(res2) + for msg in res2: + try: + ldb.delete(msg.dn) + except LdbError, (_, text): + message("Unable to delete %s: %s" % (msg.dn, text)) + + -- cgit From 09915ce8b7edcf23335d570d70f79797afe83a71 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 08:36:39 +0100 Subject: r26499: Allow testing python provision by setting the PROVISION_PYTHON environment variable. (This used to be commit 379d0bbb2f9e0cd9b1855fd77bbb89827e0315ad) --- source4/scripting/python/samba/provision.py | 10 ---------- 1 file changed, 10 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 63e50897fe..60dcf06c83 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -189,7 +189,6 @@ def ldb_delete(ldb): ldb.connect(ldb.filename) - def open_ldb(session_info, credentials, dbname): assert session_info is not None try: @@ -641,25 +640,16 @@ def provision_guess(lp): return subobj - def load_schema(setup_dir, subobj, samdb): """Load schema.""" src = os.path.join(setup_dir, "schema.ldif") - schema_data = open(src, 'r').read() - src = os.path.join(setup_dir, "schema_samba4.ldif") - schema_data += open(src, 'r').read() - schema_data = substitute_var(schema_data, subobj.subst_vars()) - src = os.path.join(setup_dir, "provision_schema_basedn_modify.ldif") - head_data = open(src, 'r').read() - head_data = substitute_var(head_data, subobj.subst_vars()) - samdb.attach_dsdb_schema_from_ldif(head_data, schema_data) -- cgit From 32f439bfa458f7936b507cb5a1e3c74bcb8c68bf Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 11:12:36 +0100 Subject: r26503: Change order of arguments in param interface so it's easier to make the section name optional. Fix several smaller bits and pieces in the Python code. (This used to be commit 1b89311e5fa4fcde060df50e580dc221205cc8ca) --- source4/scripting/python/samba/provision.py | 30 ++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 60dcf06c83..5332a9f9ff 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -16,6 +16,7 @@ import param import registry from samba import Ldb, substitute_var, valid_netbios_name from samba.samdb import SamDB +import security from ldb import Dn, SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ LDB_ERR_NO_SUCH_OBJECT, timestring @@ -69,7 +70,7 @@ class ProvisionSettings(object): "DOMAINDN_LDB": self.domaindn_ldb, "DOMAINDN_MOD": "pdc_fsmo,password_hash", "DOMAINDN_MOD2": ",objectguid", - "DOMAINSID": self.domainsid, + "DOMAINSID": str(self.domainsid), "MODULES_LIST": ",".join(self.modules_list), "CONFIGDN_MOD": "naming_fsmo", "CONFIGDN_MOD2": ",objectguid", @@ -115,13 +116,13 @@ class ProvisionSettings(object): if not valid_netbios_name(self.netbiosname): raise InvalidNetbiosName(self.netbiosname) - if lp.get("workgroup").upper() != self.domain.upper(): + if lp.get_string("workgroup").upper() != self.domain.upper(): raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'\n", - lp.get("workgroup"), self.domain) + lp.get_string("workgroup"), self.domain) - if lp.get("realm").upper() != self.realm.upper(): + if lp.get_string("realm").upper() != self.realm.upper(): raise Error("realm '%s' in smb.conf must match chosen realm '%s'\n" % - (lp.get("realm"), self.realm)) + (lp.get_string("realm"), self.realm)) class ProvisionPaths: @@ -147,9 +148,9 @@ class ProvisionPaths: def install_ok(lp, session_info, credentials): """Check whether the current install seems ok.""" - if lp.get("realm") == "": + if lp.get_string("realm") == "": return False - ldb = Ldb(lp.get("sam database"), session_info=session_info, + ldb = Ldb(lp.get_string("sam database"), session_info=session_info, credentials=credentials) if len(ldb.search("(cn=Administrator)")) != 1: return False @@ -166,7 +167,6 @@ def findnss(nssfn, *names): raise Exception("Unable to find user/group for %s" % arguments[1]) - def hostip(): """return first host IP.""" return gethostbyname(hostname()) @@ -230,7 +230,7 @@ def setup_ldb(setup_dir, ldif, session_info, credentials, subobj, dbname, ldb.transaction_start() try: if erase: - ldb_erase(ldb); + ldb.erase(); setup_add_ldif(setup_dir, ldif, subobj, ldb) except: ldb.transaction_cancel() @@ -271,10 +271,10 @@ def provision_default_paths(lp, subobj): :param subobj: Object """ paths = ProvisionPaths() - private_dir = lp.get("private dir") + private_dir = lp.get_string("private dir") paths.shareconf = os.path.join(private_dir, "share.ldb") - paths.samdb = lp.get("sam database") or os.path.join(private_dir, "samdb.ldb") - paths.secrets = lp.get("secrets database") or os.path.join(private_dir, "secrets.ldb") + paths.samdb = lp.get_string("sam database") or os.path.join(private_dir, "samdb.ldb") + paths.secrets = lp.get_string("secrets database") or os.path.join(private_dir, "secrets.ldb") paths.templates = os.path.join(private_dir, "templates.ldb") paths.keytab = os.path.join(private_dir, "secrets.keytab") paths.dns = os.path.join(private_dir, subobj.dnsdomain + ".zone") @@ -572,8 +572,8 @@ def provision_ldapbase(setup_dir, subobj, message, paths): def provision_guess(lp): """guess reasonably default options for provisioning.""" - subobj = ProvisionSettings(realm=lp.get("realm").upper(), - domain=lp.get("workgroup"), + subobj = ProvisionSettings(realm=lp.get_string("realm").upper(), + domain=lp.get_string("workgroup"), hostname=hostname(), hostip=hostip()) @@ -581,7 +581,7 @@ def provision_guess(lp): assert subobj.domain is not None assert subobj.hostname is not None - subobj.domainsid = sid.random() + subobj.domainsid = security.random_sid() subobj.invocationid = uuid.random() subobj.policyguid = uuid.random() subobj.krbtgtpass = misc.random_password(12) -- cgit From f89c7a6e5eb082794d64b487e69fc442d138ca28 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 12:07:51 +0100 Subject: r26505: Add python bindings for some samdb-related functions, improve provisioning in python. (This used to be commit d2402251666738c0372bbbaeaa1d26c06e254033) --- source4/scripting/python/samba/provision.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 5332a9f9ff..34191b7269 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -433,10 +433,8 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, message("Pre-loading the Samba 4 and AD schema") - samdb = open_ldb(session_info, credentials, paths.samdb) - + samdb = SamDB(paths.samdb, session_info, credentials) samdb.set_domain_sid(subobj.domainsid) - load_schema(setup_dir, subobj, samdb) samdb.transaction_start() @@ -650,7 +648,7 @@ def load_schema(setup_dir, subobj, samdb): src = os.path.join(setup_dir, "provision_schema_basedn_modify.ldif") head_data = open(src, 'r').read() head_data = substitute_var(head_data, subobj.subst_vars()) - samdb.attach_dsdb_schema_from_ldif(head_data, schema_data) + samdb.attach_schema_from_ldif(head_data, schema_data) def join_domain(domain, netbios_name, join_type, creds, message): -- cgit From ca74c6e6c426e6b69ba31676e2b06dda29b5409e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 20:03:06 +0100 Subject: r26513: Update substitution dictionary for ldifs. (This used to be commit 60fb2de2119cb2f42f858868e39c3b0d303ac20f) --- source4/scripting/python/samba/provision.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 34191b7269..7d7b85c13e 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -14,6 +14,7 @@ import uuid, misc from socket import gethostname, gethostbyname import param import registry +import samba from samba import Ldb, substitute_var, valid_netbios_name from samba.samdb import SamDB import security @@ -56,6 +57,7 @@ class ProvisionSettings(object): self.schemedn_ldb = None self.s4_ldapi_path = None self.policyguid = None + self.extensibleobject = None def subst_vars(self): return {"SCHEMADN": self.schemadn, @@ -77,6 +79,7 @@ class ProvisionSettings(object): "NETBIOSNAME": self.netbiosname, "DNSNAME": self.dnsname, "ROOTDN": self.rootdn, + "DOMAIN": self.domain, "DNSDOMAIN": self.dnsdomain, "REALM": self.realm, "DEFAULTSITE": self.defaultsite, @@ -89,6 +92,9 @@ class ProvisionSettings(object): "POLICYGUID": self.policyguid, "RDN_DC": self.rdn_dc, "DOMAINGUID_MOD": self.domainguid_mod, + "VERSION": samba.version(), + "ACI": "# no aci for local ldb", + "EXTENSIBLEOBJECT": self.extensibleobject, } def fix(self, paths): -- cgit From 57b8a8fd42f5d89f439fd9d0781bd8f561a84131 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 23:16:12 +0100 Subject: r26517: Add functions for setting and getting parameters on a LoadParm. Pass loadparm context along to Ldb contexts. Other minor Python improvements. (This used to be commit 7a15b486bae8fb774058b2d94cc12b7b01ee6ac0) --- source4/scripting/python/samba/provision.py | 66 +++++++++++++++-------------- 1 file changed, 35 insertions(+), 31 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 7d7b85c13e..d88b8501ba 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -122,13 +122,13 @@ class ProvisionSettings(object): if not valid_netbios_name(self.netbiosname): raise InvalidNetbiosName(self.netbiosname) - if lp.get_string("workgroup").upper() != self.domain.upper(): + if lp.get("workgroup").upper() != self.domain.upper(): raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'\n", - lp.get_string("workgroup"), self.domain) + lp.get("workgroup"), self.domain) - if lp.get_string("realm").upper() != self.realm.upper(): + if lp.get("realm").upper() != self.realm.upper(): raise Error("realm '%s' in smb.conf must match chosen realm '%s'\n" % - (lp.get_string("realm"), self.realm)) + (lp.get("realm"), self.realm)) class ProvisionPaths: @@ -154,10 +154,10 @@ class ProvisionPaths: def install_ok(lp, session_info, credentials): """Check whether the current install seems ok.""" - if lp.get_string("realm") == "": + if lp.get("realm") == "": return False - ldb = Ldb(lp.get_string("sam database"), session_info=session_info, - credentials=credentials) + ldb = Ldb(lp.get("sam database"), session_info=session_info, + credentials=credentials, lp=lp) if len(ldb.search("(cn=Administrator)")) != 1: return False return True @@ -195,14 +195,16 @@ def ldb_delete(ldb): ldb.connect(ldb.filename) -def open_ldb(session_info, credentials, dbname): +def open_ldb(session_info, credentials, lp, dbname): assert session_info is not None try: - return Ldb(dbname, session_info=session_info, credentials=credentials) + return Ldb(dbname, session_info=session_info, credentials=credentials, + lp=lp) except LdbError, e: print e os.unlink(dbname) - return Ldb(dbname, session_info=session_info, credentials=credentials) + return Ldb(dbname, session_info=session_info, credentials=credentials, + lp=lp) def setup_add_ldif(setup_dir, ldif, subobj, ldb): @@ -228,10 +230,10 @@ def setup_modify_ldif(setup_dir, ldif, subobj, ldb): ldb.modify(msg) -def setup_ldb(setup_dir, ldif, session_info, credentials, subobj, dbname, +def setup_ldb(setup_dir, ldif, session_info, credentials, subobj, lp, dbname, erase=True): assert dbname is not None - ldb = open_ldb(session_info, credentials, dbname) + ldb = open_ldb(session_info, credentials, lp, dbname) assert ldb is not None ldb.transaction_start() try: @@ -277,10 +279,10 @@ def provision_default_paths(lp, subobj): :param subobj: Object """ paths = ProvisionPaths() - private_dir = lp.get_string("private dir") + private_dir = lp.get("private dir") paths.shareconf = os.path.join(private_dir, "share.ldb") - paths.samdb = lp.get_string("sam database") or os.path.join(private_dir, "samdb.ldb") - paths.secrets = lp.get_string("secrets database") or os.path.join(private_dir, "secrets.ldb") + paths.samdb = lp.get("sam database") or os.path.join(private_dir, "samdb.ldb") + paths.secrets = lp.get("secrets database") or os.path.join(private_dir, "secrets.ldb") paths.templates = os.path.join(private_dir, "templates.ldb") paths.keytab = os.path.join(private_dir, "secrets.keytab") paths.dns = os.path.join(private_dir, subobj.dnsdomain + ".zone") @@ -329,22 +331,22 @@ def setup_name_mappings(subobj, ldb): ldb.setup_name_mapping(subobj.domaindn, sid + "-520", subobj.wheel) -def provision_become_dc(setup_dir, subobj, message, paths, session_info, +def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, credentials): assert session_info is not None subobj.fix(paths) message("Setting up templates into %s" % paths.templates) setup_ldb(setup_dir, "provision_templates.ldif", session_info, - credentials, subobj, paths.templates) + credentials, subobj, lp, paths.templates) # Also wipes the database message("Setting up %s partitions" % paths.samdb) setup_ldb(setup_dir, "provision_partitions.ldif", session_info, - credentials, subobj, paths.samdb) + credentials, subobj, lp, paths.samdb) samdb = SamDB(paths.samdb, session_info=session_info, - credentials=credentials) + credentials=credentials, lp=lp) ldb.transaction_start() try: message("Setting up %s attributes" % paths.samdb) @@ -366,9 +368,9 @@ def provision_become_dc(setup_dir, subobj, message, paths, session_info, message("Setting up %s" % paths.secrets) setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, - subobj, paths.secrets) + subobj, lp, paths.secrets) - setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, + setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, lp, paths.secrets, False) @@ -401,11 +403,11 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, # only install a new shares config db if there is none if not os.path.exists(paths.shareconf): message("Setting up share.ldb") - setup_ldb(setup_dir, "share.ldif", session_info, credentials, subobj, paths.shareconf) + setup_ldb(setup_dir, "share.ldif", session_info, credentials, subobj, lp, paths.shareconf) message("Setting up %s" % paths.secrets) - setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, subobj, paths.secrets) - setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, paths.secrets, False) + setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, subobj, lp, paths.secrets) + setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, lp, paths.secrets, False) message("Setting up registry") reg = registry.Registry() @@ -414,13 +416,13 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, #reg.apply_patchfile(os.path.join(setup_dir, "provision.reg")) message("Setting up templates into %s" % paths.templates) - setup_ldb(setup_dir, "provision_templates.ldif", session_info, credentials, subobj, paths.templates) + setup_ldb(setup_dir, "provision_templates.ldif", session_info, credentials, subobj, lp, paths.templates) message("Setting up sam.ldb partitions") setup_ldb(setup_dir, "provision_partitions.ldif", session_info, - credentials, subobj, paths.samdb) + credentials, subobj, lp, paths.samdb) - samdb = open_ldb(session_info, credentials, paths.samdb) + samdb = open_ldb(session_info, credentials, lp, paths.samdb) samdb.transaction_start() try: message("Setting up sam.ldb attributes") @@ -439,7 +441,8 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, message("Pre-loading the Samba 4 and AD schema") - samdb = SamDB(paths.samdb, session_info, credentials) + samdb = SamDB(paths.samdb, session_info=session_info, + credentials=credentials, lp=lp) samdb.set_domain_sid(subobj.domainsid) load_schema(setup_dir, subobj, samdb) @@ -531,7 +534,8 @@ def provision_dns(setup_dir, subobj, message, paths, session_info, credentials): """Write out a DNS zone file, from the info in the current database.""" message("Setting up DNS zone: %s" % subobj.dnsdomain) # connect to the sam - ldb = SamDB(paths.samdb, session_info=session_info, credentials=credentials) + ldb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, + lp=lp) # These values may have changed, due to an incoming SamSync, # or may not have been specified, so fetch them from the database @@ -576,8 +580,8 @@ def provision_ldapbase(setup_dir, subobj, message, paths): def provision_guess(lp): """guess reasonably default options for provisioning.""" - subobj = ProvisionSettings(realm=lp.get_string("realm").upper(), - domain=lp.get_string("workgroup"), + subobj = ProvisionSettings(realm=lp.get("realm").upper(), + domain=lp.get("workgroup"), hostname=hostname(), hostip=hostip()) -- cgit From 12a513b47b1a1f2adeb2cb2a10ac36d02dd44065 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Mon, 17 Dec 2007 23:16:16 +0100 Subject: r26518: Fix provision of registry using Python. (This used to be commit 12eb38e553993b2726a803af4ae9c05229d6ebe4) --- source4/scripting/python/samba/provision.py | 40 +++++++++++++++++++---------- 1 file changed, 26 insertions(+), 14 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d88b8501ba..d9863420b6 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -287,11 +287,15 @@ def provision_default_paths(lp, subobj): paths.keytab = os.path.join(private_dir, "secrets.keytab") paths.dns = os.path.join(private_dir, subobj.dnsdomain + ".zone") paths.winsdb = os.path.join(private_dir, "wins.ldb") - paths.ldap_basedn_ldif = os.path.join(private_dir, subobj.dnsdomain + ".ldif") - paths.ldap_config_basedn_ldif = os.path.join(private_dir, subobj.dnsdomain + "-config.ldif") - paths.ldap_schema_basedn_ldif = os.path.join(private_dir, subobj.dnsdomain + "-schema.ldif") + paths.ldap_basedn_ldif = os.path.join(private_dir, + subobj.dnsdomain + ".ldif") + paths.ldap_config_basedn_ldif = os.path.join(private_dir, + subobj.dnsdomain + "-config.ldif") + paths.ldap_schema_basedn_ldif = os.path.join(private_dir, + subobj.dnsdomain + "-schema.ldif") paths.s4_ldapi_path = os.path.join(private_dir, "ldapi") - paths.phpldapadminconfig = os.path.join(private_dir, "phpldapadmin-config.php") + paths.phpldapadminconfig = os.path.join(private_dir, + "phpldapadmin-config.php") paths.hklm = os.path.join(private_dir, "hklm.ldb") return paths @@ -370,8 +374,8 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, subobj, lp, paths.secrets) - setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, lp, - paths.secrets, False) + setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, + lp, paths.secrets, False) def provision(lp, setup_dir, subobj, message, blank, paths, session_info, @@ -397,26 +401,34 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, # only install a new smb.conf if there isn't one there already if not os.path.exists(paths.smbconf): message("Setting up smb.conf") - setup_file(setup_dir, "provision.smb.conf", message, paths.smbconf, subobj) + setup_file(setup_dir, "provision.smb.conf", message, paths.smbconf, + subobj) lp.reload() # only install a new shares config db if there is none if not os.path.exists(paths.shareconf): message("Setting up share.ldb") - setup_ldb(setup_dir, "share.ldif", session_info, credentials, subobj, lp, paths.shareconf) + setup_ldb(setup_dir, "share.ldif", session_info, credentials, subobj, + lp, paths.shareconf) message("Setting up %s" % paths.secrets) - setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, subobj, lp, paths.secrets) - setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, lp, paths.secrets, False) + setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, + subobj, lp, paths.secrets) + setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, + lp, paths.secrets, False) message("Setting up registry") reg = registry.Registry() - # FIXME: Still fails for some reason: - #reg.mount(paths.hklm, registry.HKEY_LOCAL_MACHINE, []) - #reg.apply_patchfile(os.path.join(setup_dir, "provision.reg")) + hive = registry.Hive(paths.hklm, session_info=session_info, + credentials=credentials, lp_ctx=lp) + reg.mount_hive(hive, registry.HKEY_LOCAL_MACHINE, []) + provision_reg = os.path.join(setup_dir, "provision.reg") + assert os.path.exists(provision_reg) + reg.apply_patchfile(provision_reg) message("Setting up templates into %s" % paths.templates) - setup_ldb(setup_dir, "provision_templates.ldif", session_info, credentials, subobj, lp, paths.templates) + setup_ldb(setup_dir, "provision_templates.ldif", session_info, + credentials, subobj, lp, paths.templates) message("Setting up sam.ldb partitions") setup_ldb(setup_dir, "provision_partitions.ldif", session_info, -- cgit From 63f53094efa29b76eb4136cddf19d9c5d325fc5f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 18 Dec 2007 02:21:14 +0100 Subject: r26520: More Python updates. (This used to be commit a8b1fe15ac853082961132ede061fe1556ae29f7) --- source4/scripting/python/samba/provision.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d9863420b6..0a3c183fcc 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -306,7 +306,7 @@ def setup_name_mappings(subobj, ldb): ["objectSid"]) assert len(res) == 1 assert "objectSid" in res[0] - sid = list(res[0]["objectSid"])[0] + sid = str(list(res[0]["objectSid"])[0]) # add some foreign sids if they are not present already ldb.add_foreign(subobj.domaindn, "S-1-5-7", "Anonymous") @@ -419,12 +419,12 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, message("Setting up registry") reg = registry.Registry() - hive = registry.Hive(paths.hklm, session_info=session_info, - credentials=credentials, lp_ctx=lp) - reg.mount_hive(hive, registry.HKEY_LOCAL_MACHINE, []) + #hive = registry.Hive(paths.hklm, session_info=session_info, + # credentials=credentials, lp_ctx=lp) + #reg.mount_hive(hive, "HKEY_LOCAL_MACHINE") provision_reg = os.path.join(setup_dir, "provision.reg") assert os.path.exists(provision_reg) - reg.apply_patchfile(provision_reg) + #reg.apply_patchfile(provision_reg) message("Setting up templates into %s" % paths.templates) setup_ldb(setup_dir, "provision_templates.ldif", session_info, @@ -434,7 +434,8 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, setup_ldb(setup_dir, "provision_partitions.ldif", session_info, credentials, subobj, lp, paths.samdb) - samdb = open_ldb(session_info, credentials, lp, paths.samdb) + samdb = SamDB(paths.samdb, session_info=session_info, + credentials=credentials, lp=lp) samdb.transaction_start() try: message("Setting up sam.ldb attributes") -- cgit From 54a48d40a10c813954e4b777377607bb8366a57e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 18 Dec 2007 02:21:28 +0100 Subject: r26522: Fix warnings on SamDB connect from Python, simplify the setup code for the various LDBs. (This used to be commit 20c686f501b652ec0578a075a124b72ecb5f41b6) --- source4/scripting/python/samba/provision.py | 61 ++++++++++++++++------------- 1 file changed, 33 insertions(+), 28 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 0a3c183fcc..2c6e50219a 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -230,15 +230,10 @@ def setup_modify_ldif(setup_dir, ldif, subobj, ldb): ldb.modify(msg) -def setup_ldb(setup_dir, ldif, session_info, credentials, subobj, lp, dbname, - erase=True): - assert dbname is not None - ldb = open_ldb(session_info, credentials, lp, dbname) +def setup_ldb(ldb, setup_dir, ldif, subobj): assert ldb is not None ldb.transaction_start() try: - if erase: - ldb.erase(); setup_add_ldif(setup_dir, ldif, subobj, ldb) except: ldb.transaction_cancel() @@ -281,8 +276,8 @@ def provision_default_paths(lp, subobj): paths = ProvisionPaths() private_dir = lp.get("private dir") paths.shareconf = os.path.join(private_dir, "share.ldb") - paths.samdb = lp.get("sam database") or os.path.join(private_dir, "samdb.ldb") - paths.secrets = lp.get("secrets database") or os.path.join(private_dir, "secrets.ldb") + paths.samdb = os.path.join(private_dir, lp.get("sam database") or "samdb.ldb") + paths.secrets = os.path.join(private_dir, lp.get("secrets database") or "secrets.ldb") paths.templates = os.path.join(private_dir, "templates.ldb") paths.keytab = os.path.join(private_dir, "secrets.keytab") paths.dns = os.path.join(private_dir, subobj.dnsdomain + ".zone") @@ -341,13 +336,17 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, subobj.fix(paths) message("Setting up templates into %s" % paths.templates) - setup_ldb(setup_dir, "provision_templates.ldif", session_info, - credentials, subobj, lp, paths.templates) + templates_ldb = Ldb(paths.templates, session_info=session_info, + credentials=credentials, lp=lp) + templates_ldb.erase() + setup_ldb(templates_ldb, setup_dir, "provision_templates.ldif", subobj) # Also wipes the database message("Setting up %s partitions" % paths.samdb) - setup_ldb(setup_dir, "provision_partitions.ldif", session_info, - credentials, subobj, lp, paths.samdb) + samdb = SamDB(paths.samdb, credentials=credentials, + session_info=session_info, lp=lp) + samdb.erase() + setup_ldb(samdb, setup_dir, "provision_partitions.ldif", subobj) samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) @@ -371,11 +370,12 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, samdb.transaction_commit() message("Setting up %s" % paths.secrets) - setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, - subobj, lp, paths.secrets) - - setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, - lp, paths.secrets, False) + secrets_ldb = Ldb(paths.secrets, session_info=session_info, + credentials=credentials, lp=lp) + secrets_ldb.clear() + setup_ldb(secrets_ldb, setup_dir, "secrets_init.ldif", subobj) + setup_ldb(secrets_ldb, setup_dir, "secrets.ldif", subobj) + setup_ldb(secrets_ldb, setup_dir, "secrets_dc.ldif", subobj) def provision(lp, setup_dir, subobj, message, blank, paths, session_info, @@ -408,14 +408,16 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, # only install a new shares config db if there is none if not os.path.exists(paths.shareconf): message("Setting up share.ldb") - setup_ldb(setup_dir, "share.ldif", session_info, credentials, subobj, - lp, paths.shareconf) + share_ldb = Ldb(paths.shareconf, session_info=session_info, + credentials=credentials, lp=lp) + setup_ldb(share_ldb, setup_dir, "share.ldif", subobj) message("Setting up %s" % paths.secrets) - setup_ldb(setup_dir, "secrets_init.ldif", session_info, credentials, - subobj, lp, paths.secrets) - setup_ldb(setup_dir, "secrets.ldif", session_info, credentials, subobj, - lp, paths.secrets, False) + secrets_ldb = Ldb(paths.secrets, session_info=session_info, + credentials=credentials, lp=lp) + secrets_ldb.erase() + setup_ldb(secrets_ldb, setup_dir, "secrets_init.ldif", subobj) + setup_ldb(secrets_ldb, setup_dir, "secrets.ldif", subobj) message("Setting up registry") reg = registry.Registry() @@ -427,12 +429,16 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, #reg.apply_patchfile(provision_reg) message("Setting up templates into %s" % paths.templates) - setup_ldb(setup_dir, "provision_templates.ldif", session_info, - credentials, subobj, lp, paths.templates) + templates_ldb = Ldb(paths.templates, session_info=session_info, + credentials=credentials, lp=lp) + templates_ldb.erase() + setup_ldb(templates_ldb, setup_dir, "provision_templates.ldif", subobj) message("Setting up sam.ldb partitions") - setup_ldb(setup_dir, "provision_partitions.ldif", session_info, - credentials, subobj, lp, paths.samdb) + samdb = SamDB(paths.samdb, session_info=session_info, + credentials=credentials, lp=lp) + samdb.erase() + setup_ldb(samdb, setup_dir, "provision_partitions.ldif", subobj) samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) @@ -453,7 +459,6 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, samdb.transaction_commit() message("Pre-loading the Samba 4 and AD schema") - samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) samdb.set_domain_sid(subobj.domainsid) -- cgit From 1c29a63d443fde3fc0253f634822c12749f1afad Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 18 Dec 2007 17:21:13 +0100 Subject: r26523: Refactor provisioning code. (This used to be commit ac1083178f9e521dcd5d3d8b5199abcb00159adf) --- source4/scripting/python/samba/provision.py | 396 +++++++++++++++++----------- 1 file changed, 244 insertions(+), 152 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 2c6e50219a..a8aeb8c831 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -39,7 +39,6 @@ class ProvisionSettings(object): self.machinepass = None self.adminpass = None self.defaultsite = "Default-First-Site-Name" - self.datestring = None self.root = None self.nobody = None self.nogroup = None @@ -49,52 +48,19 @@ class ProvisionSettings(object): self.dnsdomain = None self.dnsname = None self.domaindn = None - self.domaindn_ldb = None self.rootdn = None self.configdn = None - self.configdn_ldb = None self.schemedn = None self.schemedn_ldb = None self.s4_ldapi_path = None self.policyguid = None - self.extensibleobject = None + self.serverrole = None def subst_vars(self): - return {"SCHEMADN": self.schemadn, - "SCHEMADN_LDB": self.schemadn_ldb, - "SCHEMADN_MOD": "schema_fsmo", - "SCHEMADN_MOD2": ",objectguid", - "CONFIGDN": self.configdn, - "TDB_MODULES_LIST": ","+",".join(self.tdb_modules_list), - "MODULES_LIST2": ",".join(self.modules_list2), - "CONFIGDN_LDB": self.configdn_ldb, - "DOMAINDN": self.domaindn, - "DOMAINDN_LDB": self.domaindn_ldb, - "DOMAINDN_MOD": "pdc_fsmo,password_hash", - "DOMAINDN_MOD2": ",objectguid", - "DOMAINSID": str(self.domainsid), - "MODULES_LIST": ",".join(self.modules_list), - "CONFIGDN_MOD": "naming_fsmo", - "CONFIGDN_MOD2": ",objectguid", - "NETBIOSNAME": self.netbiosname, - "DNSNAME": self.dnsname, - "ROOTDN": self.rootdn, - "DOMAIN": self.domain, - "DNSDOMAIN": self.dnsdomain, - "REALM": self.realm, - "DEFAULTSITE": self.defaultsite, - "MACHINEPASS_B64": b64encode(self.machinepass), - "ADMINPASS_B64": b64encode(self.adminpass), - "DNSPASS_B64": b64encode(self.dnspass), - "KRBTGTPASS_B64": b64encode(self.krbtgtpass), - "S4_LDAPI_URI": "ldapi://%s" % self.s4_ldapi_path.replace("/", "%2F"), - "LDAPTIME": timestring(int(time.time())), - "POLICYGUID": self.policyguid, - "RDN_DC": self.rdn_dc, - "DOMAINGUID_MOD": self.domainguid_mod, - "VERSION": samba.version(), - "ACI": "# no aci for local ldb", - "EXTENSIBLEOBJECT": self.extensibleobject, + return { + "SERVERROLE": self.serverrole, + "DOMAIN_CONF": self.domain, + "REALM_CONF": self.realm, } def fix(self, paths): @@ -114,6 +80,7 @@ class ProvisionSettings(object): self.secrets_keytab = paths.keytab self.s4_ldapi_path = paths.s4_ldapi_path + self.serverrole = "domain controller" def validate(self, lp): if not valid_netbios_name(self.domain): @@ -207,61 +174,64 @@ def open_ldb(session_info, credentials, lp, dbname): lp=lp) -def setup_add_ldif(setup_dir, ldif, subobj, ldb): +def setup_add_ldif(ldb, setup_dir, ldif, subst_vars=None): """Setup a ldb in the private dir.""" assert isinstance(ldif, str) assert isinstance(setup_dir, str) src = os.path.join(setup_dir, ldif) data = open(src, 'r').read() - data = substitute_var(data, subobj.subst_vars()) + if subst_vars is not None: + data = substitute_var(data, subst_vars) for msg in ldb.parse_ldif(data): ldb.add(msg[1]) -def setup_modify_ldif(setup_dir, ldif, subobj, ldb): +def setup_modify_ldif(ldb, setup_dir, ldif, substvars=None): src = os.path.join(setup_dir, ldif) data = open(src, 'r').read() - data = substitute_var(data, subobj.subst_vars()) + if substvars is not None: + data = substitute_var(data, substvars) for (changetype, msg) in ldb.parse_ldif(data): ldb.modify(msg) -def setup_ldb(ldb, setup_dir, ldif, subobj): +def setup_ldb(ldb, setup_dir, ldif, subst_vars=None): assert ldb is not None ldb.transaction_start() try: - setup_add_ldif(setup_dir, ldif, subobj, ldb) + setup_add_ldif(ldb, setup_dir, ldif, subst_vars) except: ldb.transaction_cancel() raise ldb.transaction_commit() -def setup_ldb_modify(setup_dir, ldif, subobj, ldb): +def setup_ldb_modify(setup_dir, ldif, substvars, ldb): """Modify a ldb in the private dir.""" src = os.path.join(setup_dir, ldif) data = open(src, 'r').read() - data = substitute_var(data, subobj.subst_vars()) + data = substitute_var(data, substvars) assert not "${" in data for (changetype, msg) in ldb.parse_ldif(data): ldb.modify(msg) -def setup_file(setup_dir, template, message, fname, subobj): +def setup_file(setup_dir, template, fname, substvars): """Setup a file in the private dir.""" f = fname src = os.path.join(setup_dir, template) - os.unlink(f) + if os.path.exists(f): + os.unlink(f) data = open(src, 'r').read() - data = substitute_var(data, subobj.subst_vars()) + data = substitute_var(data, substvars) assert not "${" in data open(f, 'w').write(data) @@ -297,11 +267,7 @@ def provision_default_paths(lp, subobj): def setup_name_mappings(subobj, ldb): """setup reasonable name mappings for sam names to unix names.""" - res = ldb.search(Dn(ldb, subobj.domaindn), SCOPE_BASE, "objectSid=*", - ["objectSid"]) - assert len(res) == 1 - assert "objectSid" in res[0] - sid = str(list(res[0]["objectSid"])[0]) + sid = str(subobj.domainsid) # add some foreign sids if they are not present already ldb.add_foreign(subobj.domaindn, "S-1-5-7", "Anonymous") @@ -336,33 +302,35 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, subobj.fix(paths) message("Setting up templates into %s" % paths.templates) - templates_ldb = Ldb(paths.templates, session_info=session_info, - credentials=credentials, lp=lp) - templates_ldb.erase() - setup_ldb(templates_ldb, setup_dir, "provision_templates.ldif", subobj) + setup_templatesdb(paths.templates, setup_dir, session_info, + credentials, lp) # Also wipes the database - message("Setting up %s partitions" % paths.samdb) + message("Setting up samdb") + os.path.unlink(paths.samdb) samdb = SamDB(paths.samdb, credentials=credentials, session_info=session_info, lp=lp) samdb.erase() - setup_ldb(samdb, setup_dir, "provision_partitions.ldif", subobj) - samdb = SamDB(paths.samdb, session_info=session_info, - credentials=credentials, lp=lp) + message("Setting up %s partitions" % paths.samdb) + setup_samdb_partitions(samdb, setup_dir, subobj) + + samdb = SamDB(paths.samdb, credentials=credentials, + session_info=session_info, lp=lp) + ldb.transaction_start() try: message("Setting up %s attributes" % paths.samdb) - setup_add_ldif(setup_dir, "provision_init.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_init.ldif") message("Setting up %s rootDSE" % paths.samdb) - setup_add_ldif(setup_dir, "provision_rootdse_add.ldif", subobj, samdb) + setup_samdb_rootdse(samdb, setup_dir, subobj) message("Erasing data from partitions") ldb_erase_partitions(subobj, message, samdb, None) message("Setting up %s indexes" % paths.samdb) - setup_add_ldif(setup_dir, "provision_index.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_index.ldif") except: samdb.transaction_cancel() raise @@ -370,12 +338,70 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, samdb.transaction_commit() message("Setting up %s" % paths.secrets) - secrets_ldb = Ldb(paths.secrets, session_info=session_info, - credentials=credentials, lp=lp) - secrets_ldb.clear() - setup_ldb(secrets_ldb, setup_dir, "secrets_init.ldif", subobj) - setup_ldb(secrets_ldb, setup_dir, "secrets.ldif", subobj) - setup_ldb(secrets_ldb, setup_dir, "secrets_dc.ldif", subobj) + secrets_ldb = setup_secretsdb(paths.secrets, setup_dir, session_info, credentials, lp) + setup_ldb(secrets_ldb, setup_dir, "secrets_dc.ldif", + { "MACHINEPASS_B64": b64encode(self.machinepass) }) + + +def setup_secretsdb(path, setup_dir, session_info, credentials, lp): + secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, lp=lp) + secrets_ldb.erase() + setup_ldb(secrets_ldb, setup_dir, "secrets_init.ldif") + setup_ldb(secrets_ldb, setup_dir, "secrets.ldif") + return secrets_ldb + + +def setup_templatesdb(path, setup_dir, session_info, credentials, lp): + templates_ldb = Ldb(path, session_info=session_info, + credentials=credentials, lp=lp) + templates_ldb.erase() + setup_ldb(templates_ldb, setup_dir, "provision_templates.ldif", None) + + +def setup_registry(path, setup_dir, session_info, credentials, lp): + reg = registry.Registry() + hive = registry.Hive(path, session_info=session_info, + credentials=credentials, lp_ctx=lp) + reg.mount_hive(hive, "HKEY_LOCAL_MACHINE") + provision_reg = os.path.join(setup_dir, "provision.reg") + assert os.path.exists(provision_reg) + reg.apply_patchfile(provision_reg) + + +def setup_samdb_rootdse(samdb, setup_dir, subobj): + setup_add_ldif(samdb, setup_dir, "provision_rootdse_add.ldif", { + "SCHEMADN": subobj.schemadn, + "NETBIOSNAME": subobj.netbiosname, + "DNSDOMAIN": subobj.dnsdomain, + "DEFAULTSITE": subobj.defaultsite, + "REALM": subobj.realm, + "DNSNAME": subobj.dnsname, + "DOMAINDN": subobj.domaindn, + "ROOTDN": subobj.rootdn, + "CONFIGDN": subobj.configdn, + "VERSION": samba.version(), + }) + + +def setup_samdb_partitions(samdb, setup_dir, subobj): + setup_ldb(samdb, setup_dir, "provision_partitions.ldif", { + "SCHEMADN": subobj.schemadn, + "SCHEMADN_LDB": "schema.ldb", + "SCHEMADN_MOD2": ",objectguid", + "CONFIGDN": subobj.configdn, + "CONFIGDN_LDB": "configuration.ldb", + "DOMAINDN": subobj.domaindn, + "DOMAINDN_LDB": "users.ldb", + "SCHEMADN_MOD": "schema_fsmo", + "CONFIGDN_MOD": "naming_fsmo", + "CONFIGDN_MOD2": ",objectguid", + "DOMAINDN_MOD": "pdc_fsmo,password_hash", + "DOMAINDN_MOD2": ",objectguid", + "MODULES_LIST": ",".join(subobj.modules_list), + "TDB_MODULES_LIST": ","+",".join(subobj.tdb_modules_list), + "MODULES_LIST2": ",".join(subobj.modules_list2), + }) + def provision(lp, setup_dir, subobj, message, blank, paths, session_info, @@ -386,11 +412,6 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, """ subobj.fix(paths) - if subobj.domain_guid is not None: - subobj.domainguid_mod = "replace: objectGUID\nobjectGUID: %s\n-" % subobj.domain_guid - else: - subobj.domainguid_mod = "" - if subobj.host_guid is not None: subobj.hostguid_add = "objectGUID: %s" % subobj.host_guid else: @@ -401,8 +422,14 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, # only install a new smb.conf if there isn't one there already if not os.path.exists(paths.smbconf): message("Setting up smb.conf") - setup_file(setup_dir, "provision.smb.conf", message, paths.smbconf, - subobj) + if lp.get("server role") == "domain controller": + smbconfsuffix = "dc" + elif lp.get("server role") == "member": + smbconfsuffix = "member" + else: + assert "Invalid server role setting: %s" % lp.get("server role") + setup_file(setup_dir, "provision.smb.conf.%s" % smbconfsuffix, paths.smbconf, + None) lp.reload() # only install a new shares config db if there is none @@ -410,45 +437,37 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, message("Setting up share.ldb") share_ldb = Ldb(paths.shareconf, session_info=session_info, credentials=credentials, lp=lp) - setup_ldb(share_ldb, setup_dir, "share.ldif", subobj) + setup_ldb(share_ldb, setup_dir, "share.ldif", None) message("Setting up %s" % paths.secrets) - secrets_ldb = Ldb(paths.secrets, session_info=session_info, - credentials=credentials, lp=lp) - secrets_ldb.erase() - setup_ldb(secrets_ldb, setup_dir, "secrets_init.ldif", subobj) - setup_ldb(secrets_ldb, setup_dir, "secrets.ldif", subobj) + setup_secretsdb(paths.secrets, setup_dir, session_info=session_info, + credentials=credentials, lp=lp) message("Setting up registry") - reg = registry.Registry() - #hive = registry.Hive(paths.hklm, session_info=session_info, - # credentials=credentials, lp_ctx=lp) - #reg.mount_hive(hive, "HKEY_LOCAL_MACHINE") - provision_reg = os.path.join(setup_dir, "provision.reg") - assert os.path.exists(provision_reg) - #reg.apply_patchfile(provision_reg) + #setup_registry(paths.hklm, setup_dir, session_info, + # credentials=credentials, lp=lp) message("Setting up templates into %s" % paths.templates) - templates_ldb = Ldb(paths.templates, session_info=session_info, - credentials=credentials, lp=lp) - templates_ldb.erase() - setup_ldb(templates_ldb, setup_dir, "provision_templates.ldif", subobj) + setup_templatesdb(paths.templates, setup_dir, session_info=session_info, + credentials=credentials, lp=lp) - message("Setting up sam.ldb partitions") samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) samdb.erase() - setup_ldb(samdb, setup_dir, "provision_partitions.ldif", subobj) + + message("Setting up sam.ldb partitions") + setup_samdb_partitions(samdb, setup_dir, subobj) samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) + samdb.transaction_start() try: message("Setting up sam.ldb attributes") - setup_add_ldif(setup_dir, "provision_init.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_init.ldif") message("Setting up sam.ldb rootDSE") - setup_add_ldif(setup_dir, "provision_rootdse_add.ldif", subobj, samdb) + setup_samdb_rootdse(samdb, setup_dir, subobj) message("Erasing data from partitions") ldb_erase_partitions(subobj, message, samdb, ldapbackend) @@ -462,53 +481,113 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) samdb.set_domain_sid(subobj.domainsid) - load_schema(setup_dir, subobj, samdb) + load_schema(setup_dir, samdb, subobj) samdb.transaction_start() try: message("Adding DomainDN: %s (permitted to fail)" % subobj.domaindn) - setup_add_ldif(setup_dir, "provision_basedn.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_basedn.ldif", { + "DOMAINDN": subobj.domaindn, + "ACI": "# no aci for local ldb", + "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", + "RDN_DC": subobj.rdn_dc, + }) + message("Modifying DomainDN: " + subobj.domaindn + "") - setup_ldb_modify(setup_dir, "provision_basedn_modify.ldif", subobj, samdb) + if subobj.domain_guid is not None: + domainguid_mod = "replace: objectGUID\nobjectGUID: %s\n-" % subobj.domain_guid + else: + domainguid_mod = "" + + setup_ldb_modify(setup_dir, "provision_basedn_modify.ldif", { + "RDN_DC": subobj.rdn_dc, + "LDAPTIME": timestring(int(time.time())), + "DOMAINSID": str(subobj.domainsid), + "SCHEMADN": subobj.schemadn, + "NETBIOSNAME": subobj.netbiosname, + "DEFAULTSITE": subobj.defaultsite, + "CONFIGDN": subobj.configdn, + "POLICYGUID": subobj.policyguid, + "DOMAINDN": subobj.domaindn, + "DOMAINGUID_MOD": domainguid_mod, + }, samdb) message("Adding configuration container (permitted to fail)") - setup_add_ldif(setup_dir, "provision_configuration_basedn.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_configuration_basedn.ldif", { + "CONFIGDN": subobj.configdn, + "ACI": "# no aci for local ldb", + "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", + }) message("Modifying configuration container") - setup_ldb_modify(setup_dir, "provision_configuration_basedn_modify.ldif", subobj, samdb) + setup_ldb_modify(setup_dir, "provision_configuration_basedn_modify.ldif", { + "CONFIGDN": subobj.configdn, + "SCHEMADN": subobj.schemadn, + }, samdb) message("Adding schema container (permitted to fail)") - setup_add_ldif(setup_dir, "provision_schema_basedn.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_schema_basedn.ldif", { + "SCHEMADN": subobj.schemadn, + "ACI": "# no aci for local ldb", + "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" + }) message("Modifying schema container") - setup_ldb_modify(setup_dir, "provision_schema_basedn_modify.ldif", subobj, samdb) + setup_ldb_modify(setup_dir, "provision_schema_basedn_modify.ldif", { + "SCHEMADN": subobj.schemadn, + "NETBIOSNAME": subobj.netbiosname, + "DEFAULTSITE": subobj.defaultsite, + "CONFIGDN": subobj.configdn, + }, samdb) + message("Setting up sam.ldb Samba4 schema") - setup_add_ldif(setup_dir, "schema_samba4.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "schema_samba4.ldif", { + "SCHEMADN": subobj.schemadn, + }) message("Setting up sam.ldb AD schema") - setup_add_ldif(setup_dir, "schema.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "schema.ldif", { + "SCHEMADN": subobj.schemadn, + }) message("Setting up sam.ldb configuration data") - setup_add_ldif(setup_dir, "provision_configuration.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_configuration.ldif", { + "CONFIGDN": subobj.configdn, + "NETBIOSNAME": subobj.netbiosname, + "DEFAULTSITE": subobj.defaultsite, + "DNSDOMAIN": subobj.dnsdomain, + "DOMAIN": subobj.domain, + "SCHEMADN": subobj.schemadn, + "DOMAINDN": subobj.domaindn, + }) message("Setting up display specifiers") - setup_add_ldif(setup_dir, "display_specifiers.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "display_specifiers.ldif", {"CONFIGDN": subobj.configdn}) message("Adding users container (permitted to fail)") - setup_add_ldif(setup_dir, "provision_users_add.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_users_add.ldif", { + "DOMAINDN": subobj.domaindn}) message("Modifying users container") - setup_ldb_modify(setup_dir, "provision_users_modify.ldif", subobj, samdb) + setup_ldb_modify(setup_dir, "provision_users_modify.ldif", { + "DOMAINDN": subobj.domaindn}, samdb) message("Adding computers container (permitted to fail)") - setup_add_ldif(setup_dir, "provision_computers_add.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_computers_add.ldif", { + "DOMAINDN": subobj.domaindn}) message("Modifying computers container") - setup_ldb_modify(setup_dir, "provision_computers_modify.ldif", subobj, samdb) + setup_ldb_modify(setup_dir, "provision_computers_modify.ldif", { + "DOMAINDN": subobj.domaindn}, samdb) message("Setting up sam.ldb data") - setup_add_ldif(setup_dir, "provision.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision.ldif", { + "DOMAINDN": subobj.domaindn, + "NETBIOSNAME": subobj.netbiosname, + "DEFAULTSITE": subobj.defaultsite, + "CONFIGDN": subobj.configdn, + }) if blank: message("Setting up sam.ldb index") - setup_add_ldif(setup_dir, "provision_index.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_index.ldif") message("Setting up sam.ldb rootDSE marking as syncronized") - setup_modify_ldif(setup_dir, "provision_rootdse_modify.ldif", subobj, samdb) + setup_modify_ldif(samdb, setup_dir, "provision_rootdse_modify.ldif") samdb.transaction_commit() return @@ -527,15 +606,21 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, # samdb = open_ldb(info, paths.samdb, False) # message("Setting up sam.ldb users and groups") - setup_add_ldif(setup_dir, "provision_users.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_users.ldif", { + "DOMAINDN": subobj.domaindn, + "DOMAINSID": str(subobj.domainsid), + "CONFIGDN": subobj.configdn, + "ADMINPASS_B64": b64encode(subobj.adminpass), + "KRBTGTPASS_B64": b64encode(subobj.krbtgtpass), + }) setup_name_mappings(subobj, samdb) message("Setting up sam.ldb index") - setup_add_ldif(setup_dir, "provision_index.ldif", subobj, samdb) + setup_add_ldif(samdb, setup_dir, "provision_index.ldif") message("Setting up sam.ldb rootDSE marking as syncronized") - setup_modify_ldif(setup_dir, "provision_rootdse_modify.ldif", subobj, samdb) + setup_modify_ldif(samdb, setup_dir, "provision_rootdse_modify.ldif") except: samdb.transaction_cancel() raise @@ -543,12 +628,17 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, samdb.transaction_commit() message("Setting up phpLDAPadmin configuration") - setup_file(setup_dir, "phpldapadmin-config.php", message, - paths.phpldapadminconfig, subobj) + create_phplpapdadmin_config(paths.phpldapadminconfig, setup_dir, subobj.s4_ldapi_path) + message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) -def provision_dns(setup_dir, subobj, message, paths, session_info, credentials): +def create_phplpapdadmin_config(path, setup_dir, s4_ldapi_path): + setup_file(setup_dir, "phpldapadmin-config.php", + path, {"S4_LDAPI_URI": "ldapi://%s" % s4_ldapi_path.replace("/", "%2F")}) + + +def provision_dns(setup_dir, subobj, message, paths, session_info, credentials, lp): """Write out a DNS zone file, from the info in the current database.""" message("Setting up DNS zone: %s" % subobj.dnsdomain) # connect to the sam @@ -557,18 +647,22 @@ def provision_dns(setup_dir, subobj, message, paths, session_info, credentials): # These values may have changed, due to an incoming SamSync, # or may not have been specified, so fetch them from the database - - res = ldb.search(Dn(ldb, subobj.domaindn), SCOPE_BASE, "objectGUID=*", - ["objectGUID"]) - assert(len(res) == 1) - assert(res[0]["objectGUID"] is not None) - subobj.domainguid = res[0]["objectGUID"] - - subobj.host_guid = ldb.searchone(subobj.domaindn, - "(&(objectClass=computer)(cn=%s))" % subobj.netbiosname, "objectGUID") - assert subobj.host_guid is not None - - setup_file(setup_dir, "provision.zone", message, paths.dns, subobj) + domainguid = str(ldb.searchone(Dn(ldb, subobj.domaindn), "objectGUID")) + + hostguid = str(ldb.searchone(Dn(ldb, subobj.domaindn), "objectGUID" , + expression="(&(objectClass=computer)(cn=%s))" % subobj.netbiosname)) + + setup_file(setup_dir, "provision.zone", paths.dns, { + "DNSPASS_B64": b64encode(subobj.dnspass), + "HOSTNAME": hostname(), + "DNSDOMAIN": subobj.dnsdomain, + "REALM": subobj.realm, + "HOSTIP": hostip(), + "DOMAINGUID": domainguid, + "DATESTRING": time.strftime("%Y%m%d%H"), + "DEFAULTSITE": subobj.defaultsite, + "HOSTGUID": hostguid, + }) message("Please install the zone located in %s into your DNS server" % paths.dns) @@ -577,21 +671,21 @@ def provision_ldapbase(setup_dir, subobj, message, paths): """Write out a DNS zone file, from the info in the current database.""" message("Setting up LDAP base entry: %s" % subobj.domaindn) rdns = subobj.domaindn.split(",") - subobj.extensibleobject = "objectClass: extensibleObject" subobj.rdn_dc = rdns[0][len("DC="):] setup_file(setup_dir, "provision_basedn.ldif", - message, paths.ldap_basedn_ldif, - subobj) + paths.ldap_basedn_ldif, + None) setup_file(setup_dir, "provision_configuration_basedn.ldif", - message, paths.ldap_config_basedn_ldif, - subobj) + paths.ldap_config_basedn_ldif, None) setup_file(setup_dir, "provision_schema_basedn.ldif", - message, paths.ldap_schema_basedn_ldif, - subobj) + paths.ldap_schema_basedn_ldif, { + "SCHEMADN": subobj.schemadn, + "ACI": "# no aci for local ldb", + "EXTENSIBLEOBJECT": "objectClass: extensibleObject"}) 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") @@ -614,7 +708,6 @@ def provision_guess(lp): subobj.machinepass = misc.random_password(12) subobj.adminpass = misc.random_password(12) subobj.dnspass = misc.random_password(12) - subobj.datestring = time.strftime("%Y%m%d%H") subobj.root = findnss(pwd.getpwnam, "root")[4] subobj.nobody = findnss(pwd.getpwnam, "nobody")[4] subobj.nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] @@ -625,12 +718,9 @@ def provision_guess(lp): subobj.dnsdomain = subobj.realm.lower() subobj.dnsname = "%s.%s" % (subobj.hostname.lower(), subobj.dnsdomain) subobj.domaindn = "DC=" + subobj.dnsdomain.replace(".", ",DC=") - subobj.domaindn_ldb = "users.ldb" subobj.rootdn = subobj.domaindn subobj.configdn = "CN=Configuration," + subobj.rootdn - subobj.configdn_ldb = "configuration.ldb" subobj.schemadn = "CN=Schema," + subobj.configdn - subobj.schemadn_ldb = "schema.ldb" #Add modules to the list to activate them by default #beware often order is important @@ -661,21 +751,23 @@ def provision_guess(lp): subobj.modules_list2 = ["show_deleted", "partition"] - subobj.extensibleobject = "# no objectClass: extensibleObject for local ldb" - subobj.aci = "# no aci for local ldb" return subobj -def load_schema(setup_dir, subobj, samdb): +def load_schema(setup_dir, samdb, subobj): """Load schema.""" src = os.path.join(setup_dir, "schema.ldif") schema_data = open(src, 'r').read() src = os.path.join(setup_dir, "schema_samba4.ldif") schema_data += open(src, 'r').read() - schema_data = substitute_var(schema_data, subobj.subst_vars()) + schema_data = substitute_var(schema_data, {"SCHEMADN": subobj.schemadn}) src = os.path.join(setup_dir, "provision_schema_basedn_modify.ldif") head_data = open(src, 'r').read() - head_data = substitute_var(head_data, subobj.subst_vars()) + head_data = substitute_var(head_data, { + "SCHEMADN": subobj.schemadn, + "NETBIOSNAME": subobj.netbiosname, + "CONFIGDN": subobj.configdn, + "DEFAULTSITE": subobj.defaultsite}) samdb.attach_schema_from_ldif(head_data, schema_data) -- cgit From 4bfbd78086a342e4075596a6a9e5de0cec0b47ac Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 18 Dec 2007 17:21:20 +0100 Subject: r26524: Import self join. (This used to be commit daae983c260da6af6a4f1cba1290bc7240d7a970) --- source4/scripting/python/samba/provision.py | 117 ++++++++++++++++++---------- 1 file changed, 75 insertions(+), 42 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index a8aeb8c831..c17b74345a 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -54,14 +54,6 @@ class ProvisionSettings(object): self.schemedn_ldb = None self.s4_ldapi_path = None self.policyguid = None - self.serverrole = None - - def subst_vars(self): - return { - "SERVERROLE": self.serverrole, - "DOMAIN_CONF": self.domain, - "REALM_CONF": self.realm, - } def fix(self, paths): self.realm = self.realm.upper() @@ -75,13 +67,6 @@ class ProvisionSettings(object): rdns = self.domaindn.split(",") self.rdn_dc = rdns[0][len("DC="):] - self.sam_ldb = paths.samdb - self.secrets_ldb = paths.secrets - self.secrets_keytab = paths.keytab - - self.s4_ldapi_path = paths.s4_ldapi_path - self.serverrole = "domain controller" - def validate(self, lp): if not valid_netbios_name(self.domain): raise InvalidNetbiosName(self.domain) @@ -111,12 +96,12 @@ class ProvisionPaths: self.samdb = None self.secrets = None self.keytab = None + self.dns_keytab = None self.dns = None self.winsdb = None self.ldap_basedn_ldif = None self.ldap_config_basedn_ldif = None self.ldap_schema_basedn_ldif = None - self.s4_ldapi_path = None def install_ok(lp, session_info, credentials): @@ -184,6 +169,8 @@ def setup_add_ldif(ldb, setup_dir, ldif, subst_vars=None): if subst_vars is not None: data = substitute_var(data, subst_vars) + assert "${" not in data + for msg in ldb.parse_ldif(data): ldb.add(msg[1]) @@ -195,6 +182,8 @@ def setup_modify_ldif(ldb, setup_dir, ldif, substvars=None): if substvars is not None: data = substitute_var(data, substvars) + assert "${" not in data + for (changetype, msg) in ldb.parse_ldif(data): ldb.modify(msg) @@ -231,7 +220,8 @@ def setup_file(setup_dir, template, fname, substvars): os.unlink(f) data = open(src, 'r').read() - data = substitute_var(data, substvars) + if substvars: + data = substitute_var(data, substvars) assert not "${" in data open(f, 'w').write(data) @@ -250,6 +240,7 @@ def provision_default_paths(lp, subobj): paths.secrets = os.path.join(private_dir, lp.get("secrets database") or "secrets.ldb") paths.templates = os.path.join(private_dir, "templates.ldb") paths.keytab = os.path.join(private_dir, "secrets.keytab") + paths.dns_keytab = os.path.join(private_dir, "dns.keytab") paths.dns = os.path.join(private_dir, subobj.dnsdomain + ".zone") paths.winsdb = os.path.join(private_dir, "wins.ldb") paths.ldap_basedn_ldif = os.path.join(private_dir, @@ -262,6 +253,14 @@ def provision_default_paths(lp, subobj): paths.phpldapadminconfig = os.path.join(private_dir, "phpldapadmin-config.php") paths.hklm = os.path.join(private_dir, "hklm.ldb") + paths.sysvol = lp.get("sysvol", "path") + if paths.sysvol is None: + paths.sysvol = os.path.join(lp.get("lock dir"), "sysvol") + + paths.netlogon = lp.get("netlogon", "path") + if paths.netlogon is None: + paths.netlogon = os.path.join(os.path.join(paths.sysvol, "scripts")) + return paths @@ -412,11 +411,6 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, """ subobj.fix(paths) - if subobj.host_guid is not None: - subobj.hostguid_add = "objectGUID: %s" % subobj.host_guid - else: - subobj.hostguid_add = "" - assert paths.smbconf is not None # only install a new smb.conf if there isn't one there already @@ -440,10 +434,11 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, setup_ldb(share_ldb, setup_dir, "share.ldif", None) message("Setting up %s" % paths.secrets) - setup_secretsdb(paths.secrets, setup_dir, session_info=session_info, + secrets_ldb = setup_secretsdb(paths.secrets, setup_dir, session_info=session_info, credentials=credentials, lp=lp) message("Setting up registry") + # FIXME: Still fails for some reason #setup_registry(paths.hklm, setup_dir, session_info, # credentials=credentials, lp=lp) @@ -582,15 +577,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, "CONFIGDN": subobj.configdn, }) - if blank: - message("Setting up sam.ldb index") - setup_add_ldif(samdb, setup_dir, "provision_index.ldif") - - message("Setting up sam.ldb rootDSE marking as syncronized") - setup_modify_ldif(samdb, setup_dir, "provision_rootdse_modify.ldif") - - samdb.transaction_commit() - return + if not blank: # message("Activate schema module") # setup_modify_ldif("schema_activation.ldif", info, samdb, False) @@ -605,16 +592,62 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, # # samdb = open_ldb(info, paths.samdb, False) # - message("Setting up sam.ldb users and groups") - setup_add_ldif(samdb, setup_dir, "provision_users.ldif", { - "DOMAINDN": subobj.domaindn, - "DOMAINSID": str(subobj.domainsid), - "CONFIGDN": subobj.configdn, - "ADMINPASS_B64": b64encode(subobj.adminpass), - "KRBTGTPASS_B64": b64encode(subobj.krbtgtpass), - }) + message("Setting up sam.ldb users and groups") + setup_add_ldif(samdb, setup_dir, "provision_users.ldif", { + "DOMAINDN": subobj.domaindn, + "DOMAINSID": str(subobj.domainsid), + "CONFIGDN": subobj.configdn, + "ADMINPASS_B64": b64encode(subobj.adminpass), + "KRBTGTPASS_B64": b64encode(subobj.krbtgtpass), + }) + + if lp.get("server role") == "domain controller": + message("Setting up self join") + if subobj.host_guid is not None: + hostguid_add = "objectGUID: %s" % subobj.host_guid + else: + hostguid_add = "" + + setup_add_ldif(samdb, setup_dir, "provision_self_join.ldif", { + "CONFIGDN": subobj.configdn, + "SCHEMADN": subobj.schemadn, + "DOMAINDN": subobj.domaindn, + "INVOCATIONID": subobj.invocationid, + "NETBIOSNAME": subobj.netbiosname, + "DEFAULTSITE": subobj.defaultsite, + "DNSNAME": subobj.dnsname, + "MACHINEPASS_B64": b64encode(subobj.machinepass), + "DNSPASS_B64": b64encode(subobj.dnspass), + "REALM": subobj.realm, + "DOMAIN": subobj.domain, + "HOSTGUID_ADD": hostguid_add, + "DNSDOMAIN": subobj.dnsdomain}) + setup_add_ldif(samdb, setup_dir, "provision_group_policy.ldif", { + "POLICYGUID": subobj.policyguid, + "DNSDOMAIN": subobj.dnsdomain, + "DOMAINSID": str(subobj.domainsid), + "DOMAINDN": subobj.domaindn}) + + os.makedirs(os.path.join(paths.sysvol, subobj.dnsdomain, "Policies", "{" + subobj.policyguid + "}"), 0755) + os.makedirs(os.path.join(paths.sysvol, subobj.dnsdomain, "Policies", "{" + subobj.policyguid + "}", "Machine"), 0755) + os.makedirs(os.path.join(paths.sysvol, subobj.dnsdomain, "Policies", "{" + subobj.policyguid + "}", "User"), 0755) + if not os.path.isdir(paths.netlogon): + os.makedirs(paths.netlogon, 0755) + setup_ldb(secrets_ldb, setup_dir, "secrets_dc.ldif", { + "MACHINEPASS_B64": b64encode(subobj.machinepass), + "DOMAIN": subobj.domain, + "REALM": subobj.realm, + "LDAPTIME": timestring(int(time.time())), + "DNSDOMAIN": subobj.dnsdomain, + "DOMAINSID": str(subobj.domainsid), + "SECRETS_KEYTAB": paths.keytab, + "NETBIOSNAME": subobj.netbiosname, + "SAM_LDB": paths.samdb, + "DNS_KEYTAB": paths.dns_keytab, + "DNSPASS_B64": b64encode(subobj.dnspass), + }) - setup_name_mappings(subobj, samdb) + setup_name_mappings(subobj, samdb) message("Setting up sam.ldb index") setup_add_ldif(samdb, setup_dir, "provision_index.ldif") @@ -628,7 +661,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, samdb.transaction_commit() message("Setting up phpLDAPadmin configuration") - create_phplpapdadmin_config(paths.phpldapadminconfig, setup_dir, subobj.s4_ldapi_path) + create_phplpapdadmin_config(paths.phpldapadminconfig, setup_dir, paths.s4_ldapi_path) message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) -- cgit From 44946cefb3c016a45f1d167db765b705e96ed70c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 18 Dec 2007 17:21:24 +0100 Subject: r26525: Consistency in the API. (This used to be commit 37577fee582e7c9896b5cf8b62016d480b8f147e) --- source4/scripting/python/samba/provision.py | 103 ++++++++++++++-------------- 1 file changed, 53 insertions(+), 50 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index c17b74345a..ebc8288351 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -199,12 +199,13 @@ def setup_ldb(ldb, setup_dir, ldif, subst_vars=None): ldb.transaction_commit() -def setup_ldb_modify(setup_dir, ldif, substvars, ldb): +def setup_ldb_modify(ldb, setup_dir, ldif, substvars=None): """Modify a ldb in the private dir.""" src = os.path.join(setup_dir, ldif) data = open(src, 'r').read() - data = substitute_var(data, substvars) + if substvars is not None: + data = substitute_var(data, substvars) assert not "${" in data for (changetype, msg) in ldb.parse_ldif(data): @@ -312,7 +313,8 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, samdb.erase() message("Setting up %s partitions" % paths.samdb) - setup_samdb_partitions(samdb, setup_dir, subobj) + setup_samdb_partitions(samdb, setup_dir, subobj.schemadn, + subobj.configdn, subobj.domaindn) samdb = SamDB(paths.samdb, credentials=credentials, session_info=session_info, lp=lp) @@ -382,23 +384,52 @@ def setup_samdb_rootdse(samdb, setup_dir, subobj): }) -def setup_samdb_partitions(samdb, setup_dir, subobj): +def setup_samdb_partitions(samdb, setup_dir, schemadn, configdn, domaindn): + #Add modules to the list to activate them by default + #beware often order is important + # + # Some Known ordering constraints: + # - rootdse must be first, as it makes redirects from "" -> cn=rootdse + # - objectclass must be before password_hash, because password_hash checks + # that the objectclass is of type person (filled in by objectclass + # module when expanding the objectclass list) + # - partition must be last + # - each partition has its own module list then + modules_list = ["rootdse", + "paged_results", + "ranged_results", + "anr", + "server_sort", + "extended_dn", + "asq", + "samldb", + "rdn_name", + "objectclass", + "kludge_acl", + "operational"] + tdb_modules_list = [ + "subtree_rename", + "subtree_delete", + "linked_attributes"] + modules_list2 = ["show_deleted", + "partition"] + setup_ldb(samdb, setup_dir, "provision_partitions.ldif", { - "SCHEMADN": subobj.schemadn, + "SCHEMADN": schemadn, "SCHEMADN_LDB": "schema.ldb", "SCHEMADN_MOD2": ",objectguid", - "CONFIGDN": subobj.configdn, + "CONFIGDN": configdn, "CONFIGDN_LDB": "configuration.ldb", - "DOMAINDN": subobj.domaindn, + "DOMAINDN": domaindn, "DOMAINDN_LDB": "users.ldb", "SCHEMADN_MOD": "schema_fsmo", "CONFIGDN_MOD": "naming_fsmo", "CONFIGDN_MOD2": ",objectguid", "DOMAINDN_MOD": "pdc_fsmo,password_hash", "DOMAINDN_MOD2": ",objectguid", - "MODULES_LIST": ",".join(subobj.modules_list), - "TDB_MODULES_LIST": ","+",".join(subobj.tdb_modules_list), - "MODULES_LIST2": ",".join(subobj.modules_list2), + "MODULES_LIST": ",".join(modules_list), + "TDB_MODULES_LIST": ","+",".join(tdb_modules_list), + "MODULES_LIST2": ",".join(modules_list2), }) @@ -451,7 +482,8 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, samdb.erase() message("Setting up sam.ldb partitions") - setup_samdb_partitions(samdb, setup_dir, subobj) + setup_samdb_partitions(samdb, setup_dir, subobj.schemadn, + subobj.configdn, subobj.domaindn) samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) @@ -495,7 +527,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, else: domainguid_mod = "" - setup_ldb_modify(setup_dir, "provision_basedn_modify.ldif", { + setup_ldb_modify(samdb, setup_dir, "provision_basedn_modify.ldif", { "RDN_DC": subobj.rdn_dc, "LDAPTIME": timestring(int(time.time())), "DOMAINSID": str(subobj.domainsid), @@ -506,7 +538,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, "POLICYGUID": subobj.policyguid, "DOMAINDN": subobj.domaindn, "DOMAINGUID_MOD": domainguid_mod, - }, samdb) + }) message("Adding configuration container (permitted to fail)") setup_add_ldif(samdb, setup_dir, "provision_configuration_basedn.ldif", { @@ -515,10 +547,10 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", }) message("Modifying configuration container") - setup_ldb_modify(setup_dir, "provision_configuration_basedn_modify.ldif", { + setup_ldb_modify(samdb, setup_dir, "provision_configuration_basedn_modify.ldif", { "CONFIGDN": subobj.configdn, "SCHEMADN": subobj.schemadn, - }, samdb) + }) message("Adding schema container (permitted to fail)") setup_add_ldif(samdb, setup_dir, "provision_schema_basedn.ldif", { @@ -527,12 +559,12 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" }) message("Modifying schema container") - setup_ldb_modify(setup_dir, "provision_schema_basedn_modify.ldif", { + setup_ldb_modify(samdb, setup_dir, "provision_schema_basedn_modify.ldif", { "SCHEMADN": subobj.schemadn, "NETBIOSNAME": subobj.netbiosname, "DEFAULTSITE": subobj.defaultsite, "CONFIGDN": subobj.configdn, - }, samdb) + }) message("Setting up sam.ldb Samba4 schema") setup_add_ldif(samdb, setup_dir, "schema_samba4.ldif", { @@ -561,14 +593,14 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, setup_add_ldif(samdb, setup_dir, "provision_users_add.ldif", { "DOMAINDN": subobj.domaindn}) message("Modifying users container") - setup_ldb_modify(setup_dir, "provision_users_modify.ldif", { - "DOMAINDN": subobj.domaindn}, samdb) + setup_ldb_modify(samdb, setup_dir, "provision_users_modify.ldif", { + "DOMAINDN": subobj.domaindn}) message("Adding computers container (permitted to fail)") setup_add_ldif(samdb, setup_dir, "provision_computers_add.ldif", { "DOMAINDN": subobj.domaindn}) message("Modifying computers container") - setup_ldb_modify(setup_dir, "provision_computers_modify.ldif", { - "DOMAINDN": subobj.domaindn}, samdb) + setup_ldb_modify(samdb, setup_dir, "provision_computers_modify.ldif", { + "DOMAINDN": subobj.domaindn}) message("Setting up sam.ldb data") setup_add_ldif(samdb, setup_dir, "provision.ldif", { "DOMAINDN": subobj.domaindn, @@ -755,35 +787,6 @@ def provision_guess(lp): subobj.configdn = "CN=Configuration," + subobj.rootdn subobj.schemadn = "CN=Schema," + subobj.configdn - #Add modules to the list to activate them by default - #beware often order is important - # - # Some Known ordering constraints: - # - rootdse must be first, as it makes redirects from "" -> cn=rootdse - # - objectclass must be before password_hash, because password_hash checks - # that the objectclass is of type person (filled in by objectclass - # module when expanding the objectclass list) - # - partition must be last - # - each partition has its own module list then - subobj.modules_list = ["rootdse", - "paged_results", - "ranged_results", - "anr", - "server_sort", - "extended_dn", - "asq", - "samldb", - "rdn_name", - "objectclass", - "kludge_acl", - "operational"] - subobj.tdb_modules_list = [ - "subtree_rename", - "subtree_delete", - "linked_attributes"] - subobj.modules_list2 = ["show_deleted", - "partition"] - return subobj -- cgit From 4e6ab64762477c0117aa823fd8e6b1275d63e0d7 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 18 Dec 2007 18:54:19 +0100 Subject: r26527: Start on tests for provision. (This used to be commit 84ac6c6bbfc4baaf28906ee5826a9cf888043656) --- source4/scripting/python/samba/provision.py | 60 ++++++++++------------------- 1 file changed, 20 insertions(+), 40 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index ebc8288351..04f50e8359 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -135,18 +135,6 @@ def hostname(): return gethostname().split(".")[0] -def ldb_delete(ldb): - """Delete a LDB file. - - This may be necessary if the ldb is in bad shape, possibly due to being - built from an incompatible previous version of the code, so delete it - completely. - """ - print "Deleting %s\n" % ldb.filename - os.unlink(ldb.filename) - ldb.connect(ldb.filename) - - def open_ldb(session_info, credentials, lp, dbname): assert session_info is not None try: @@ -176,6 +164,13 @@ def setup_add_ldif(ldb, setup_dir, ldif, subst_vars=None): def setup_modify_ldif(ldb, setup_dir, ldif, substvars=None): + """Modify a ldb in the private dir. + + :param ldb: LDB object. + :param setup_dir: Setup directory. + :param ldif: LDIF file path. + :param substvars: Optional dictionary with substitution variables. + """ src = os.path.join(setup_dir, ldif) data = open(src, 'r').read() @@ -199,19 +194,6 @@ def setup_ldb(ldb, setup_dir, ldif, subst_vars=None): ldb.transaction_commit() -def setup_ldb_modify(ldb, setup_dir, ldif, substvars=None): - """Modify a ldb in the private dir.""" - src = os.path.join(setup_dir, ldif) - - data = open(src, 'r').read() - if substvars is not None: - data = substitute_var(data, substvars) - assert not "${" in data - - for (changetype, msg) in ldb.parse_ldif(data): - ldb.modify(msg) - - def setup_file(setup_dir, template, fname, substvars): """Setup a file in the private dir.""" f = fname @@ -328,7 +310,7 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, setup_samdb_rootdse(samdb, setup_dir, subobj) message("Erasing data from partitions") - ldb_erase_partitions(subobj, message, samdb, None) + ldb_erase_partitions(subobj.domaindn, message, samdb, None) message("Setting up %s indexes" % paths.samdb) setup_add_ldif(samdb, setup_dir, "provision_index.ldif") @@ -453,8 +435,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, smbconfsuffix = "member" else: assert "Invalid server role setting: %s" % lp.get("server role") - setup_file(setup_dir, "provision.smb.conf.%s" % smbconfsuffix, paths.smbconf, - None) + setup_file(setup_dir, "provision.smb.conf.%s" % smbconfsuffix, paths.smbconf) lp.reload() # only install a new shares config db if there is none @@ -462,7 +443,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, message("Setting up share.ldb") share_ldb = Ldb(paths.shareconf, session_info=session_info, credentials=credentials, lp=lp) - setup_ldb(share_ldb, setup_dir, "share.ldif", None) + setup_ldb(share_ldb, setup_dir, "share.ldif") message("Setting up %s" % paths.secrets) secrets_ldb = setup_secretsdb(paths.secrets, setup_dir, session_info=session_info, @@ -497,7 +478,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, setup_samdb_rootdse(samdb, setup_dir, subobj) message("Erasing data from partitions") - ldb_erase_partitions(subobj, message, samdb, ldapbackend) + ldb_erase_partitions(subobj.domaindn, message, samdb, ldapbackend) except: samdb.transaction_cancel() raise @@ -527,7 +508,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, else: domainguid_mod = "" - setup_ldb_modify(samdb, setup_dir, "provision_basedn_modify.ldif", { + setup_modify_ldif(samdb, setup_dir, "provision_basedn_modify.ldif", { "RDN_DC": subobj.rdn_dc, "LDAPTIME": timestring(int(time.time())), "DOMAINSID": str(subobj.domainsid), @@ -547,7 +528,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", }) message("Modifying configuration container") - setup_ldb_modify(samdb, setup_dir, "provision_configuration_basedn_modify.ldif", { + setup_modify_ldif(samdb, setup_dir, "provision_configuration_basedn_modify.ldif", { "CONFIGDN": subobj.configdn, "SCHEMADN": subobj.schemadn, }) @@ -559,7 +540,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" }) message("Modifying schema container") - setup_ldb_modify(samdb, setup_dir, "provision_schema_basedn_modify.ldif", { + setup_modify_ldif(samdb, setup_dir, "provision_schema_basedn_modify.ldif", { "SCHEMADN": subobj.schemadn, "NETBIOSNAME": subobj.netbiosname, "DEFAULTSITE": subobj.defaultsite, @@ -593,13 +574,13 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, setup_add_ldif(samdb, setup_dir, "provision_users_add.ldif", { "DOMAINDN": subobj.domaindn}) message("Modifying users container") - setup_ldb_modify(samdb, setup_dir, "provision_users_modify.ldif", { + setup_modify_ldif(samdb, setup_dir, "provision_users_modify.ldif", { "DOMAINDN": subobj.domaindn}) message("Adding computers container (permitted to fail)") setup_add_ldif(samdb, setup_dir, "provision_computers_add.ldif", { "DOMAINDN": subobj.domaindn}) message("Modifying computers container") - setup_ldb_modify(samdb, setup_dir, "provision_computers_modify.ldif", { + setup_modify_ldif(samdb, setup_dir, "provision_computers_modify.ldif", { "DOMAINDN": subobj.domaindn}) message("Setting up sam.ldb data") setup_add_ldif(samdb, setup_dir, "provision.ldif", { @@ -807,7 +788,7 @@ def load_schema(setup_dir, samdb, subobj): samdb.attach_schema_from_ldif(head_data, schema_data) -def join_domain(domain, netbios_name, join_type, creds, message): +def join_domain(domain, netbios_name, join_type, creds): ctx = NetContext(creds) joindom = object() joindom.domain = domain @@ -824,8 +805,7 @@ def vampire(domain, session_info, credentials, message): access to our local database (might be remote ldap) """ ctx = NetContext(credentials) - vampire_ctx = object() - machine_creds = credentials_init() + machine_creds = Credentials() machine_creds.set_domain(form.domain) if not machine_creds.set_machine_account(): raise Exception("Failed to access domain join information!") @@ -835,7 +815,7 @@ def vampire(domain, session_info, credentials, message): raise Exception("Migration of remote domain to Samba failed: %s " % vampire_ctx.error_string) -def ldb_erase_partitions(subobj, message, ldb, ldapbackend): +def ldb_erase_partitions(domaindn, message, ldb, ldapbackend): """Erase an ldb, removing all records.""" assert ldb is not None res = ldb.search(Dn(ldb, ""), SCOPE_BASE, "(objectClass=*)", @@ -848,7 +828,7 @@ def ldb_erase_partitions(subobj, message, ldb, ldapbackend): previous_remaining = 1 current_remaining = 0 - if ldapbackend and (basedn == subobj.domaindn): + if ldapbackend and (basedn == domaindn): # Only delete objects that were created by provision anything = "(objectcategory=*)" -- cgit From 595ec370da471116b35464dc65d2962f28380d74 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 19 Dec 2007 23:27:24 +0100 Subject: r26535: Get rid of all-knowing ProvisionSettings object. (This used to be commit 40bf88c8a70e8379a6081cb6050034bcd7ae56eb) --- source4/scripting/python/samba/provision.py | 522 ++++++++++++++-------------- 1 file changed, 258 insertions(+), 264 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 04f50e8359..c9cb457b4a 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1,8 +1,10 @@ # # backend code for provisioning a Samba4 server -# Copyright Andrew Tridgell 2005 -# Copyright Jelmer Vernooij 2007 # Released under the GNU GPL v2 or later +# Copyright Jelmer Vernooij 2007 +# +# Based on the original in EJS: +# Copyright Andrew Tridgell 2005 # from base64 import b64encode @@ -22,67 +24,13 @@ from ldb import Dn, SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ LDB_ERR_NO_SUCH_OBJECT, timestring +DEFAULTSITE = "Default-First-Site-Name" + class InvalidNetbiosName(Exception): def __init__(self, name): super(InvalidNetbiosName, self).__init__("The name '%r' is not a valid NetBIOS name" % name) -class ProvisionSettings(object): - def __init__(self, realm=None, domain=None, hostname=None, hostip=None): - self.realm = realm - self.domain = domain - self.hostname = hostname - self.hostip = hostip - self.domainsid = None - self.invocationid = None - self.krbtgtpass = None - self.machinepass = None - self.adminpass = None - self.defaultsite = "Default-First-Site-Name" - self.root = None - self.nobody = None - self.nogroup = None - self.wheel = None - self.backup = None - self.users = None - self.dnsdomain = None - self.dnsname = None - self.domaindn = None - self.rootdn = None - self.configdn = None - self.schemedn = None - self.schemedn_ldb = None - self.s4_ldapi_path = None - self.policyguid = None - - def fix(self, paths): - self.realm = self.realm.upper() - self.hostname = self.hostname.lower() - self.domain = self.domain.upper() - if not valid_netbios_name(self.domain): - raise InvalidNetbiosName(self.domain) - self.netbiosname = self.hostname.upper() - if not valid_netbios_name(self.netbiosname): - raise InvalidNetbiosName(self.netbiosname) - rdns = self.domaindn.split(",") - self.rdn_dc = rdns[0][len("DC="):] - - def validate(self, lp): - if not valid_netbios_name(self.domain): - raise InvalidNetbiosName(self.domain) - - if not valid_netbios_name(self.netbiosname): - raise InvalidNetbiosName(self.netbiosname) - - if lp.get("workgroup").upper() != self.domain.upper(): - raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'\n", - lp.get("workgroup"), self.domain) - - if lp.get("realm").upper() != self.realm.upper(): - raise Error("realm '%s' in smb.conf must match chosen realm '%s'\n" % - (lp.get("realm"), self.realm)) - - class ProvisionPaths: def __init__(self): self.smbconf = None @@ -125,11 +73,6 @@ def findnss(nssfn, *names): raise Exception("Unable to find user/group for %s" % arguments[1]) -def hostip(): - """return first host IP.""" - return gethostbyname(hostname()) - - def hostname(): """return first part of hostname.""" return gethostname().split(".")[0] @@ -210,11 +153,11 @@ def setup_file(setup_dir, template, fname, substvars): open(f, 'w').write(data) -def provision_default_paths(lp, subobj): +def provision_default_paths(lp, dnsdomain): """Set the default paths for provisioning. :param lp: Loadparm context. - :param subobj: Object + :param dnsdomain: DNS Domain name """ paths = ProvisionPaths() private_dir = lp.get("private dir") @@ -224,14 +167,14 @@ def provision_default_paths(lp, subobj): paths.templates = os.path.join(private_dir, "templates.ldb") paths.keytab = os.path.join(private_dir, "secrets.keytab") paths.dns_keytab = os.path.join(private_dir, "dns.keytab") - paths.dns = os.path.join(private_dir, subobj.dnsdomain + ".zone") + paths.dns = os.path.join(private_dir, dnsdomain + ".zone") paths.winsdb = os.path.join(private_dir, "wins.ldb") paths.ldap_basedn_ldif = os.path.join(private_dir, - subobj.dnsdomain + ".ldif") + dnsdomain + ".ldif") paths.ldap_config_basedn_ldif = os.path.join(private_dir, - subobj.dnsdomain + "-config.ldif") + dnsdomain + "-config.ldif") paths.ldap_schema_basedn_ldif = os.path.join(private_dir, - subobj.dnsdomain + "-schema.ldif") + dnsdomain + "-schema.ldif") paths.s4_ldapi_path = os.path.join(private_dir, "ldapi") paths.phpldapadminconfig = os.path.join(private_dir, "phpldapadmin-config.php") @@ -247,41 +190,39 @@ def provision_default_paths(lp, subobj): return paths -def setup_name_mappings(subobj, ldb): +def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users, + wheel, backup): """setup reasonable name mappings for sam names to unix names.""" - sid = str(subobj.domainsid) - # add some foreign sids if they are not present already - ldb.add_foreign(subobj.domaindn, "S-1-5-7", "Anonymous") - ldb.add_foreign(subobj.domaindn, "S-1-1-0", "World") - ldb.add_foreign(subobj.domaindn, "S-1-5-2", "Network") - ldb.add_foreign(subobj.domaindn, "S-1-5-18", "System") - ldb.add_foreign(subobj.domaindn, "S-1-5-11", "Authenticated Users") + ldb.add_foreign(domaindn, "S-1-5-7", "Anonymous") + ldb.add_foreign(domaindn, "S-1-1-0", "World") + ldb.add_foreign(domaindn, "S-1-5-2", "Network") + ldb.add_foreign(domaindn, "S-1-5-18", "System") + ldb.add_foreign(domaindn, "S-1-5-11", "Authenticated Users") # some well known sids - ldb.setup_name_mapping(subobj.domaindn, "S-1-5-7", subobj.nobody) - ldb.setup_name_mapping(subobj.domaindn, "S-1-1-0", subobj.nogroup) - ldb.setup_name_mapping(subobj.domaindn, "S-1-5-2", subobj.nogroup) - ldb.setup_name_mapping(subobj.domaindn, "S-1-5-18", subobj.root) - ldb.setup_name_mapping(subobj.domaindn, "S-1-5-11", subobj.users) - ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-544", subobj.wheel) - ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-545", subobj.users) - ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-546", subobj.nogroup) - ldb.setup_name_mapping(subobj.domaindn, "S-1-5-32-551", subobj.backup) + ldb.setup_name_mapping(domaindn, "S-1-5-7", nobody) + ldb.setup_name_mapping(domaindn, "S-1-1-0", nogroup) + ldb.setup_name_mapping(domaindn, "S-1-5-2", nogroup) + ldb.setup_name_mapping(domaindn, "S-1-5-18", root) + ldb.setup_name_mapping(domaindn, "S-1-5-11", users) + ldb.setup_name_mapping(domaindn, "S-1-5-32-544", wheel) + ldb.setup_name_mapping(domaindn, "S-1-5-32-545", users) + ldb.setup_name_mapping(domaindn, "S-1-5-32-546", nogroup) + ldb.setup_name_mapping(domaindn, "S-1-5-32-551", backup) # and some well known domain rids - ldb.setup_name_mapping(subobj.domaindn, sid + "-500", subobj.root) - ldb.setup_name_mapping(subobj.domaindn, sid + "-518", subobj.wheel) - ldb.setup_name_mapping(subobj.domaindn, sid + "-519", subobj.wheel) - ldb.setup_name_mapping(subobj.domaindn, sid + "-512", subobj.wheel) - ldb.setup_name_mapping(subobj.domaindn, sid + "-513", subobj.users) - ldb.setup_name_mapping(subobj.domaindn, sid + "-520", subobj.wheel) + ldb.setup_name_mapping(domaindn, sid + "-500", root) + ldb.setup_name_mapping(domaindn, sid + "-518", wheel) + ldb.setup_name_mapping(domaindn, sid + "-519", wheel) + ldb.setup_name_mapping(domaindn, sid + "-512", wheel) + ldb.setup_name_mapping(domaindn, sid + "-513", users) + ldb.setup_name_mapping(domaindn, sid + "-520", wheel) -def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, +def provision_become_dc(setup_dir, message, paths, lp, session_info, credentials): assert session_info is not None - subobj.fix(paths) message("Setting up templates into %s" % paths.templates) setup_templatesdb(paths.templates, setup_dir, session_info, @@ -295,8 +236,8 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, samdb.erase() message("Setting up %s partitions" % paths.samdb) - setup_samdb_partitions(samdb, setup_dir, subobj.schemadn, - subobj.configdn, subobj.domaindn) + setup_samdb_partitions(samdb, setup_dir, schemadn, + configdn, domaindn) samdb = SamDB(paths.samdb, credentials=credentials, session_info=session_info, lp=lp) @@ -307,10 +248,12 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, setup_add_ldif(samdb, setup_dir, "provision_init.ldif") message("Setting up %s rootDSE" % paths.samdb) - setup_samdb_rootdse(samdb, setup_dir, subobj) + setup_samdb_rootdse(samdb, setup_dir, schemadn, domaindn, + hostname, dnsdomain, realm, rootdn, configdn, + netbiosname) message("Erasing data from partitions") - ldb_erase_partitions(subobj.domaindn, message, samdb, None) + ldb_erase_partitions(domaindn, message, samdb, None) message("Setting up %s indexes" % paths.samdb) setup_add_ldif(samdb, setup_dir, "provision_index.ldif") @@ -323,7 +266,7 @@ def provision_become_dc(setup_dir, subobj, message, paths, lp, session_info, message("Setting up %s" % paths.secrets) secrets_ldb = setup_secretsdb(paths.secrets, setup_dir, session_info, credentials, lp) setup_ldb(secrets_ldb, setup_dir, "secrets_dc.ldif", - { "MACHINEPASS_B64": b64encode(self.machinepass) }) + { "MACHINEPASS_B64": b64encode(machinepass) }) def setup_secretsdb(path, setup_dir, session_info, credentials, lp): @@ -351,17 +294,18 @@ def setup_registry(path, setup_dir, session_info, credentials, lp): reg.apply_patchfile(provision_reg) -def setup_samdb_rootdse(samdb, setup_dir, subobj): +def setup_samdb_rootdse(samdb, setup_dir, schemadn, domaindn, hostname, + dnsdomain, realm, rootdn, configdn, netbiosname): setup_add_ldif(samdb, setup_dir, "provision_rootdse_add.ldif", { - "SCHEMADN": subobj.schemadn, - "NETBIOSNAME": subobj.netbiosname, - "DNSDOMAIN": subobj.dnsdomain, - "DEFAULTSITE": subobj.defaultsite, - "REALM": subobj.realm, - "DNSNAME": subobj.dnsname, - "DOMAINDN": subobj.domaindn, - "ROOTDN": subobj.rootdn, - "CONFIGDN": subobj.configdn, + "SCHEMADN": schemadn, + "NETBIOSNAME": netbiosname, + "DNSDOMAIN": dnsdomain, + "DEFAULTSITE": DEFAULTSITE, + "REALM": realm, + "DNSNAME": "%s.%s" % (hostname, dnsdomain), + "DOMAINDN": domaindn, + "ROOTDN": rootdn, + "CONFIGDN": configdn, "VERSION": samba.version(), }) @@ -416,25 +360,103 @@ def setup_samdb_partitions(samdb, setup_dir, schemadn, configdn, domaindn): -def provision(lp, setup_dir, subobj, message, blank, paths, session_info, - credentials, ldapbackend): +def provision(lp, setup_dir, message, blank, paths, session_info, + credentials, ldapbackend, realm=None, domain=None, hostname=None, + hostip=None, domainsid=None, hostguid=None, adminpass=None, + krbtgtpass=None, domainguid=None, policyguid=None, + invocationid=None, machinepass=None, dnspass=None, root=None, + nobody=None, nogroup=None, users=None, wheel=None, backup=None, + aci=None, serverrole=None): """Provision samba4 :note: caution, this wipes all existing data! """ - subobj.fix(paths) + + if domainsid is None: + domainsid = security.random_sid() + if policyguid is None: + policyguid = uuid.random() + if invocationid is None: + invocationid = uuid.random() + if adminpass is None: + adminpass = misc.random_password(12) + if krbtgtpass is None: + krbtgtpass = misc.random_password(12) + if machinepass is None: + machinepass = misc.random_password(12) + if dnspass is None: + dnspass = misc.random_password(12) + if root is None: + root = findnss(pwd.getpwnam, "root")[4] + if nobody is None: + nobody = findnss(pwd.getpwnam, "nobody")[4] + if nogroup is None: + nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] + if users is None: + users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", "usr")[2] + if wheel is None: + wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[2] + if backup is None: + backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[2] + if aci is None: + aci = "# no aci for local ldb" + if serverrole is None: + serverrole = lp.get("server role") + + if realm is None: + realm = lp.get("realm") + else: + if lp.get("realm").upper() != realm.upper(): + raise Error("realm '%s' in smb.conf must match chosen realm '%s'\n" % + (lp.get("realm"), realm)) + + assert realm is not None + realm = realm.upper() + + if domain is None: + domain = lp.get("workgroup") + else: + if lp.get("workgroup").upper() != domain.upper(): + raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'\n", + lp.get("workgroup"), domain) + + assert domain is not None + domain = domain.upper() + if not valid_netbios_name(domain): + raise InvalidNetbiosName(domain) + + if hostname is None: + hostname = gethostname().split(".")[0].lower() + + if hostip is None: + hostip = gethostbyname(hostname) + + netbiosname = hostname.upper() + if not valid_netbios_name(netbiosname): + raise InvalidNetbiosName(netbiosname) + + dnsdomain = realm.lower() + domaindn = "DC=" + dnsdomain.replace(".", ",DC=") + rootdn = domaindn + configdn = "CN=Configuration," + rootdn + schemadn = "CN=Schema," + configdn + + rdn_dc = domaindn.split(",")[0][len("DC="):] + + message("Provisioning for %s in realm %s" % (domain, realm)) + message("Using administrator password: %s" % adminpass) assert paths.smbconf is not None # only install a new smb.conf if there isn't one there already if not os.path.exists(paths.smbconf): message("Setting up smb.conf") - if lp.get("server role") == "domain controller": + if serverrole == "domain controller": smbconfsuffix = "dc" - elif lp.get("server role") == "member": + elif serverrole == "member": smbconfsuffix = "member" else: - assert "Invalid server role setting: %s" % lp.get("server role") + assert "Invalid server role setting: %s" % serverrole setup_file(setup_dir, "provision.smb.conf.%s" % smbconfsuffix, paths.smbconf) lp.reload() @@ -463,8 +485,7 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, samdb.erase() message("Setting up sam.ldb partitions") - setup_samdb_partitions(samdb, setup_dir, subobj.schemadn, - subobj.configdn, subobj.domaindn) + setup_samdb_partitions(samdb, setup_dir, schemadn, configdn, domaindn) samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) @@ -475,10 +496,12 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, setup_add_ldif(samdb, setup_dir, "provision_init.ldif") message("Setting up sam.ldb rootDSE") - setup_samdb_rootdse(samdb, setup_dir, subobj) + setup_samdb_rootdse(samdb, setup_dir, schemadn, domaindn, + hostname, dnsdomain, realm, rootdn, configdn, + netbiosname) message("Erasing data from partitions") - ldb_erase_partitions(subobj.domaindn, message, samdb, ldapbackend) + ldb_erase_partitions(domaindn, message, samdb, ldapbackend) except: samdb.transaction_cancel() raise @@ -488,106 +511,104 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, message("Pre-loading the Samba 4 and AD schema") samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) - samdb.set_domain_sid(subobj.domainsid) - load_schema(setup_dir, samdb, subobj) + samdb.set_domain_sid(domainsid) + load_schema(setup_dir, samdb, schemadn, netbiosname, configdn) samdb.transaction_start() try: - message("Adding DomainDN: %s (permitted to fail)" % subobj.domaindn) + message("Adding DomainDN: %s (permitted to fail)" % domaindn) setup_add_ldif(samdb, setup_dir, "provision_basedn.ldif", { - "DOMAINDN": subobj.domaindn, - "ACI": "# no aci for local ldb", + "DOMAINDN": domaindn, + "ACI": aci, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", - "RDN_DC": subobj.rdn_dc, + "RDN_DC": rdn_dc, }) - message("Modifying DomainDN: " + subobj.domaindn + "") - if subobj.domain_guid is not None: - domainguid_mod = "replace: objectGUID\nobjectGUID: %s\n-" % subobj.domain_guid + message("Modifying DomainDN: " + domaindn + "") + if domainguid is not None: + domainguid_mod = "replace: objectGUID\nobjectGUID: %s\n-" % domainguid else: domainguid_mod = "" setup_modify_ldif(samdb, setup_dir, "provision_basedn_modify.ldif", { - "RDN_DC": subobj.rdn_dc, + "RDN_DC": rdn_dc, "LDAPTIME": timestring(int(time.time())), - "DOMAINSID": str(subobj.domainsid), - "SCHEMADN": subobj.schemadn, - "NETBIOSNAME": subobj.netbiosname, - "DEFAULTSITE": subobj.defaultsite, - "CONFIGDN": subobj.configdn, - "POLICYGUID": subobj.policyguid, - "DOMAINDN": subobj.domaindn, + "DOMAINSID": str(domainsid), + "SCHEMADN": schemadn, + "NETBIOSNAME": netbiosname, + "DEFAULTSITE": DEFAULTSITE, + "CONFIGDN": configdn, + "POLICYGUID": policyguid, + "DOMAINDN": domaindn, "DOMAINGUID_MOD": domainguid_mod, }) message("Adding configuration container (permitted to fail)") setup_add_ldif(samdb, setup_dir, "provision_configuration_basedn.ldif", { - "CONFIGDN": subobj.configdn, - "ACI": "# no aci for local ldb", + "CONFIGDN": configdn, + "ACI": aci, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", }) message("Modifying configuration container") setup_modify_ldif(samdb, setup_dir, "provision_configuration_basedn_modify.ldif", { - "CONFIGDN": subobj.configdn, - "SCHEMADN": subobj.schemadn, + "CONFIGDN": configdn, + "SCHEMADN": schemadn, }) message("Adding schema container (permitted to fail)") setup_add_ldif(samdb, setup_dir, "provision_schema_basedn.ldif", { - "SCHEMADN": subobj.schemadn, - "ACI": "# no aci for local ldb", + "SCHEMADN": schemadn, + "ACI": aci, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" }) message("Modifying schema container") setup_modify_ldif(samdb, setup_dir, "provision_schema_basedn_modify.ldif", { - "SCHEMADN": subobj.schemadn, - "NETBIOSNAME": subobj.netbiosname, - "DEFAULTSITE": subobj.defaultsite, - "CONFIGDN": subobj.configdn, + "SCHEMADN": schemadn, + "NETBIOSNAME": netbiosname, + "DEFAULTSITE": DEFAULTSITE, + "CONFIGDN": configdn, }) message("Setting up sam.ldb Samba4 schema") - setup_add_ldif(samdb, setup_dir, "schema_samba4.ldif", { - "SCHEMADN": subobj.schemadn, - }) + setup_add_ldif(samdb, setup_dir, "schema_samba4.ldif", + {"SCHEMADN": schemadn }) message("Setting up sam.ldb AD schema") - setup_add_ldif(samdb, setup_dir, "schema.ldif", { - "SCHEMADN": subobj.schemadn, - }) + setup_add_ldif(samdb, setup_dir, "schema.ldif", + {"SCHEMADN": schemadn}) message("Setting up sam.ldb configuration data") setup_add_ldif(samdb, setup_dir, "provision_configuration.ldif", { - "CONFIGDN": subobj.configdn, - "NETBIOSNAME": subobj.netbiosname, - "DEFAULTSITE": subobj.defaultsite, - "DNSDOMAIN": subobj.dnsdomain, - "DOMAIN": subobj.domain, - "SCHEMADN": subobj.schemadn, - "DOMAINDN": subobj.domaindn, + "CONFIGDN": configdn, + "NETBIOSNAME": netbiosname, + "DEFAULTSITE": DEFAULTSITE, + "DNSDOMAIN": dnsdomain, + "DOMAIN": domain, + "SCHEMADN": schemadn, + "DOMAINDN": domaindn, }) message("Setting up display specifiers") - setup_add_ldif(samdb, setup_dir, "display_specifiers.ldif", {"CONFIGDN": subobj.configdn}) + setup_add_ldif(samdb, setup_dir, "display_specifiers.ldif", {"CONFIGDN": configdn}) message("Adding users container (permitted to fail)") setup_add_ldif(samdb, setup_dir, "provision_users_add.ldif", { - "DOMAINDN": subobj.domaindn}) + "DOMAINDN": domaindn}) message("Modifying users container") setup_modify_ldif(samdb, setup_dir, "provision_users_modify.ldif", { - "DOMAINDN": subobj.domaindn}) + "DOMAINDN": domaindn}) message("Adding computers container (permitted to fail)") setup_add_ldif(samdb, setup_dir, "provision_computers_add.ldif", { - "DOMAINDN": subobj.domaindn}) + "DOMAINDN": domaindn}) message("Modifying computers container") setup_modify_ldif(samdb, setup_dir, "provision_computers_modify.ldif", { - "DOMAINDN": subobj.domaindn}) + "DOMAINDN": domaindn}) message("Setting up sam.ldb data") setup_add_ldif(samdb, setup_dir, "provision.ldif", { - "DOMAINDN": subobj.domaindn, - "NETBIOSNAME": subobj.netbiosname, - "DEFAULTSITE": subobj.defaultsite, - "CONFIGDN": subobj.configdn, + "DOMAINDN": domaindn, + "NETBIOSNAME": netbiosname, + "DEFAULTSITE": DEFAULTSITE, + "CONFIGDN": configdn, }) if not blank: @@ -607,60 +628,63 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, # message("Setting up sam.ldb users and groups") setup_add_ldif(samdb, setup_dir, "provision_users.ldif", { - "DOMAINDN": subobj.domaindn, - "DOMAINSID": str(subobj.domainsid), - "CONFIGDN": subobj.configdn, - "ADMINPASS_B64": b64encode(subobj.adminpass), - "KRBTGTPASS_B64": b64encode(subobj.krbtgtpass), + "DOMAINDN": domaindn, + "DOMAINSID": str(domainsid), + "CONFIGDN": configdn, + "ADMINPASS_B64": b64encode(adminpass), + "KRBTGTPASS_B64": b64encode(krbtgtpass), }) if lp.get("server role") == "domain controller": message("Setting up self join") - if subobj.host_guid is not None: - hostguid_add = "objectGUID: %s" % subobj.host_guid + if hostguid is not None: + hostguid_add = "objectGUID: %s" % hostguid else: hostguid_add = "" setup_add_ldif(samdb, setup_dir, "provision_self_join.ldif", { - "CONFIGDN": subobj.configdn, - "SCHEMADN": subobj.schemadn, - "DOMAINDN": subobj.domaindn, - "INVOCATIONID": subobj.invocationid, - "NETBIOSNAME": subobj.netbiosname, - "DEFAULTSITE": subobj.defaultsite, - "DNSNAME": subobj.dnsname, - "MACHINEPASS_B64": b64encode(subobj.machinepass), - "DNSPASS_B64": b64encode(subobj.dnspass), - "REALM": subobj.realm, - "DOMAIN": subobj.domain, + "CONFIGDN": configdn, + "SCHEMADN": schemadn, + "DOMAINDN": domaindn, + "INVOCATIONID": invocationid, + "NETBIOSNAME": netbiosname, + "DEFAULTSITE": DEFAULTSITE, + "DNSNAME": "%s.%s" % (hostname, dnsdomain), + "MACHINEPASS_B64": b64encode(machinepass), + "DNSPASS_B64": b64encode(dnspass), + "REALM": realm, + "DOMAIN": domain, "HOSTGUID_ADD": hostguid_add, - "DNSDOMAIN": subobj.dnsdomain}) + "DNSDOMAIN": dnsdomain}) setup_add_ldif(samdb, setup_dir, "provision_group_policy.ldif", { - "POLICYGUID": subobj.policyguid, - "DNSDOMAIN": subobj.dnsdomain, - "DOMAINSID": str(subobj.domainsid), - "DOMAINDN": subobj.domaindn}) - - os.makedirs(os.path.join(paths.sysvol, subobj.dnsdomain, "Policies", "{" + subobj.policyguid + "}"), 0755) - os.makedirs(os.path.join(paths.sysvol, subobj.dnsdomain, "Policies", "{" + subobj.policyguid + "}", "Machine"), 0755) - os.makedirs(os.path.join(paths.sysvol, subobj.dnsdomain, "Policies", "{" + subobj.policyguid + "}", "User"), 0755) + "POLICYGUID": policyguid, + "DNSDOMAIN": dnsdomain, + "DOMAINSID": str(domainsid), + "DOMAINDN": domaindn}) + + os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}"), 0755) + os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "Machine"), 0755) + os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "User"), 0755) if not os.path.isdir(paths.netlogon): os.makedirs(paths.netlogon, 0755) setup_ldb(secrets_ldb, setup_dir, "secrets_dc.ldif", { - "MACHINEPASS_B64": b64encode(subobj.machinepass), - "DOMAIN": subobj.domain, - "REALM": subobj.realm, + "MACHINEPASS_B64": b64encode(machinepass), + "DOMAIN": domain, + "REALM": realm, "LDAPTIME": timestring(int(time.time())), - "DNSDOMAIN": subobj.dnsdomain, - "DOMAINSID": str(subobj.domainsid), + "DNSDOMAIN": dnsdomain, + "DOMAINSID": str(domainsid), "SECRETS_KEYTAB": paths.keytab, - "NETBIOSNAME": subobj.netbiosname, + "NETBIOSNAME": netbiosname, "SAM_LDB": paths.samdb, "DNS_KEYTAB": paths.dns_keytab, - "DNSPASS_B64": b64encode(subobj.dnspass), + "DNSPASS_B64": b64encode(dnspass), }) - setup_name_mappings(subobj, samdb) + setup_name_mappings(samdb, str(domainsid), + domaindn, root=root, nobody=nobody, + nogroup=nogroup, wheel=wheel, users=users, + backup=backup) message("Setting up sam.ldb index") setup_add_ldif(samdb, setup_dir, "provision_index.ldif") @@ -678,113 +702,83 @@ def provision(lp, setup_dir, subobj, message, blank, paths, session_info, message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) + message("Setting up DNS zone: %s" % dnsdomain) + provision_dns(setup_dir, paths, session_info, credentials, lp, + hostname=hostname, hostip=hostip, dnsdomain=dnsdomain, + domaindn=domaindn, dnspass=dnspass, realm=realm) + message("Please install the zone located in %s into your DNS server" % paths.dns) def create_phplpapdadmin_config(path, setup_dir, s4_ldapi_path): setup_file(setup_dir, "phpldapadmin-config.php", path, {"S4_LDAPI_URI": "ldapi://%s" % s4_ldapi_path.replace("/", "%2F")}) -def provision_dns(setup_dir, subobj, message, paths, session_info, credentials, lp): +def provision_dns(setup_dir, paths, session_info, + credentials, lp, dnsdomain, domaindn, + hostip, hostname, dnspass, realm): """Write out a DNS zone file, from the info in the current database.""" - message("Setting up DNS zone: %s" % subobj.dnsdomain) + # connect to the sam ldb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) # These values may have changed, due to an incoming SamSync, # or may not have been specified, so fetch them from the database - domainguid = str(ldb.searchone(Dn(ldb, subobj.domaindn), "objectGUID")) + domainguid = str(ldb.searchone(Dn(ldb, domaindn), "objectGUID")) - hostguid = str(ldb.searchone(Dn(ldb, subobj.domaindn), "objectGUID" , - expression="(&(objectClass=computer)(cn=%s))" % subobj.netbiosname)) + hostguid = str(ldb.searchone(Dn(ldb, domaindn), "objectGUID" , + expression="(&(objectClass=computer)(cn=%s))" % hostname)) setup_file(setup_dir, "provision.zone", paths.dns, { - "DNSPASS_B64": b64encode(subobj.dnspass), - "HOSTNAME": hostname(), - "DNSDOMAIN": subobj.dnsdomain, - "REALM": subobj.realm, - "HOSTIP": hostip(), + "DNSPASS_B64": b64encode(dnspass), + "HOSTNAME": hostname, + "DNSDOMAIN": dnsdomain, + "REALM": realm, + "HOSTIP": hostip, "DOMAINGUID": domainguid, "DATESTRING": time.strftime("%Y%m%d%H"), - "DEFAULTSITE": subobj.defaultsite, + "DEFAULTSITE": DEFAULTSITE, "HOSTGUID": hostguid, }) - message("Please install the zone located in %s into your DNS server" % paths.dns) -def provision_ldapbase(setup_dir, subobj, message, paths): +def provision_ldapbase(setup_dir, message, paths): """Write out a DNS zone file, from the info in the current database.""" - message("Setting up LDAP base entry: %s" % subobj.domaindn) - rdns = subobj.domaindn.split(",") + message("Setting up LDAP base entry: %s" % domaindn) + rdns = domaindn.split(",") - subobj.rdn_dc = rdns[0][len("DC="):] + rdn_dc = rdns[0][len("DC="):] setup_file(setup_dir, "provision_basedn.ldif", - paths.ldap_basedn_ldif, - None) + paths.ldap_basedn_ldif) setup_file(setup_dir, "provision_configuration_basedn.ldif", - paths.ldap_config_basedn_ldif, None) + paths.ldap_config_basedn_ldif) setup_file(setup_dir, "provision_schema_basedn.ldif", paths.ldap_schema_basedn_ldif, { - "SCHEMADN": subobj.schemadn, + "SCHEMADN": schemadn, "ACI": "# no aci for local ldb", "EXTENSIBLEOBJECT": "objectClass: extensibleObject"}) 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") -def provision_guess(lp): - """guess reasonably default options for provisioning.""" - subobj = ProvisionSettings(realm=lp.get("realm").upper(), - domain=lp.get("workgroup"), - hostname=hostname(), - hostip=hostip()) - - assert subobj.realm is not None - assert subobj.domain is not None - assert subobj.hostname is not None - - subobj.domainsid = security.random_sid() - subobj.invocationid = uuid.random() - subobj.policyguid = uuid.random() - subobj.krbtgtpass = misc.random_password(12) - subobj.machinepass = misc.random_password(12) - subobj.adminpass = misc.random_password(12) - subobj.dnspass = misc.random_password(12) - subobj.root = findnss(pwd.getpwnam, "root")[4] - subobj.nobody = findnss(pwd.getpwnam, "nobody")[4] - subobj.nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] - subobj.wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[2] - subobj.backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[2] - subobj.users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", "usr")[2] - - subobj.dnsdomain = subobj.realm.lower() - subobj.dnsname = "%s.%s" % (subobj.hostname.lower(), subobj.dnsdomain) - subobj.domaindn = "DC=" + subobj.dnsdomain.replace(".", ",DC=") - subobj.rootdn = subobj.domaindn - subobj.configdn = "CN=Configuration," + subobj.rootdn - subobj.schemadn = "CN=Schema," + subobj.configdn - - return subobj - - -def load_schema(setup_dir, samdb, subobj): +def load_schema(setup_dir, samdb, schemadn, netbiosname, configdn): """Load schema.""" src = os.path.join(setup_dir, "schema.ldif") schema_data = open(src, 'r').read() src = os.path.join(setup_dir, "schema_samba4.ldif") schema_data += open(src, 'r').read() - schema_data = substitute_var(schema_data, {"SCHEMADN": subobj.schemadn}) + schema_data = substitute_var(schema_data, {"SCHEMADN": schemadn}) src = os.path.join(setup_dir, "provision_schema_basedn_modify.ldif") head_data = open(src, 'r').read() head_data = substitute_var(head_data, { - "SCHEMADN": subobj.schemadn, - "NETBIOSNAME": subobj.netbiosname, - "CONFIGDN": subobj.configdn, - "DEFAULTSITE": subobj.defaultsite}) + "SCHEMADN": schemadn, + "NETBIOSNAME": netbiosname, + "CONFIGDN": configdn, + "DEFAULTSITE": DEFAULTSITE}) samdb.attach_schema_from_ldif(head_data, schema_data) -- cgit From 86f91db7d5c84526b3fbd4369d7a56dc0f057b4c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 19 Dec 2007 23:27:31 +0100 Subject: r26536: More tests for provisioning code. (This used to be commit 43c8bfeedf06ce806c524a28fa72c643f6db60f4) --- source4/scripting/python/samba/provision.py | 6 ------ 1 file changed, 6 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index c9cb457b4a..f3fc138e6b 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -73,11 +73,6 @@ def findnss(nssfn, *names): raise Exception("Unable to find user/group for %s" % arguments[1]) -def hostname(): - """return first part of hostname.""" - return gethostname().split(".")[0] - - def open_ldb(session_info, credentials, lp, dbname): assert session_info is not None try: @@ -742,7 +737,6 @@ def provision_dns(setup_dir, paths, session_info, }) - def provision_ldapbase(setup_dir, message, paths): """Write out a DNS zone file, from the info in the current database.""" message("Setting up LDAP base entry: %s" % domaindn) -- cgit From c2fffa8335ac68ff70de52f9fc80fb49e5d6d686 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 19 Dec 2007 23:27:38 +0100 Subject: r26538: Pass path generation function around rather than base directory. (This used to be commit 5f921af41e4dcd6844f6a662d56bd27c4e76ff88) --- source4/scripting/python/samba/provision.py | 256 +++++++++++++--------------- 1 file changed, 117 insertions(+), 139 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index f3fc138e6b..90f7cd0697 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -21,7 +21,7 @@ from samba import Ldb, substitute_var, valid_netbios_name from samba.samdb import SamDB import security from ldb import Dn, SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ - LDB_ERR_NO_SUCH_OBJECT, timestring + LDB_ERR_NO_SUCH_OBJECT, timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE DEFAULTSITE = "Default-First-Site-Name" @@ -58,7 +58,7 @@ def install_ok(lp, session_info, credentials): return False ldb = Ldb(lp.get("sam database"), session_info=session_info, credentials=credentials, lp=lp) - if len(ldb.search("(cn=Administrator)")) != 1: + if len(ldb.search(ldb.Dn("(cn=Administrator)"))) != 1: return False return True @@ -85,62 +85,56 @@ def open_ldb(session_info, credentials, lp, dbname): lp=lp) -def setup_add_ldif(ldb, setup_dir, ldif, subst_vars=None): +def setup_add_ldif(ldb, ldif_path, subst_vars=None): """Setup a ldb in the private dir.""" - assert isinstance(ldif, str) - assert isinstance(setup_dir, str) - src = os.path.join(setup_dir, ldif) + assert isinstance(ldif_path, str) - data = open(src, 'r').read() + data = open(ldif_path, 'r').read() if subst_vars is not None: data = substitute_var(data, subst_vars) assert "${" not in data - for msg in ldb.parse_ldif(data): - ldb.add(msg[1]) + ldb.load_ldif_add(data) -def setup_modify_ldif(ldb, setup_dir, ldif, substvars=None): +def setup_modify_ldif(ldb, ldif_path, substvars=None): """Modify a ldb in the private dir. :param ldb: LDB object. - :param setup_dir: Setup directory. - :param ldif: LDIF file path. + :param ldif_path: LDIF file path. :param substvars: Optional dictionary with substitution variables. """ - src = os.path.join(setup_dir, ldif) - - data = open(src, 'r').read() + data = open(ldif_path, 'r').read() if substvars is not None: data = substitute_var(data, substvars) assert "${" not in data for (changetype, msg) in ldb.parse_ldif(data): + assert changetype == CHANGETYPE_MODIFY ldb.modify(msg) -def setup_ldb(ldb, setup_dir, ldif, subst_vars=None): +def setup_ldb(ldb, ldif_path, subst_vars): assert ldb is not None ldb.transaction_start() try: - setup_add_ldif(ldb, setup_dir, ldif, subst_vars) + setup_add_ldif(ldb, ldif_path, subst_vars) except: ldb.transaction_cancel() raise ldb.transaction_commit() -def setup_file(setup_dir, template, fname, substvars): +def setup_file(template, fname, substvars): """Setup a file in the private dir.""" f = fname - src = os.path.join(setup_dir, template) if os.path.exists(f): os.unlink(f) - data = open(src, 'r').read() + data = open(template, 'r').read() if substvars: data = substitute_var(data, substvars) assert not "${" in data @@ -218,40 +212,44 @@ def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users, def provision_become_dc(setup_dir, message, paths, lp, session_info, credentials): assert session_info is not None + erase = False + + def setup_path(file): + return os.path.join(setup_dir, file) + os.path.unlink(paths.samdb) - message("Setting up templates into %s" % paths.templates) - setup_templatesdb(paths.templates, setup_dir, session_info, + message("Setting up templates db") + setup_templatesdb(paths.templates, setup_path, session_info, credentials, lp) # Also wipes the database - message("Setting up samdb") - os.path.unlink(paths.samdb) + message("Setting up sam.ldb") samdb = SamDB(paths.samdb, credentials=credentials, session_info=session_info, lp=lp) - samdb.erase() - message("Setting up %s partitions" % paths.samdb) - setup_samdb_partitions(samdb, setup_dir, schemadn, - configdn, domaindn) + message("Setting up sam.ldb partitions") + setup_samdb_partitions(samdb, setup_path, schemadn, + configdn, domaindn) samdb = SamDB(paths.samdb, credentials=credentials, session_info=session_info, lp=lp) ldb.transaction_start() try: - message("Setting up %s attributes" % paths.samdb) - setup_add_ldif(samdb, setup_dir, "provision_init.ldif") + message("Setting up sam.ldb attributes") + samdb.load_ldif_file_add(setup_path("provision_init.ldif")) - message("Setting up %s rootDSE" % paths.samdb) - setup_samdb_rootdse(samdb, setup_dir, schemadn, domaindn, + message("Setting up sam.ldb rootDSE") + setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, dnsdomain, realm, rootdn, configdn, netbiosname) - message("Erasing data from partitions") - ldb_erase_partitions(domaindn, message, samdb, None) + if erase: + message("Erasing data from partitions") + samdb.erase_partitions() - message("Setting up %s indexes" % paths.samdb) - setup_add_ldif(samdb, setup_dir, "provision_index.ldif") + message("Setting up sam.ldb indexes") + samdb.load_ldif_file_add(setup_path("provision_index.ldif")) except: samdb.transaction_cancel() raise @@ -259,39 +257,39 @@ def provision_become_dc(setup_dir, message, paths, lp, session_info, samdb.transaction_commit() message("Setting up %s" % paths.secrets) - secrets_ldb = setup_secretsdb(paths.secrets, setup_dir, session_info, credentials, lp) - setup_ldb(secrets_ldb, setup_dir, "secrets_dc.ldif", + secrets_ldb = setup_secretsdb(paths.secrets, setup_path, session_info, credentials, lp) + setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"), { "MACHINEPASS_B64": b64encode(machinepass) }) -def setup_secretsdb(path, setup_dir, session_info, credentials, lp): +def setup_secretsdb(path, setup_path, session_info, credentials, lp): secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, lp=lp) secrets_ldb.erase() - setup_ldb(secrets_ldb, setup_dir, "secrets_init.ldif") - setup_ldb(secrets_ldb, setup_dir, "secrets.ldif") + secrets_ldb.load_ldif_file_add(setup_path("secrets_init.ldif")) + secrets_ldb.load_ldif_file_add(setup_path("secrets.ldif")) return secrets_ldb -def setup_templatesdb(path, setup_dir, session_info, credentials, lp): - templates_ldb = Ldb(path, session_info=session_info, +def setup_templatesdb(path, setup_path, session_info, credentials, lp): + templates_ldb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) templates_ldb.erase() - setup_ldb(templates_ldb, setup_dir, "provision_templates.ldif", None) + templates_ldb.load_ldif_file_add(setup_path("provision_templates.ldif")) -def setup_registry(path, setup_dir, session_info, credentials, lp): +def setup_registry(path, setup_path, session_info, credentials, lp): reg = registry.Registry() hive = registry.Hive(path, session_info=session_info, credentials=credentials, lp_ctx=lp) reg.mount_hive(hive, "HKEY_LOCAL_MACHINE") - provision_reg = os.path.join(setup_dir, "provision.reg") + provision_reg = setup_path("provision.reg") assert os.path.exists(provision_reg) reg.apply_patchfile(provision_reg) -def setup_samdb_rootdse(samdb, setup_dir, schemadn, domaindn, hostname, +def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, dnsdomain, realm, rootdn, configdn, netbiosname): - setup_add_ldif(samdb, setup_dir, "provision_rootdse_add.ldif", { + setup_add_ldif(samdb, setup_path("provision_rootdse_add.ldif"), { "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, "DNSDOMAIN": dnsdomain, @@ -305,7 +303,7 @@ def setup_samdb_rootdse(samdb, setup_dir, schemadn, domaindn, hostname, }) -def setup_samdb_partitions(samdb, setup_dir, schemadn, configdn, domaindn): +def setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn): #Add modules to the list to activate them by default #beware often order is important # @@ -335,7 +333,7 @@ def setup_samdb_partitions(samdb, setup_dir, schemadn, configdn, domaindn): modules_list2 = ["show_deleted", "partition"] - setup_ldb(samdb, setup_dir, "provision_partitions.ldif", { + setup_add_ldif(samdb, setup_path("provision_partitions.ldif"), { "SCHEMADN": schemadn, "SCHEMADN_LDB": "schema.ldb", "SCHEMADN_MOD2": ",objectguid", @@ -367,6 +365,11 @@ def provision(lp, setup_dir, message, blank, paths, session_info, :note: caution, this wipes all existing data! """ + def setup_path(file): + return os.path.join(setup_dir, file) + + erase = False + if domainsid is None: domainsid = security.random_sid() if policyguid is None: @@ -438,6 +441,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, rdn_dc = domaindn.split(",")[0][len("DC="):] + message("set DOMAIN SID: %s" % str(domainsid)) message("Provisioning for %s in realm %s" % (domain, realm)) message("Using administrator password: %s" % adminpass) @@ -452,7 +456,14 @@ def provision(lp, setup_dir, message, blank, paths, session_info, smbconfsuffix = "member" else: assert "Invalid server role setting: %s" % serverrole - setup_file(setup_dir, "provision.smb.conf.%s" % smbconfsuffix, paths.smbconf) + setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), paths.smbconf, { + "HOSTNAME": hostname, + "DOMAIN_CONF": domain, + "REALM_CONF": realm, + "SERVERROLE": serverrole, + "NETLOGONPATH": paths.netlogon, + "SYSVOLPATH": paths.sysvol, + }) lp.reload() # only install a new shares config db if there is none @@ -460,27 +471,26 @@ def provision(lp, setup_dir, message, blank, paths, session_info, message("Setting up share.ldb") share_ldb = Ldb(paths.shareconf, session_info=session_info, credentials=credentials, lp=lp) - setup_ldb(share_ldb, setup_dir, "share.ldif") + share_ldb.load_ldif_file_add(setup_path("share.ldif")) - message("Setting up %s" % paths.secrets) - secrets_ldb = setup_secretsdb(paths.secrets, setup_dir, session_info=session_info, + message("Setting up secrets.ldb") + secrets_ldb = setup_secretsdb(paths.secrets, setup_path, session_info=session_info, credentials=credentials, lp=lp) - message("Setting up registry") + message("Setting up the registry") # FIXME: Still fails for some reason - #setup_registry(paths.hklm, setup_dir, session_info, + #setup_registry(paths.hklm, setup_path, session_info, # credentials=credentials, lp=lp) - message("Setting up templates into %s" % paths.templates) - setup_templatesdb(paths.templates, setup_dir, session_info=session_info, + message("Setting up templates db") + setup_templatesdb(paths.templates, setup_path, session_info=session_info, credentials=credentials, lp=lp) samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) - samdb.erase() message("Setting up sam.ldb partitions") - setup_samdb_partitions(samdb, setup_dir, schemadn, configdn, domaindn) + setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn) samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) @@ -488,15 +498,16 @@ def provision(lp, setup_dir, message, blank, paths, session_info, samdb.transaction_start() try: message("Setting up sam.ldb attributes") - setup_add_ldif(samdb, setup_dir, "provision_init.ldif") + samdb.load_ldif_file_add(setup_path("provision_init.ldif")) message("Setting up sam.ldb rootDSE") - setup_samdb_rootdse(samdb, setup_dir, schemadn, domaindn, + setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, dnsdomain, realm, rootdn, configdn, netbiosname) - message("Erasing data from partitions") - ldb_erase_partitions(domaindn, message, samdb, ldapbackend) + if erase: + message("Erasing data from partitions") + samdb.erase_partitions() except: samdb.transaction_cancel() raise @@ -507,13 +518,13 @@ def provision(lp, setup_dir, message, blank, paths, session_info, samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) samdb.set_domain_sid(domainsid) - load_schema(setup_dir, samdb, schemadn, netbiosname, configdn) + load_schema(setup_path, samdb, schemadn, netbiosname, configdn) samdb.transaction_start() try: message("Adding DomainDN: %s (permitted to fail)" % domaindn) - setup_add_ldif(samdb, setup_dir, "provision_basedn.ldif", { + setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), { "DOMAINDN": domaindn, "ACI": aci, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", @@ -526,7 +537,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, else: domainguid_mod = "" - setup_modify_ldif(samdb, setup_dir, "provision_basedn_modify.ldif", { + setup_modify_ldif(samdb, setup_path("provision_basedn_modify.ldif"), { "RDN_DC": rdn_dc, "LDAPTIME": timestring(int(time.time())), "DOMAINSID": str(domainsid), @@ -540,25 +551,25 @@ def provision(lp, setup_dir, message, blank, paths, session_info, }) message("Adding configuration container (permitted to fail)") - setup_add_ldif(samdb, setup_dir, "provision_configuration_basedn.ldif", { + setup_add_ldif(samdb, setup_path("provision_configuration_basedn.ldif"), { "CONFIGDN": configdn, "ACI": aci, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", }) message("Modifying configuration container") - setup_modify_ldif(samdb, setup_dir, "provision_configuration_basedn_modify.ldif", { + setup_modify_ldif(samdb, setup_path("provision_configuration_basedn_modify.ldif"), { "CONFIGDN": configdn, "SCHEMADN": schemadn, }) message("Adding schema container (permitted to fail)") - setup_add_ldif(samdb, setup_dir, "provision_schema_basedn.ldif", { + setup_add_ldif(samdb, setup_path("provision_schema_basedn.ldif"), { "SCHEMADN": schemadn, "ACI": aci, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" }) message("Modifying schema container") - setup_modify_ldif(samdb, setup_dir, "provision_schema_basedn_modify.ldif", { + setup_modify_ldif(samdb, setup_path("provision_schema_basedn_modify.ldif"), { "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, "DEFAULTSITE": DEFAULTSITE, @@ -566,14 +577,14 @@ def provision(lp, setup_dir, message, blank, paths, session_info, }) message("Setting up sam.ldb Samba4 schema") - setup_add_ldif(samdb, setup_dir, "schema_samba4.ldif", + setup_add_ldif(samdb, setup_path("schema_samba4.ldif"), {"SCHEMADN": schemadn }) message("Setting up sam.ldb AD schema") - setup_add_ldif(samdb, setup_dir, "schema.ldif", + setup_add_ldif(samdb, setup_path("schema.ldif"), {"SCHEMADN": schemadn}) message("Setting up sam.ldb configuration data") - setup_add_ldif(samdb, setup_dir, "provision_configuration.ldif", { + setup_add_ldif(samdb, setup_path("provision_configuration.ldif"), { "CONFIGDN": configdn, "NETBIOSNAME": netbiosname, "DEFAULTSITE": DEFAULTSITE, @@ -584,22 +595,23 @@ def provision(lp, setup_dir, message, blank, paths, session_info, }) message("Setting up display specifiers") - setup_add_ldif(samdb, setup_dir, "display_specifiers.ldif", {"CONFIGDN": configdn}) + setup_add_ldif(samdb, setup_path("display_specifiers.ldif"), + {"CONFIGDN": configdn}) message("Adding users container (permitted to fail)") - setup_add_ldif(samdb, setup_dir, "provision_users_add.ldif", { + setup_add_ldif(samdb, setup_path("provision_users_add.ldif"), { "DOMAINDN": domaindn}) message("Modifying users container") - setup_modify_ldif(samdb, setup_dir, "provision_users_modify.ldif", { + setup_modify_ldif(samdb, setup_path("provision_users_modify.ldif"), { "DOMAINDN": domaindn}) message("Adding computers container (permitted to fail)") - setup_add_ldif(samdb, setup_dir, "provision_computers_add.ldif", { + setup_add_ldif(samdb, setup_path("provision_computers_add.ldif"), { "DOMAINDN": domaindn}) message("Modifying computers container") - setup_modify_ldif(samdb, setup_dir, "provision_computers_modify.ldif", { + setup_modify_ldif(samdb, setup_path("provision_computers_modify.ldif"), { "DOMAINDN": domaindn}) message("Setting up sam.ldb data") - setup_add_ldif(samdb, setup_dir, "provision.ldif", { + setup_add_ldif(samdb, setup_path("provision.ldif"), { "DOMAINDN": domaindn, "NETBIOSNAME": netbiosname, "DEFAULTSITE": DEFAULTSITE, @@ -622,7 +634,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, # samdb = open_ldb(info, paths.samdb, False) # message("Setting up sam.ldb users and groups") - setup_add_ldif(samdb, setup_dir, "provision_users.ldif", { + setup_add_ldif(samdb, setup_path("provision_users.ldif"), { "DOMAINDN": domaindn, "DOMAINSID": str(domainsid), "CONFIGDN": configdn, @@ -637,7 +649,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, else: hostguid_add = "" - setup_add_ldif(samdb, setup_dir, "provision_self_join.ldif", { + setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), { "CONFIGDN": configdn, "SCHEMADN": schemadn, "DOMAINDN": domaindn, @@ -651,7 +663,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, "DOMAIN": domain, "HOSTGUID_ADD": hostguid_add, "DNSDOMAIN": dnsdomain}) - setup_add_ldif(samdb, setup_dir, "provision_group_policy.ldif", { + setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), { "POLICYGUID": policyguid, "DNSDOMAIN": dnsdomain, "DOMAINSID": str(domainsid), @@ -662,7 +674,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "User"), 0755) if not os.path.isdir(paths.netlogon): os.makedirs(paths.netlogon, 0755) - setup_ldb(secrets_ldb, setup_dir, "secrets_dc.ldif", { + setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"), { "MACHINEPASS_B64": b64encode(machinepass), "DOMAIN": domain, "REALM": realm, @@ -682,10 +694,10 @@ def provision(lp, setup_dir, message, blank, paths, session_info, backup=backup) message("Setting up sam.ldb index") - setup_add_ldif(samdb, setup_dir, "provision_index.ldif") + samdb.load_ldif_file_add(setup_path("provision_index.ldif")) message("Setting up sam.ldb rootDSE marking as syncronized") - setup_modify_ldif(samdb, setup_dir, "provision_rootdse_modify.ldif") + setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif")) except: samdb.transaction_cancel() raise @@ -693,38 +705,33 @@ def provision(lp, setup_dir, message, blank, paths, session_info, samdb.transaction_commit() message("Setting up phpLDAPadmin configuration") - create_phplpapdadmin_config(paths.phpldapadminconfig, setup_dir, paths.s4_ldapi_path) + create_phplpapdadmin_config(paths.phpldapadminconfig, setup_path, paths.s4_ldapi_path) message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) message("Setting up DNS zone: %s" % dnsdomain) - provision_dns(setup_dir, paths, session_info, credentials, lp, + create_zone_file(paths.dns, setup_path, samdb, hostname=hostname, hostip=hostip, dnsdomain=dnsdomain, domaindn=domaindn, dnspass=dnspass, realm=realm) message("Please install the zone located in %s into your DNS server" % paths.dns) -def create_phplpapdadmin_config(path, setup_dir, s4_ldapi_path): - setup_file(setup_dir, "phpldapadmin-config.php", +def create_phplpapdadmin_config(path, setup_path, s4_ldapi_path): + setup_file(setup_path("phpldapadmin-config.php"), path, {"S4_LDAPI_URI": "ldapi://%s" % s4_ldapi_path.replace("/", "%2F")}) -def provision_dns(setup_dir, paths, session_info, - credentials, lp, dnsdomain, domaindn, +def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, hostip, hostname, dnspass, realm): """Write out a DNS zone file, from the info in the current database.""" # connect to the sam - ldb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, - lp=lp) - # These values may have changed, due to an incoming SamSync, # or may not have been specified, so fetch them from the database - domainguid = str(ldb.searchone(Dn(ldb, domaindn), "objectGUID")) + domainguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID") + hostguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID" , + expression="(&(objectClass=computer)(cn=%s))" % hostname) - hostguid = str(ldb.searchone(Dn(ldb, domaindn), "objectGUID" , - expression="(&(objectClass=computer)(cn=%s))" % hostname)) - - setup_file(setup_dir, "provision.zone", paths.dns, { + setup_file(setup_path("provision.zone"), path, { "DNSPASS_B64": b64encode(dnspass), "HOSTNAME": hostname, "DNSDOMAIN": dnsdomain, @@ -744,13 +751,16 @@ def provision_ldapbase(setup_dir, message, paths): rdn_dc = rdns[0][len("DC="):] - setup_file(setup_dir, "provision_basedn.ldif", + def setup_path(file): + return os.path.join(setup_dir, file) + + setup_file(setup_path("provision_basedn.ldif"), paths.ldap_basedn_ldif) - setup_file(setup_dir, "provision_configuration_basedn.ldif", + setup_file(setup_path("provision_configuration_basedn.ldif"), paths.ldap_config_basedn_ldif) - setup_file(setup_dir, "provision_schema_basedn.ldif", + setup_file(setup_path("provision_schema_basedn.ldif"), paths.ldap_schema_basedn_ldif, { "SCHEMADN": schemadn, "ACI": "# no aci for local ldb", @@ -759,15 +769,12 @@ def provision_ldapbase(setup_dir, message, paths): 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") -def load_schema(setup_dir, samdb, schemadn, netbiosname, configdn): +def load_schema(setup_path, samdb, schemadn, netbiosname, configdn): """Load schema.""" - src = os.path.join(setup_dir, "schema.ldif") - schema_data = open(src, 'r').read() - src = os.path.join(setup_dir, "schema_samba4.ldif") - schema_data += open(src, 'r').read() + schema_data = open(setup_path("schema.ldif"), 'r').read() + schema_data += open(setup_path("schema_samba4.ldif"), 'r').read() schema_data = substitute_var(schema_data, {"SCHEMADN": schemadn}) - src = os.path.join(setup_dir, "provision_schema_basedn_modify.ldif") - head_data = open(src, 'r').read() + head_data = open(setup_path("provision_schema_basedn_modify.ldif"), 'r').read() head_data = substitute_var(head_data, { "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, @@ -803,33 +810,4 @@ def vampire(domain, session_info, credentials, message): raise Exception("Migration of remote domain to Samba failed: %s " % vampire_ctx.error_string) -def ldb_erase_partitions(domaindn, message, ldb, ldapbackend): - """Erase an ldb, removing all records.""" - assert ldb is not None - res = ldb.search(Dn(ldb, ""), SCOPE_BASE, "(objectClass=*)", - ["namingContexts"]) - assert len(res) == 1 - if not "namingContexts" in res[0]: - return - for basedn in res[0]["namingContexts"]: - anything = "(|(objectclass=*)(dn=*))" - previous_remaining = 1 - current_remaining = 0 - - if ldapbackend and (basedn == domaindn): - # Only delete objects that were created by provision - anything = "(objectcategory=*)" - - k = 0 - while ++k < 10 and (previous_remaining != current_remaining): - # and the rest - res2 = ldb.search(Dn(ldb, basedn), SCOPE_SUBTREE, anything, ["dn"]) - previous_remaining = current_remaining - current_remaining = len(res2) - for msg in res2: - try: - ldb.delete(msg.dn) - except LdbError, (_, text): - message("Unable to delete %s: %s" % (msg.dn, text)) - -- cgit From 109a903750e6bec865e402f02c5c457250594e55 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 20 Dec 2007 15:53:56 +0100 Subject: r26545: Sync output with ejs. (This used to be commit 48ceaa964327ed7094275780cc3c0767636bcb18) --- source4/scripting/python/samba/provision.py | 65 +++++++++++++---------------- 1 file changed, 30 insertions(+), 35 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 90f7cd0697..a4a9e7ac46 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -219,20 +219,19 @@ def provision_become_dc(setup_dir, message, paths, lp, session_info, os.path.unlink(paths.samdb) message("Setting up templates db") - setup_templatesdb(paths.templates, setup_path, session_info, - credentials, lp) + setup_templatesdb(paths.templates, setup_path, session_info=session_info, + credentials=credentials, lp=lp) # Also wipes the database message("Setting up sam.ldb") - samdb = SamDB(paths.samdb, credentials=credentials, - session_info=session_info, lp=lp) + samdb = SamDB(paths.samdb, session_info=session_info, + credentials=credentials, lp=lp) message("Setting up sam.ldb partitions") - setup_samdb_partitions(samdb, setup_path, schemadn, - configdn, domaindn) + setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn) - samdb = SamDB(paths.samdb, credentials=credentials, - session_info=session_info, lp=lp) + samdb = SamDB(paths.samdb, session_info=session_info, + credentials=credentials, lp=lp) ldb.transaction_start() try: @@ -257,12 +256,15 @@ def provision_become_dc(setup_dir, message, paths, lp, session_info, samdb.transaction_commit() message("Setting up %s" % paths.secrets) - secrets_ldb = setup_secretsdb(paths.secrets, setup_path, session_info, credentials, lp) + secrets_ldb = setup_secretsdb(paths.secrets, setup_path, session_info, + credentials, lp) setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"), { "MACHINEPASS_B64": b64encode(machinepass) }) def setup_secretsdb(path, setup_path, session_info, credentials, lp): + if os.path.exists(path): + os.unlink(path) secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, lp=lp) secrets_ldb.erase() secrets_ldb.load_ldif_file_add(setup_path("secrets_init.ldif")) @@ -474,8 +476,9 @@ def provision(lp, setup_dir, message, blank, paths, session_info, share_ldb.load_ldif_file_add(setup_path("share.ldif")) message("Setting up secrets.ldb") - secrets_ldb = setup_secretsdb(paths.secrets, setup_path, session_info=session_info, - credentials=credentials, lp=lp) + secrets_ldb = setup_secretsdb(paths.secrets, setup_path, + session_info=session_info, + credentials=credentials, lp=lp) message("Setting up the registry") # FIXME: Still fails for some reason @@ -486,6 +489,8 @@ def provision(lp, setup_dir, message, blank, paths, session_info, setup_templatesdb(paths.templates, setup_path, session_info=session_info, credentials=credentials, lp=lp) + # Also wipes the database + message("Setting up sam.ldb") samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) @@ -619,20 +624,6 @@ def provision(lp, setup_dir, message, blank, paths, session_info, }) if not blank: - - # message("Activate schema module") - # setup_modify_ldif("schema_activation.ldif", info, samdb, False) - # - # // (hack) Reload, now we have the schema loaded. - # commit_ok = samdb.transaction_commit() - # if (!commit_ok) { - # message("samdb commit failed: " + samdb.errstring() + "\n") - # assert(commit_ok) - # } - # samdb.close() - # - # samdb = open_ldb(info, paths.samdb, False) - # message("Setting up sam.ldb users and groups") setup_add_ldif(samdb, setup_path("provision_users.ldif"), { "DOMAINDN": domaindn, @@ -696,7 +687,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, message("Setting up sam.ldb index") samdb.load_ldif_file_add(setup_path("provision_index.ldif")) - message("Setting up sam.ldb rootDSE marking as syncronized") + message("Setting up sam.ldb rootDSE marking as synchronized") setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif")) except: samdb.transaction_cancel() @@ -709,10 +700,21 @@ def provision(lp, setup_dir, message, blank, paths, session_info, message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) + samdb = SamDB(paths.samdb, session_info=session_info, + credentials=credentials, lp=lp) + + domainguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID") + assert isinstance(domainguid, str) + hostguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID", + expression="(&(objectClass=computer)(cn=%s))" % hostname, + scope=SCOPE_SUBTREE) + assert isinstance(hostguid, str) + message("Setting up DNS zone: %s" % dnsdomain) create_zone_file(paths.dns, setup_path, samdb, hostname=hostname, hostip=hostip, dnsdomain=dnsdomain, - domaindn=domaindn, dnspass=dnspass, realm=realm) + domaindn=domaindn, dnspass=dnspass, realm=realm, + domainguid=domainguid, hostguid=hostguid) message("Please install the zone located in %s into your DNS server" % paths.dns) def create_phplpapdadmin_config(path, setup_path, s4_ldapi_path): @@ -721,16 +723,9 @@ def create_phplpapdadmin_config(path, setup_path, s4_ldapi_path): def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, - hostip, hostname, dnspass, realm): + hostip, hostname, dnspass, realm, domainguid, hostguid): """Write out a DNS zone file, from the info in the current database.""" - # connect to the sam - # These values may have changed, due to an incoming SamSync, - # or may not have been specified, so fetch them from the database - domainguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID") - hostguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID" , - expression="(&(objectClass=computer)(cn=%s))" % hostname) - setup_file(setup_path("provision.zone"), path, { "DNSPASS_B64": b64encode(dnspass), "HOSTNAME": hostname, -- cgit From 30ce895e0c75c50bbe510b6a3685c7e1f217b919 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 22 Dec 2007 00:47:36 -0600 Subject: r26559: Make the provision function a bit smaller. (This used to be commit a1175231a58c60f32574816643dafc78ff867161) --- source4/scripting/python/samba/provision.py | 346 +++++++++++++++------------- 1 file changed, 182 insertions(+), 164 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index a4a9e7ac46..f516e73893 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -354,150 +354,21 @@ def setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn): }) - -def provision(lp, setup_dir, message, blank, paths, session_info, - credentials, ldapbackend, realm=None, domain=None, hostname=None, - hostip=None, domainsid=None, hostguid=None, adminpass=None, - krbtgtpass=None, domainguid=None, policyguid=None, - invocationid=None, machinepass=None, dnspass=None, root=None, - nobody=None, nogroup=None, users=None, wheel=None, backup=None, - aci=None, serverrole=None): - """Provision samba4 - - :note: caution, this wipes all existing data! - """ - - def setup_path(file): - return os.path.join(setup_dir, file) - - erase = False - - if domainsid is None: - domainsid = security.random_sid() - if policyguid is None: - policyguid = uuid.random() - if invocationid is None: - invocationid = uuid.random() - if adminpass is None: - adminpass = misc.random_password(12) - if krbtgtpass is None: - krbtgtpass = misc.random_password(12) - if machinepass is None: - machinepass = misc.random_password(12) - if dnspass is None: - dnspass = misc.random_password(12) - if root is None: - root = findnss(pwd.getpwnam, "root")[4] - if nobody is None: - nobody = findnss(pwd.getpwnam, "nobody")[4] - if nogroup is None: - nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] - if users is None: - users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", "usr")[2] - if wheel is None: - wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[2] - if backup is None: - backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[2] - if aci is None: - aci = "# no aci for local ldb" - if serverrole is None: - serverrole = lp.get("server role") - - if realm is None: - realm = lp.get("realm") - else: - if lp.get("realm").upper() != realm.upper(): - raise Error("realm '%s' in smb.conf must match chosen realm '%s'\n" % - (lp.get("realm"), realm)) - - assert realm is not None - realm = realm.upper() - - if domain is None: - domain = lp.get("workgroup") - else: - if lp.get("workgroup").upper() != domain.upper(): - raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'\n", - lp.get("workgroup"), domain) - - assert domain is not None - domain = domain.upper() - if not valid_netbios_name(domain): - raise InvalidNetbiosName(domain) - - if hostname is None: - hostname = gethostname().split(".")[0].lower() - - if hostip is None: - hostip = gethostbyname(hostname) - - netbiosname = hostname.upper() - if not valid_netbios_name(netbiosname): - raise InvalidNetbiosName(netbiosname) - - dnsdomain = realm.lower() - domaindn = "DC=" + dnsdomain.replace(".", ",DC=") - rootdn = domaindn - configdn = "CN=Configuration," + rootdn - schemadn = "CN=Schema," + configdn - - rdn_dc = domaindn.split(",")[0][len("DC="):] - - message("set DOMAIN SID: %s" % str(domainsid)) - message("Provisioning for %s in realm %s" % (domain, realm)) - message("Using administrator password: %s" % adminpass) - - assert paths.smbconf is not None - - # only install a new smb.conf if there isn't one there already - if not os.path.exists(paths.smbconf): - message("Setting up smb.conf") - if serverrole == "domain controller": - smbconfsuffix = "dc" - elif serverrole == "member": - smbconfsuffix = "member" - else: - assert "Invalid server role setting: %s" % serverrole - setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), paths.smbconf, { - "HOSTNAME": hostname, - "DOMAIN_CONF": domain, - "REALM_CONF": realm, - "SERVERROLE": serverrole, - "NETLOGONPATH": paths.netlogon, - "SYSVOLPATH": paths.sysvol, - }) - lp.reload() - - # only install a new shares config db if there is none - if not os.path.exists(paths.shareconf): - message("Setting up share.ldb") - share_ldb = Ldb(paths.shareconf, session_info=session_info, - credentials=credentials, lp=lp) - share_ldb.load_ldif_file_add(setup_path("share.ldif")) - - message("Setting up secrets.ldb") - secrets_ldb = setup_secretsdb(paths.secrets, setup_path, - session_info=session_info, - credentials=credentials, lp=lp) - - message("Setting up the registry") - # FIXME: Still fails for some reason - #setup_registry(paths.hklm, setup_path, session_info, - # credentials=credentials, lp=lp) - - message("Setting up templates db") - setup_templatesdb(paths.templates, setup_path, session_info=session_info, - credentials=credentials, lp=lp) - +def setup_samdb(path, setup_path, session_info, credentials, lp, + schemadn, configdn, domaindn, dnsdomain, realm, + netbiosname, message, hostname, rootdn, erase, + domainsid, aci, rdn_dc, domainguid, policyguid, + domainname, blank, adminpass, krbtgtpass, + machinepass, hostguid, invocationid, dnspass): # Also wipes the database message("Setting up sam.ldb") - samdb = SamDB(paths.samdb, session_info=session_info, + samdb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) message("Setting up sam.ldb partitions") setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn) - samdb = SamDB(paths.samdb, session_info=session_info, + samdb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) samdb.transaction_start() @@ -520,7 +391,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, samdb.transaction_commit() message("Pre-loading the Samba 4 and AD schema") - samdb = SamDB(paths.samdb, session_info=session_info, + samdb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) samdb.set_domain_sid(domainsid) load_schema(setup_path, samdb, schemadn, netbiosname, configdn) @@ -594,7 +465,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, "NETBIOSNAME": netbiosname, "DEFAULTSITE": DEFAULTSITE, "DNSDOMAIN": dnsdomain, - "DOMAIN": domain, + "DOMAIN": domainname, "SCHEMADN": schemadn, "DOMAINDN": domaindn, }) @@ -651,7 +522,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, "MACHINEPASS_B64": b64encode(machinepass), "DNSPASS_B64": b64encode(dnspass), "REALM": realm, - "DOMAIN": domain, + "DOMAIN": domainname, "HOSTGUID_ADD": hostguid_add, "DNSDOMAIN": dnsdomain}) setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), { @@ -660,30 +531,6 @@ def provision(lp, setup_dir, message, blank, paths, session_info, "DOMAINSID": str(domainsid), "DOMAINDN": domaindn}) - os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}"), 0755) - os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "Machine"), 0755) - os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "User"), 0755) - if not os.path.isdir(paths.netlogon): - os.makedirs(paths.netlogon, 0755) - setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"), { - "MACHINEPASS_B64": b64encode(machinepass), - "DOMAIN": domain, - "REALM": realm, - "LDAPTIME": timestring(int(time.time())), - "DNSDOMAIN": dnsdomain, - "DOMAINSID": str(domainsid), - "SECRETS_KEYTAB": paths.keytab, - "NETBIOSNAME": netbiosname, - "SAM_LDB": paths.samdb, - "DNS_KEYTAB": paths.dns_keytab, - "DNSPASS_B64": b64encode(dnspass), - }) - - setup_name_mappings(samdb, str(domainsid), - domaindn, root=root, nobody=nobody, - nogroup=nogroup, wheel=wheel, users=users, - backup=backup) - message("Setting up sam.ldb index") samdb.load_ldif_file_add(setup_path("provision_index.ldif")) @@ -694,6 +541,177 @@ def provision(lp, setup_dir, message, blank, paths, session_info, raise samdb.transaction_commit() + return samdb + + +def provision(lp, setup_dir, message, blank, paths, session_info, + credentials, ldapbackend, realm=None, domain=None, hostname=None, + hostip=None, domainsid=None, hostguid=None, adminpass=None, + krbtgtpass=None, domainguid=None, policyguid=None, + invocationid=None, machinepass=None, dnspass=None, root=None, + nobody=None, nogroup=None, users=None, wheel=None, backup=None, + aci=None, serverrole=None): + """Provision samba4 + + :note: caution, this wipes all existing data! + """ + + def setup_path(file): + return os.path.join(setup_dir, file) + + erase = False + + if domainsid is None: + domainsid = security.random_sid() + if policyguid is None: + policyguid = uuid.random() + if invocationid is None: + invocationid = uuid.random() + if adminpass is None: + adminpass = misc.random_password(12) + if krbtgtpass is None: + krbtgtpass = misc.random_password(12) + if machinepass is None: + machinepass = misc.random_password(12) + if dnspass is None: + dnspass = misc.random_password(12) + if root is None: + root = findnss(pwd.getpwnam, "root")[4] + if nobody is None: + nobody = findnss(pwd.getpwnam, "nobody")[4] + if nogroup is None: + nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] + if users is None: + users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", "usr")[2] + if wheel is None: + wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[2] + if backup is None: + backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[2] + if aci is None: + aci = "# no aci for local ldb" + if serverrole is None: + serverrole = lp.get("server role") + + if realm is None: + realm = lp.get("realm") + else: + if lp.get("realm").upper() != realm.upper(): + raise Error("realm '%s' in smb.conf must match chosen realm '%s'\n" % + (lp.get("realm"), realm)) + + assert realm is not None + realm = realm.upper() + + if domain is None: + domain = lp.get("workgroup") + else: + if lp.get("workgroup").upper() != domain.upper(): + raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'\n", + lp.get("workgroup"), domain) + + assert domain is not None + domain = domain.upper() + if not valid_netbios_name(domain): + raise InvalidNetbiosName(domain) + + if hostname is None: + hostname = gethostname().split(".")[0].lower() + + if hostip is None: + hostip = gethostbyname(hostname) + + netbiosname = hostname.upper() + if not valid_netbios_name(netbiosname): + raise InvalidNetbiosName(netbiosname) + + dnsdomain = realm.lower() + domaindn = "DC=" + dnsdomain.replace(".", ",DC=") + rootdn = domaindn + configdn = "CN=Configuration," + rootdn + schemadn = "CN=Schema," + configdn + + rdn_dc = domaindn.split(",")[0][len("DC="):] + + message("set DOMAIN SID: %s" % str(domainsid)) + message("Provisioning for %s in realm %s" % (domain, realm)) + message("Using administrator password: %s" % adminpass) + + assert paths.smbconf is not None + + # only install a new smb.conf if there isn't one there already + if not os.path.exists(paths.smbconf): + message("Setting up smb.conf") + if serverrole == "domain controller": + smbconfsuffix = "dc" + elif serverrole == "member": + smbconfsuffix = "member" + else: + assert "Invalid server role setting: %s" % serverrole + setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), paths.smbconf, { + "HOSTNAME": hostname, + "DOMAIN_CONF": domain, + "REALM_CONF": realm, + "SERVERROLE": serverrole, + "NETLOGONPATH": paths.netlogon, + "SYSVOLPATH": paths.sysvol, + }) + lp.reload() + + # only install a new shares config db if there is none + if not os.path.exists(paths.shareconf): + message("Setting up share.ldb") + share_ldb = Ldb(paths.shareconf, session_info=session_info, + credentials=credentials, lp=lp) + share_ldb.load_ldif_file_add(setup_path("share.ldif")) + + message("Setting up secrets.ldb") + secrets_ldb = setup_secretsdb(paths.secrets, setup_path, + session_info=session_info, + credentials=credentials, lp=lp) + + message("Setting up the registry") + # FIXME: Still fails for some reason + #setup_registry(paths.hklm, setup_path, session_info, + # credentials=credentials, lp=lp) + + message("Setting up templates db") + setup_templatesdb(paths.templates, setup_path, session_info=session_info, + credentials=credentials, lp=lp) + + samdb = setup_samdb(paths.samdb, setup_path, session_info=session_info, credentials=credentials, + lp=lp, schemadn=schemadn, configdn=configdn, domaindn=domaindn, + dnsdomain=dnsdomain, netbiosname=netbiosname, realm=realm, message=message, + hostname=hostname, rootdn=rootdn, erase=erase, domainsid=domainsid, aci=aci, + rdn_dc=rdn_dc, domainguid=domainguid, policyguid=policyguid, + domainname=domain, blank=blank, adminpass=adminpass, krbtgtpass=krbtgtpass, + hostguid=hostguid, invocationid=invocationid, machinepass=machinepass, + dnspass=dnspass) + + if lp.get("server role") == "domain controller": + os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}"), 0755) + os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "Machine"), 0755) + os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "User"), 0755) + if not os.path.isdir(paths.netlogon): + os.makedirs(paths.netlogon, 0755) + setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"), { + "MACHINEPASS_B64": b64encode(machinepass), + "DOMAIN": domain, + "REALM": realm, + "LDAPTIME": timestring(int(time.time())), + "DNSDOMAIN": dnsdomain, + "DOMAINSID": str(domainsid), + "SECRETS_KEYTAB": paths.keytab, + "NETBIOSNAME": netbiosname, + "SAM_LDB": paths.samdb, + "DNS_KEYTAB": paths.dns_keytab, + "DNSPASS_B64": b64encode(dnspass), + }) + + if not blank: + setup_name_mappings(samdb, str(domainsid), + domaindn, root=root, nobody=nobody, + nogroup=nogroup, wheel=wheel, users=users, + backup=backup) message("Setting up phpLDAPadmin configuration") create_phplpapdadmin_config(paths.phpldapadminconfig, setup_path, paths.s4_ldapi_path) -- cgit From b7ffc3b404fbe3cf759e743c23e7bdbf75e71286 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 22 Dec 2007 02:26:38 -0600 Subject: r26562: Fix provisioning using Python. (This used to be commit b07ca944ba62a3f3de58c06b66533c0953a32de9) --- source4/scripting/python/samba/provision.py | 73 +++++++++++++++++------------ 1 file changed, 43 insertions(+), 30 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index f516e73893..65094ecfac 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -354,6 +354,36 @@ def setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn): }) +def setup_self_join(samdb, configdn, schemadn, domaindn, + netbiosname, hostname, dnsdomain, machinepass, dnspass, + realm, domainname, domainsid, invocationid, setup_path, + policyguid, hostguid=None): + if hostguid is not None: + hostguid_add = "objectGUID: %s" % hostguid + else: + hostguid_add = "" + + setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), { + "CONFIGDN": configdn, + "SCHEMADN": schemadn, + "DOMAINDN": domaindn, + "INVOCATIONID": invocationid, + "NETBIOSNAME": netbiosname, + "DEFAULTSITE": DEFAULTSITE, + "DNSNAME": "%s.%s" % (hostname, dnsdomain), + "MACHINEPASS_B64": b64encode(machinepass), + "DNSPASS_B64": b64encode(dnspass), + "REALM": realm, + "DOMAIN": domainname, + "HOSTGUID_ADD": hostguid_add, + "DNSDOMAIN": dnsdomain}) + setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), { + "POLICYGUID": policyguid, + "DNSDOMAIN": dnsdomain, + "DOMAINSID": str(domainsid), + "DOMAINDN": domaindn}) + + def setup_samdb(path, setup_path, session_info, credentials, lp, schemadn, configdn, domaindn, dnsdomain, realm, netbiosname, message, hostname, rootdn, erase, @@ -506,30 +536,11 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, if lp.get("server role") == "domain controller": message("Setting up self join") - if hostguid is not None: - hostguid_add = "objectGUID: %s" % hostguid - else: - hostguid_add = "" - - setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), { - "CONFIGDN": configdn, - "SCHEMADN": schemadn, - "DOMAINDN": domaindn, - "INVOCATIONID": invocationid, - "NETBIOSNAME": netbiosname, - "DEFAULTSITE": DEFAULTSITE, - "DNSNAME": "%s.%s" % (hostname, dnsdomain), - "MACHINEPASS_B64": b64encode(machinepass), - "DNSPASS_B64": b64encode(dnspass), - "REALM": realm, - "DOMAIN": domainname, - "HOSTGUID_ADD": hostguid_add, - "DNSDOMAIN": dnsdomain}) - setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), { - "POLICYGUID": policyguid, - "DNSDOMAIN": dnsdomain, - "DOMAINSID": str(domainsid), - "DOMAINDN": domaindn}) + setup_self_join(samdb, configdn=configdn, schemadn=schemadn, domaindn=domaindn, + invocationid=invocationid, dnspass=dnspass, netbiosname=netbiosname, + dnsdomain=dnsdomain, realm=realm, machinepass=machinepass, + domainname=domainname, domainsid=domainsid, policyguid=policyguid, + hostname=hostname, hostguid=hostguid, setup_path=setup_path) message("Setting up sam.ldb index") samdb.load_ldif_file_add(setup_path("provision_index.ldif")) @@ -693,6 +704,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "User"), 0755) if not os.path.isdir(paths.netlogon): os.makedirs(paths.netlogon, 0755) + secrets_ldb = Ldb(paths.secrets, session_info=session_info, credentials=credentials, lp=lp) setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"), { "MACHINEPASS_B64": b64encode(machinepass), "DOMAIN": domain, @@ -728,12 +740,13 @@ def provision(lp, setup_dir, message, blank, paths, session_info, scope=SCOPE_SUBTREE) assert isinstance(hostguid, str) - message("Setting up DNS zone: %s" % dnsdomain) - create_zone_file(paths.dns, setup_path, samdb, - hostname=hostname, hostip=hostip, dnsdomain=dnsdomain, - domaindn=domaindn, dnspass=dnspass, realm=realm, - domainguid=domainguid, hostguid=hostguid) - message("Please install the zone located in %s into your DNS server" % paths.dns) + if lp.get("server role") == "domain controller": + message("Setting up DNS zone: %s" % dnsdomain) + create_zone_file(paths.dns, setup_path, samdb, + hostname=hostname, hostip=hostip, dnsdomain=dnsdomain, + domaindn=domaindn, dnspass=dnspass, realm=realm, + domainguid=domainguid, hostguid=hostguid) + message("Please install the zone located in %s into your DNS server" % paths.dns) def create_phplpapdadmin_config(path, setup_path, s4_ldapi_path): setup_file(setup_path("phpldapadmin-config.php"), -- cgit From 09f820f0bd1a9fc7ffd171418ceb0e19df8e2e43 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 22 Dec 2007 05:02:57 -0600 Subject: r26564: More python bindings for registry code. (This used to be commit f40fad9827d0e9567224bc1e64ea91e610a07a3f) --- source4/scripting/python/samba/provision.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 65094ecfac..1d606d80e5 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -681,9 +681,8 @@ def provision(lp, setup_dir, message, blank, paths, session_info, credentials=credentials, lp=lp) message("Setting up the registry") - # FIXME: Still fails for some reason - #setup_registry(paths.hklm, setup_path, session_info, - # credentials=credentials, lp=lp) + setup_registry(paths.hklm, setup_path, session_info, + credentials=credentials, lp=lp) message("Setting up templates db") setup_templatesdb(paths.templates, setup_path, session_info=session_info, -- cgit From 249cc734cebfef31320ec10b05dbfaaaa39682ca Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 22 Dec 2007 05:03:02 -0600 Subject: r26565: Fix python registry bindings. 'PROVISION_PYTHON=yes make test' works now. (This used to be commit 485d1fa3d17fe6cc7a0ecd80e8bac42d173bbb19) --- source4/scripting/python/samba/provision.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 1d606d80e5..b5fe3eba9e 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -281,12 +281,12 @@ def setup_templatesdb(path, setup_path, session_info, credentials, lp): def setup_registry(path, setup_path, session_info, credentials, lp): reg = registry.Registry() - hive = registry.Hive(path, session_info=session_info, + hive = registry.open_ldb(path, session_info=session_info, credentials=credentials, lp_ctx=lp) reg.mount_hive(hive, "HKEY_LOCAL_MACHINE") provision_reg = setup_path("provision.reg") assert os.path.exists(provision_reg) - reg.apply_patchfile(provision_reg) + reg.diff_apply(provision_reg) def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, -- cgit From f053e385ff796914392d0eafa1e8756ff5ffdb18 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 22 Dec 2007 05:11:21 -0600 Subject: r26566: Fix member provision when using python. (This used to be commit e5573283df9e98bccc8eae227cf0f11367ecf084) --- source4/scripting/python/samba/provision.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index b5fe3eba9e..dcf567954a 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -729,17 +729,17 @@ def provision(lp, setup_dir, message, blank, paths, session_info, message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) - samdb = SamDB(paths.samdb, session_info=session_info, - credentials=credentials, lp=lp) + if lp.get("server role") == "domain controller": + samdb = SamDB(paths.samdb, session_info=session_info, + credentials=credentials, lp=lp) - domainguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID") - assert isinstance(domainguid, str) - hostguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID", - expression="(&(objectClass=computer)(cn=%s))" % hostname, - scope=SCOPE_SUBTREE) - assert isinstance(hostguid, str) + domainguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID") + assert isinstance(domainguid, str) + hostguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID", + expression="(&(objectClass=computer)(cn=%s))" % hostname, + scope=SCOPE_SUBTREE) + assert isinstance(hostguid, str) - if lp.get("server role") == "domain controller": message("Setting up DNS zone: %s" % dnsdomain) create_zone_file(paths.dns, setup_path, samdb, hostname=hostname, hostip=hostip, dnsdomain=dnsdomain, -- cgit From aa0a06f13c44e0eca0b3f2f0c34f0f7995b87159 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 23 Dec 2007 19:19:41 -0600 Subject: r26570: - Trim size of the swig-generated Python bindings by removing a bunch of {}'s. - Start working on Python equivalents for various EJS tests. - Fix regression in argument order for reg_diff_apply() in EJS bindings. (This used to be commit c550c03372cb260b78f6a6c132e70571bc4cb852) --- source4/scripting/python/samba/provision.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index dcf567954a..a4e6c6a214 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -111,9 +111,7 @@ def setup_modify_ldif(ldb, ldif_path, substvars=None): assert "${" not in data - for (changetype, msg) in ldb.parse_ldif(data): - assert changetype == CHANGETYPE_MODIFY - ldb.modify(msg) + ldb.modify_ldif(data) def setup_ldb(ldb, ldif_path, subst_vars): -- cgit From 533cc583ed20efdfd6bee60f86d16fef3942898b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Tue, 25 Dec 2007 16:36:44 -0600 Subject: r26596: Fixed upgrade.py. Added blackbox tests for provision and upgrade Python scripts. Clean up temporary files created by the Python tests. (This used to be commit 2227fb6df62240cae64d27a1920d878316f819fc) --- source4/scripting/python/samba/provision.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index a4e6c6a214..c4a3bb7fd6 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -95,7 +95,7 @@ def setup_add_ldif(ldb, ldif_path, subst_vars=None): assert "${" not in data - ldb.load_ldif_add(data) + ldb.add_ldif(data) def setup_modify_ldif(ldb, ldif_path, substvars=None): @@ -140,7 +140,7 @@ def setup_file(template, fname, substvars): open(f, 'w').write(data) -def provision_default_paths(lp, dnsdomain): +def provision_paths_from_lp(lp, dnsdomain): """Set the default paths for provisioning. :param lp: Loadparm context. @@ -605,7 +605,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, realm = lp.get("realm") else: if lp.get("realm").upper() != realm.upper(): - raise Error("realm '%s' in smb.conf must match chosen realm '%s'\n" % + raise Exception("realm '%s' in smb.conf must match chosen realm '%s'\n" % (lp.get("realm"), realm)) assert realm is not None -- cgit From 222262b54e74a01a66b3cbbea5502d4ce488905d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 27 Dec 2007 03:09:49 -0600 Subject: r26608: More improvements to the upgrade code. (This used to be commit 7ea06d91f602f770f55a1171174f11b922fed8e7) --- source4/scripting/python/samba/provision.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index c4a3bb7fd6..53eb1d618f 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -745,6 +745,8 @@ def provision(lp, setup_dir, message, blank, paths, session_info, domainguid=domainguid, hostguid=hostguid) message("Please install the zone located in %s into your DNS server" % paths.dns) + return domaindn + def create_phplpapdadmin_config(path, setup_path, s4_ldapi_path): setup_file(setup_path("phpldapadmin-config.php"), path, {"S4_LDAPI_URI": "ldapi://%s" % s4_ldapi_path.replace("/", "%2F")}) -- cgit From a61e25f17492bf78eb5d5ec962f0d174f94d8f84 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 28 Dec 2007 16:25:17 -0600 Subject: r26622: python: Update license version, clarify copyright. (This used to be commit 3ee62094074d74b6c69948730f2892f0a430f40b) --- source4/scripting/python/samba/provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 53eb1d618f..fa45f7a79d 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1,6 +1,6 @@ # # backend code for provisioning a Samba4 server -# Released under the GNU GPL v2 or later +# Released under the GNU GPL v3 or later # Copyright Jelmer Vernooij 2007 # # Based on the original in EJS: -- cgit From 6817c5d885a75a1af0e646827c3fa8220df8c7a5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 29 Dec 2007 18:14:15 -0600 Subject: r26628: python: Add more documentation, simplify code in Samba3 module. (This used to be commit 3c329ee73d9979236313c37e51750ec06b8dd69e) --- source4/scripting/python/samba/provision.py | 96 ++++++++++++++++++----------- 1 file changed, 61 insertions(+), 35 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index fa45f7a79d..bdfe035c41 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -74,6 +74,14 @@ def findnss(nssfn, *names): def open_ldb(session_info, credentials, lp, dbname): + """Open a LDB, thrashing it if it is corrupt. + + :param session_info: auth session information + :param credentials: credentials + :param lp: Loadparm context + :param dbname: Path of the database to open. + :return: a Ldb object + """ assert session_info is not None try: return Ldb(dbname, session_info=session_info, credentials=credentials, @@ -86,7 +94,12 @@ def open_ldb(session_info, credentials, lp, dbname): def setup_add_ldif(ldb, ldif_path, subst_vars=None): - """Setup a ldb in the private dir.""" + """Setup a ldb in the private dir. + + :param ldb: LDB file to import data into + :param ldif_path: Path of the LDIF file to load + :param subst_vars: Optional variables to subsitute in LDIF. + """ assert isinstance(ldif_path, str) data = open(ldif_path, 'r').read() @@ -126,7 +139,12 @@ def setup_ldb(ldb, ldif_path, subst_vars): def setup_file(template, fname, substvars): - """Setup a file in the private dir.""" + """Setup a file in the private dir. + + :param template: Path of the template file. + :param fname: Path of the file to create. + :param substvars: Substitution variables. + """ f = fname if os.path.exists(f): @@ -179,7 +197,17 @@ def provision_paths_from_lp(lp, dnsdomain): def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users, wheel, backup): - """setup reasonable name mappings for sam names to unix names.""" + """setup reasonable name mappings for sam names to unix names. + + :param ldb: SamDB object. + :param sid: The domain sid. + :param domaindn: The domain DN. + :param root: Name of the UNIX root user. + :param nobody: Name of the UNIX nobody user. + :param nogroup: Name of the unix nobody group. + :param users: Name of the unix users group. + :param wheel: Name of the wheel group (users that can become root). + :param backup: Name of the backup group.""" # add some foreign sids if they are not present already ldb.add_foreign(domaindn, "S-1-5-7", "Anonymous") ldb.add_foreign(domaindn, "S-1-1-0", "World") @@ -591,7 +619,8 @@ def provision(lp, setup_dir, message, blank, paths, session_info, if nogroup is None: nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] if users is None: - users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", "usr")[2] + users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", + "usr")[2] if wheel is None: wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[2] if backup is None: @@ -748,13 +777,32 @@ def provision(lp, setup_dir, message, blank, paths, session_info, return domaindn def create_phplpapdadmin_config(path, setup_path, s4_ldapi_path): + """Create a PHP LDAP admin configuration file. + + :param path: Path to write the configuration to. + :param setup_path: Function to generate setup paths. + :param s4_ldapi_path: Path to Samba 4 LDAPI socket. + """ setup_file(setup_path("phpldapadmin-config.php"), path, {"S4_LDAPI_URI": "ldapi://%s" % s4_ldapi_path.replace("/", "%2F")}) def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, hostip, hostname, dnspass, realm, domainguid, hostguid): - """Write out a DNS zone file, from the info in the current database.""" + """Write out a DNS zone file, from the info in the current database. + + :param path: Path of the new file. + :param setup_path": Setup path function. + :param samdb: SamDB object + :param dnsdomain: DNS Domain name + :param domaindn: DN of the Domain + :param hostip: Local IP + :param hostname: Local hostname + :param dnspass: Password for DNS + :param realm: Realm name + :param domainguid: GUID of the domain. + :param hostguid: GUID of the host. + """ setup_file(setup_path("provision.zone"), path, { "DNSPASS_B64": b64encode(dnspass), @@ -795,7 +843,14 @@ def provision_ldapbase(setup_dir, message, paths): def load_schema(setup_path, samdb, schemadn, netbiosname, configdn): - """Load schema.""" + """Load schema. + + :param samdb: Load a schema into a SamDB. + :param setup_path: Setup path function. + :param schemadn: DN of the schema + :param netbiosname: NetBIOS name of the host. + :param configdn: DN of the configuration + """ schema_data = open(setup_path("schema.ldif"), 'r').read() schema_data += open(setup_path("schema_samba4.ldif"), 'r').read() schema_data = substitute_var(schema_data, {"SCHEMADN": schemadn}) @@ -807,32 +862,3 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn): "DEFAULTSITE": DEFAULTSITE}) samdb.attach_schema_from_ldif(head_data, schema_data) - -def join_domain(domain, netbios_name, join_type, creds): - ctx = NetContext(creds) - joindom = object() - joindom.domain = domain - joindom.join_type = join_type - joindom.netbios_name = netbios_name - if not ctx.JoinDomain(joindom): - raise Exception("Domain Join failed: " + joindom.error_string) - - -def vampire(domain, session_info, credentials, message): - """Vampire a remote domain. - - Session info and credentials are required for for - access to our local database (might be remote ldap) - """ - ctx = NetContext(credentials) - machine_creds = Credentials() - machine_creds.set_domain(form.domain) - if not machine_creds.set_machine_account(): - raise Exception("Failed to access domain join information!") - vampire_ctx.machine_creds = machine_creds - vampire_ctx.session_info = session_info - if not ctx.SamSyncLdb(vampire_ctx): - raise Exception("Migration of remote domain to Samba failed: %s " % vampire_ctx.error_string) - - - -- cgit From 2bd4bf6a1beb2b00ab86cca59ac875bf75c921ef Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 29 Dec 2007 18:14:18 -0600 Subject: r26629: python: Improve documentation in various places. (This used to be commit ee71a27bca66426d34cb1d686a83ac6a342329d3) --- source4/scripting/python/samba/provision.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index bdfe035c41..db3749f721 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -23,6 +23,7 @@ import security from ldb import Dn, SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ LDB_ERR_NO_SUCH_OBJECT, timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE +"""Functions for setting up a Samba configuration.""" DEFAULTSITE = "Default-First-Site-Name" @@ -53,7 +54,12 @@ class ProvisionPaths: def install_ok(lp, session_info, credentials): - """Check whether the current install seems ok.""" + """Check whether the current install seems ok. + + :param lp: Loadparm context + :param session_info: Session information + :param credentials: Credentials + """ if lp.get("realm") == "": return False ldb = Ldb(lp.get("sam database"), session_info=session_info, -- cgit From 7c3e8c838f0ada9ebae9dbb2bc5d84320c8431f2 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 11 Jan 2008 16:13:46 +0100 Subject: Python: Simplify code in a couple of places. Copy Andrew's changes from g53b5166. (This used to be commit f056f624958af79204c972eba3f85e36e93daed7) --- source4/scripting/python/samba/provision.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index db3749f721..1607cb343b 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -20,7 +20,7 @@ import samba from samba import Ldb, substitute_var, valid_netbios_name from samba.samdb import SamDB import security -from ldb import Dn, SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ +from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ LDB_ERR_NO_SUCH_OBJECT, timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE """Functions for setting up a Samba configuration.""" @@ -64,7 +64,7 @@ def install_ok(lp, session_info, credentials): return False ldb = Ldb(lp.get("sam database"), session_info=session_info, credentials=credentials, lp=lp) - if len(ldb.search(ldb.Dn("(cn=Administrator)"))) != 1: + if len(ldb.search("(cn=Administrator)")) != 1: return False return True @@ -766,9 +766,9 @@ def provision(lp, setup_dir, message, blank, paths, session_info, samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) - domainguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID") + domainguid = samdb.searchone(domaindn, "objectGUID") assert isinstance(domainguid, str) - hostguid = samdb.searchone(Dn(samdb, domaindn), "objectGUID", + hostguid = samdb.searchone(domaindn, "objectGUID", expression="(&(objectClass=computer)(cn=%s))" % hostname, scope=SCOPE_SUBTREE) assert isinstance(hostguid, str) -- cgit From 064eb82870596e72373c290dfaf0e6b8289303de Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 18 Jan 2008 13:25:01 +1100 Subject: Remove --ldap-base from the python provision script (This is a merge from the ejs script) Andrew Bartlett (This used to be commit d822dfa017b84895222ace8c44935fb872930548) --- source4/scripting/python/samba/provision.py | 32 ----------------------------- 1 file changed, 32 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 1607cb343b..d59cea121e 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -180,12 +180,6 @@ def provision_paths_from_lp(lp, dnsdomain): paths.dns_keytab = os.path.join(private_dir, "dns.keytab") paths.dns = os.path.join(private_dir, dnsdomain + ".zone") paths.winsdb = os.path.join(private_dir, "wins.ldb") - paths.ldap_basedn_ldif = os.path.join(private_dir, - dnsdomain + ".ldif") - paths.ldap_config_basedn_ldif = os.path.join(private_dir, - dnsdomain + "-config.ldif") - paths.ldap_schema_basedn_ldif = os.path.join(private_dir, - dnsdomain + "-schema.ldif") paths.s4_ldapi_path = os.path.join(private_dir, "ldapi") paths.phpldapadminconfig = os.path.join(private_dir, "phpldapadmin-config.php") @@ -465,7 +459,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), { "DOMAINDN": domaindn, "ACI": aci, - "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", "RDN_DC": rdn_dc, }) @@ -823,31 +816,6 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, }) -def provision_ldapbase(setup_dir, message, paths): - """Write out a DNS zone file, from the info in the current database.""" - message("Setting up LDAP base entry: %s" % domaindn) - rdns = domaindn.split(",") - - rdn_dc = rdns[0][len("DC="):] - - def setup_path(file): - return os.path.join(setup_dir, file) - - setup_file(setup_path("provision_basedn.ldif"), - paths.ldap_basedn_ldif) - - setup_file(setup_path("provision_configuration_basedn.ldif"), - paths.ldap_config_basedn_ldif) - - setup_file(setup_path("provision_schema_basedn.ldif"), - paths.ldap_schema_basedn_ldif, { - "SCHEMADN": schemadn, - "ACI": "# no aci for local ldb", - "EXTENSIBLEOBJECT": "objectClass: extensibleObject"}) - - 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") - - def load_schema(setup_path, samdb, schemadn, netbiosname, configdn): """Load schema. -- cgit From a2dcf7bd22b5f206ef3c3816d0c93b140260da67 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 24 Jan 2008 01:06:19 +0100 Subject: Python: add some docstrings. (This used to be commit 1de69a772e1cc007220add1f51bffe83784c3344) --- source4/scripting/python/samba/provision.py | 51 ++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 5 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d59cea121e..11dd819ad3 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -289,6 +289,14 @@ def provision_become_dc(setup_dir, message, paths, lp, session_info, def setup_secretsdb(path, setup_path, session_info, credentials, lp): + """Setup the secrets database. + + :param path: Path to the secrets database. + :param setup_path: Get the path to a setup file. + :param session_info: Session info. + :param credentials: Credentials + :param lp: Loadparm context + """ if os.path.exists(path): os.unlink(path) secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, lp=lp) @@ -299,6 +307,14 @@ def setup_secretsdb(path, setup_path, session_info, credentials, lp): def setup_templatesdb(path, setup_path, session_info, credentials, lp): + """Setup the templates database. + + :param path: Path to the database. + :param setup_path: Function for obtaining the path to setup files. + :param session_info: Session info + :param credentials: Credentials + :param lp: Loadparm context + """ templates_ldb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) templates_ldb.erase() @@ -306,6 +322,14 @@ def setup_templatesdb(path, setup_path, session_info, credentials, lp): def setup_registry(path, setup_path, session_info, credentials, lp): + """Setup the registry. + + :param path: Path to the registry database + :param setup_path: Function that returns the path to a setup. + :param session_info: Session information + :param credentials: Credentials + :param lp: Loadparm context + """ reg = registry.Registry() hive = registry.open_ldb(path, session_info=session_info, credentials=credentials, lp_ctx=lp) @@ -317,6 +341,12 @@ def setup_registry(path, setup_path, session_info, credentials, lp): def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, dnsdomain, realm, rootdn, configdn, netbiosname): + """Setup the SamDB rootdse. + + :param samdb: Sam Database handle + :param setup_path: Obtain setup path + ... + """ setup_add_ldif(samdb, setup_path("provision_rootdse_add.ldif"), { "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, @@ -332,6 +362,14 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, def setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn): + """Setup SAM database partitions. + + :param samdb: Sam Database handle + :param setup_path: Setup path function + :param schemadn: Schema DN. + :param configdn: Configuration DN. + :param domaindn: Domain DN. + """ #Add modules to the list to activate them by default #beware often order is important # @@ -561,11 +599,14 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, if lp.get("server role") == "domain controller": message("Setting up self join") - setup_self_join(samdb, configdn=configdn, schemadn=schemadn, domaindn=domaindn, - invocationid=invocationid, dnspass=dnspass, netbiosname=netbiosname, - dnsdomain=dnsdomain, realm=realm, machinepass=machinepass, - domainname=domainname, domainsid=domainsid, policyguid=policyguid, - hostname=hostname, hostguid=hostguid, setup_path=setup_path) + setup_self_join(samdb, configdn=configdn, schemadn=schemadn, + domaindn=domaindn, invocationid=invocationid, + dnspass=dnspass, netbiosname=netbiosname, + dnsdomain=dnsdomain, realm=realm, + machinepass=machinepass, domainname=domainname, + domainsid=domainsid, policyguid=policyguid, + hostname=hostname, hostguid=hostguid, + setup_path=setup_path) message("Setting up sam.ldb index") samdb.load_ldif_file_add(setup_path("provision_index.ldif")) -- cgit From 37f35d2a03409e0d52232d4c4f956ec8637d4884 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 25 Jan 2008 01:02:13 +0100 Subject: python/provision: Reconcile code partitions-only provisioning and generic provisioning, some other minor refactoring of the provisioning. Pair-programmed by Andrew and me using obby :-) (This used to be commit 688adcbb635af87fcfedb869b7f1857a947fd2f9) --- source4/scripting/python/samba/provision.py | 469 ++++++++++++++++------------ 1 file changed, 265 insertions(+), 204 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 11dd819ad3..918d983782 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1,10 +1,25 @@ # -# backend code for provisioning a Samba4 server -# Released under the GNU GPL v3 or later -# Copyright Jelmer Vernooij 2007 +# Unix SMB/CIFS implementation. +# backend code for provisioning a Samba4 server + +# Copyright (C) Jelmer Vernooij 2007-2008 +# Copyright (C) Andrew Bartlett 2008 # # Based on the original in EJS: -# Copyright Andrew Tridgell 2005 +# Copyright (C) Andrew Tridgell 2005 +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see . # from base64 import b64encode @@ -17,9 +32,10 @@ from socket import gethostname, gethostbyname import param import registry import samba -from samba import Ldb, substitute_var, valid_netbios_name +from samba import Ldb, substitute_var, valid_netbios_name, check_all_substituted from samba.samdb import SamDB import security +import urllib from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ LDB_ERR_NO_SUCH_OBJECT, timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE @@ -53,7 +69,7 @@ class ProvisionPaths: self.ldap_schema_basedn_ldif = None -def install_ok(lp, session_info, credentials): +def check_install(lp, session_info, credentials): """Check whether the current install seems ok. :param lp: Loadparm context @@ -61,12 +77,11 @@ def install_ok(lp, session_info, credentials): :param credentials: Credentials """ if lp.get("realm") == "": - return False + raise Error("Realm empty") ldb = Ldb(lp.get("sam database"), session_info=session_info, credentials=credentials, lp=lp) if len(ldb.search("(cn=Administrator)")) != 1: - return False - return True + raise "No administrator account found" def findnss(nssfn, *names): @@ -112,7 +127,7 @@ def setup_add_ldif(ldb, ldif_path, subst_vars=None): if subst_vars is not None: data = substitute_var(data, subst_vars) - assert "${" not in data + check_all_substituted(data) ldb.add_ldif(data) @@ -128,7 +143,7 @@ def setup_modify_ldif(ldb, ldif_path, substvars=None): if substvars is not None: data = substitute_var(data, substvars) - assert "${" not in data + check_all_substituted(data) ldb.modify_ldif(data) @@ -159,19 +174,20 @@ def setup_file(template, fname, substvars): data = open(template, 'r').read() if substvars: data = substitute_var(data, substvars) - assert not "${" in data + check_all_substituted(data) open(f, 'w').write(data) -def provision_paths_from_lp(lp, dnsdomain): +def provision_paths_from_lp(lp, dnsdomain, private_dir=None): """Set the default paths for provisioning. :param lp: Loadparm context. :param dnsdomain: DNS Domain name """ paths = ProvisionPaths() - private_dir = lp.get("private dir") + if private_dir is None: + private_dir = lp.get("private dir") paths.shareconf = os.path.join(private_dir, "share.ldb") paths.samdb = os.path.join(private_dir, lp.get("sam database") or "samdb.ldb") paths.secrets = os.path.join(private_dir, lp.get("secrets database") or "secrets.ldb") @@ -235,57 +251,144 @@ def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users, ldb.setup_name_mapping(domaindn, sid + "-520", wheel) -def provision_become_dc(setup_dir, message, paths, lp, session_info, - credentials): +def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, + credentials, configdn, schemadn, domaindn, + hostname, netbiosname, dnsdomain, realm, + rootdn, serverrole, ldap_backend=None, + ldap_backend_type=None, erase=False): + """Setup the partitions for the SAM database. + + Alternatively, provision() may call this, and then populate the database. + + :param erase: Remove the existing data present in the database. + :param + + :note: This will wipe the Sam Database! + + :note: This function always removes the local SAM LDB file. The erase + parameter controls whether to erase the existing data, which + may not be stored locally but in LDAP. + """ assert session_info is not None - erase = False - def setup_path(file): - return os.path.join(setup_dir, file) - os.path.unlink(paths.samdb) - - message("Setting up templates db") - setup_templatesdb(paths.templates, setup_path, session_info=session_info, - credentials=credentials, lp=lp) + if os.path.exists(samdb_path): + os.unlink(samdb_path) # Also wipes the database - message("Setting up sam.ldb") - samdb = SamDB(paths.samdb, session_info=session_info, + samdb = SamDB(samdb_path, session_info=session_info, credentials=credentials, lp=lp) - message("Setting up sam.ldb partitions") - setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn) + #Add modules to the list to activate them by default + #beware often order is important + # + # Some Known ordering constraints: + # - rootdse must be first, as it makes redirects from "" -> cn=rootdse + # - objectclass must be before password_hash, because password_hash checks + # that the objectclass is of type person (filled in by objectclass + # module when expanding the objectclass list) + # - partition must be last + # - each partition has its own module list then + modules_list = ["rootdse", + "paged_results", + "ranged_results", + "anr", + "server_sort", + "extended_dn", + "asq", + "samldb", + "rdn_name", + "objectclass", + "kludge_acl", + "operational"] + tdb_modules_list = [ + "subtree_rename", + "subtree_delete", + "linked_attributes"] + modules_list2 = ["show_deleted", + "partition"] + + domaindn_ldb = "users.ldb" + if ldap_backend is not None: + domaindn_ldb = ldap_backend + configdn_ldb = "configuration.ldb" + if ldap_backend is not None: + configdn_ldb = ldap_backend + schema_ldb = "schema.ldb" + if ldap_backend is not None: + schema_ldb = ldap_backend + + if ldap_backend_type == "fedora-ds": + backend_modules = ["nsuniqueid","paged_searches"] + elif ldap_backend_type == "openldap": + backend_modules = ["normalise","entryuuid","paged_searches"] + elif serverrole == "domain controller": + backend_modules = ["repl_meta_data"] + else: + backend_modules = ["objectguid"] + + setup_add_ldif(samdb, setup_path("provision_partitions.ldif"), { + "SCHEMADN": schemadn, + "SCHEMADN_LDB": "schema.ldb", + "SCHEMADN_MOD2": ",objectguid", + "CONFIGDN": configdn, + "CONFIGDN_LDB": "configuration.ldb", + "DOMAINDN": domaindn, + "DOMAINDN_LDB": "users.ldb", + "SCHEMADN_MOD": "schema_fsmo,instancetype", + "CONFIGDN_MOD": "naming_fsmo,instancetype", + "DOMAINDN_MOD": "pdc_fsmo,password_hash,instancetype", + "MODULES_LIST": ",".join(modules_list), + "TDB_MODULES_LIST": ","+",".join(tdb_modules_list), + "MODULES_LIST2": ",".join(modules_list2), + "BACKEND_MOD": ",".join(backend_modules), + }) - samdb = SamDB(paths.samdb, session_info=session_info, + samdb = SamDB(samdb_path, session_info=session_info, credentials=credentials, lp=lp) - ldb.transaction_start() + samdb.transaction_start() try: message("Setting up sam.ldb attributes") samdb.load_ldif_file_add(setup_path("provision_init.ldif")) message("Setting up sam.ldb rootDSE") - setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, - hostname, dnsdomain, realm, rootdn, configdn, - netbiosname) + setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, + dnsdomain, realm, rootdn, configdn, netbiosname) if erase: message("Erasing data from partitions") samdb.erase_partitions() - message("Setting up sam.ldb indexes") - samdb.load_ldif_file_add(setup_path("provision_index.ldif")) except: samdb.transaction_cancel() raise samdb.transaction_commit() + + return samdb + - message("Setting up %s" % paths.secrets) - secrets_ldb = setup_secretsdb(paths.secrets, setup_path, session_info, - credentials, lp) - setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"), - { "MACHINEPASS_B64": b64encode(machinepass) }) +def secretsdb_become_dc(secretsdb, setup_path, domain, realm, dnsdomain, + netbiosname, domainsid, keytab_path, samdb_url, + dns_keytab_path, dnspass, machinepass): + """Add DC-specific bits to a secrets database. + + :param secretsdb: Ldb Handle to the secrets database + :param setup_path: Setup path function + :param machinepass: Machine password + """ + setup_ldb(secretsdb, setup_path("secrets_dc.ldif"), { + "MACHINEPASS_B64": b64encode(machinepass), + "DOMAIN": domain, + "REALM": realm, + "DNSDOMAIN": dnsdomain, + "DOMAINSID": str(domainsid), + "SECRETS_KEYTAB": keytab_path, + "NETBIOSNAME": netbiosname, + "SAM_LDB": samdb_url, + "DNS_KEYTAB": dns_keytab_path, + "DNSPASS_B64": b64encode(dnspass), + }) def setup_secretsdb(path, setup_path, session_info, credentials, lp): @@ -296,10 +399,12 @@ def setup_secretsdb(path, setup_path, session_info, credentials, lp): :param session_info: Session info. :param credentials: Credentials :param lp: Loadparm context + :return: LDB handle for the created secrets database """ if os.path.exists(path): os.unlink(path) - secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, lp=lp) + secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, + lp=lp) secrets_ldb.erase() secrets_ldb.load_ldif_file_add(setup_path("secrets_init.ldif")) secrets_ldb.load_ldif_file_add(setup_path("secrets.ldif")) @@ -316,7 +421,7 @@ def setup_templatesdb(path, setup_path, session_info, credentials, lp): :param lp: Loadparm context """ templates_ldb = SamDB(path, session_info=session_info, - credentials=credentials, lp=lp) + credentials=credentials, lp=lp) templates_ldb.erase() templates_ldb.load_ldif_file_add(setup_path("provision_templates.ldif")) @@ -359,69 +464,13 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, "CONFIGDN": configdn, "VERSION": samba.version(), }) - - -def setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn): - """Setup SAM database partitions. - - :param samdb: Sam Database handle - :param setup_path: Setup path function - :param schemadn: Schema DN. - :param configdn: Configuration DN. - :param domaindn: Domain DN. - """ - #Add modules to the list to activate them by default - #beware often order is important - # - # Some Known ordering constraints: - # - rootdse must be first, as it makes redirects from "" -> cn=rootdse - # - objectclass must be before password_hash, because password_hash checks - # that the objectclass is of type person (filled in by objectclass - # module when expanding the objectclass list) - # - partition must be last - # - each partition has its own module list then - modules_list = ["rootdse", - "paged_results", - "ranged_results", - "anr", - "server_sort", - "extended_dn", - "asq", - "samldb", - "rdn_name", - "objectclass", - "kludge_acl", - "operational"] - tdb_modules_list = [ - "subtree_rename", - "subtree_delete", - "linked_attributes"] - modules_list2 = ["show_deleted", - "partition"] - - setup_add_ldif(samdb, setup_path("provision_partitions.ldif"), { - "SCHEMADN": schemadn, - "SCHEMADN_LDB": "schema.ldb", - "SCHEMADN_MOD2": ",objectguid", - "CONFIGDN": configdn, - "CONFIGDN_LDB": "configuration.ldb", - "DOMAINDN": domaindn, - "DOMAINDN_LDB": "users.ldb", - "SCHEMADN_MOD": "schema_fsmo", - "CONFIGDN_MOD": "naming_fsmo", - "CONFIGDN_MOD2": ",objectguid", - "DOMAINDN_MOD": "pdc_fsmo,password_hash", - "DOMAINDN_MOD2": ",objectguid", - "MODULES_LIST": ",".join(modules_list), - "TDB_MODULES_LIST": ","+",".join(tdb_modules_list), - "MODULES_LIST2": ",".join(modules_list2), - }) - + def setup_self_join(samdb, configdn, schemadn, domaindn, netbiosname, hostname, dnsdomain, machinepass, dnspass, realm, domainname, domainsid, invocationid, setup_path, policyguid, hostguid=None): + """Join a host to its own domain.""" if hostguid is not None: hostguid_add = "objectGUID: %s" % hostguid else: @@ -451,43 +500,39 @@ def setup_self_join(samdb, configdn, schemadn, domaindn, def setup_samdb(path, setup_path, session_info, credentials, lp, schemadn, configdn, domaindn, dnsdomain, realm, netbiosname, message, hostname, rootdn, erase, - domainsid, aci, rdn_dc, domainguid, policyguid, - domainname, blank, adminpass, krbtgtpass, - machinepass, hostguid, invocationid, dnspass): - # Also wipes the database - message("Setting up sam.ldb") - samdb = SamDB(path, session_info=session_info, - credentials=credentials, lp=lp) + domainsid, aci, domainguid, policyguid, + domainname, fill, adminpass, krbtgtpass, + machinepass, hostguid, invocationid, dnspass, + serverrole, ldap_backend=None, ldap_backend_type=None): + """Setup a complete SAM Database. + + """ - message("Setting up sam.ldb partitions") - setup_samdb_partitions(samdb, setup_path, schemadn, configdn, domaindn) + # Also wipes the database + setup_samdb_partitions(path, setup_path, schemadn=schemadn, configdn=configdn, + domaindn=domaindn, message=message, lp=lp, + credentials=credentials, session_info=session_info, + hostname=hostname, netbiosname=netbiosname, + dnsdomain=dnsdomain, realm=realm, rootdn=rootdn, + ldap_backend=ldap_backend, serverrole=serverrole, + ldap_backend_type=ldap_backend_type, erase=erase) samdb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) - samdb.transaction_start() - try: - message("Setting up sam.ldb attributes") - samdb.load_ldif_file_add(setup_path("provision_init.ldif")) - - message("Setting up sam.ldb rootDSE") - setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, - hostname, dnsdomain, realm, rootdn, configdn, - netbiosname) - - if erase: - message("Erasing data from partitions") - samdb.erase_partitions() - except: - samdb.transaction_cancel() - raise - - samdb.transaction_commit() + if fill == FILL_DRS: + # We want to finish here, but setup the index before we do so + message("Setting up sam.ldb index") + samdb.load_ldif_file_add(setup_path("provision_index.ldif")) + return samdb message("Pre-loading the Samba 4 and AD schema") samdb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) samdb.set_domain_sid(domainsid) + if lp.get("server role") == "domain controller": + samdb.set_invocation_id(invocationid) + load_schema(setup_path, samdb, schemadn, netbiosname, configdn) samdb.transaction_start() @@ -497,7 +542,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), { "DOMAINDN": domaindn, "ACI": aci, - "RDN_DC": rdn_dc, }) message("Modifying DomainDN: " + domaindn + "") @@ -507,7 +551,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, domainguid_mod = "" setup_modify_ldif(samdb, setup_path("provision_basedn_modify.ldif"), { - "RDN_DC": rdn_dc, "LDAPTIME": timestring(int(time.time())), "DOMAINSID": str(domainsid), "SCHEMADN": schemadn, @@ -538,7 +581,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" }) message("Modifying schema container") - setup_modify_ldif(samdb, setup_path("provision_schema_basedn_modify.ldif"), { + setup_modify_ldif(samdb, + setup_path("provision_schema_basedn_modify.ldif"), { "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, "DEFAULTSITE": DEFAULTSITE, @@ -587,7 +631,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "CONFIGDN": configdn, }) - if not blank: + if fill == FILL_FULL: message("Setting up sam.ldb users and groups") setup_add_ldif(samdb, setup_path("provision_users.ldif"), { "DOMAINDN": domaindn, @@ -608,11 +652,9 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, hostname=hostname, hostguid=hostguid, setup_path=setup_path) + #We want to setup the index last, as adds are faster unindexed message("Setting up sam.ldb index") samdb.load_ldif_file_add(setup_path("provision_index.ldif")) - - message("Setting up sam.ldb rootDSE marking as synchronized") - setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif")) except: samdb.transaction_cancel() raise @@ -620,14 +662,18 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, samdb.transaction_commit() return samdb - -def provision(lp, setup_dir, message, blank, paths, session_info, - credentials, ldapbackend, realm=None, domain=None, hostname=None, - hostip=None, domainsid=None, hostguid=None, adminpass=None, - krbtgtpass=None, domainguid=None, policyguid=None, - invocationid=None, machinepass=None, dnspass=None, root=None, - nobody=None, nogroup=None, users=None, wheel=None, backup=None, - aci=None, serverrole=None): +FILL_FULL = "FULL" +FILL_NT4SYNC = "NT4SYNC" +FILL_DRS = "DRS" + +def provision(lp, setup_dir, message, paths, session_info, + credentials, ldapbackend, samdb_fill=FILL_FULL, realm=None, rootdn=None, + domain=None, hostname=None, hostip=None, domainsid=None, + hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None, + policyguid=None, invocationid=None, machinepass=None, + dnspass=None, root=None, nobody=None, nogroup=None, users=None, + wheel=None, backup=None, aci=None, serverrole=None, erase=False, + ldap_backend=None, ldap_backend_type=None): """Provision samba4 :note: caution, this wipes all existing data! @@ -636,14 +682,10 @@ def provision(lp, setup_dir, message, blank, paths, session_info, def setup_path(file): return os.path.join(setup_dir, file) - erase = False - if domainsid is None: domainsid = security.random_sid() if policyguid is None: policyguid = uuid.random() - if invocationid is None: - invocationid = uuid.random() if adminpass is None: adminpass = misc.random_password(12) if krbtgtpass is None: @@ -669,29 +711,25 @@ def provision(lp, setup_dir, message, blank, paths, session_info, aci = "# no aci for local ldb" if serverrole is None: serverrole = lp.get("server role") + if invocationid is None and serverrole == "domain controller": + invocationid = uuid.random() if realm is None: realm = lp.get("realm") - else: - if lp.get("realm").upper() != realm.upper(): - raise Exception("realm '%s' in smb.conf must match chosen realm '%s'\n" % + + if lp.get("realm").upper() != realm.upper(): + raise Exception("realm '%s' in smb.conf must match chosen realm '%s'" % (lp.get("realm"), realm)) + ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path) + + if ldap_backend == "ldapi": + # provision-backend will set this path suggested slapd command line / fedorads.inf + ldap_backend = "ldapi://" % urllib.quote(os.path.join(lp.get("private dir"), "ldap", "ldapi")) + assert realm is not None realm = realm.upper() - if domain is None: - domain = lp.get("workgroup") - else: - if lp.get("workgroup").upper() != domain.upper(): - raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'\n", - lp.get("workgroup"), domain) - - assert domain is not None - domain = domain.upper() - if not valid_netbios_name(domain): - raise InvalidNetbiosName(domain) - if hostname is None: hostname = gethostname().split(".")[0].lower() @@ -703,13 +741,30 @@ def provision(lp, setup_dir, message, blank, paths, session_info, raise InvalidNetbiosName(netbiosname) dnsdomain = realm.lower() - domaindn = "DC=" + dnsdomain.replace(".", ",DC=") - rootdn = domaindn + if serverrole == "domain controller": + domaindn = "DC=" + dnsdomain.replace(".", ",DC=") + if domain is None: + domain = lp.get("workgroup") + + if lp.get("workgroup").upper() != domain.upper(): + raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'", + lp.get("workgroup"), domain) + + assert domain is not None + domain = domain.upper() + if not valid_netbios_name(domain): + raise InvalidNetbiosName(domain) + + else: + domaindn = "CN=" + netbiosname + domain = netbiosname + + if rootdn is None: + rootdn = domaindn + configdn = "CN=Configuration," + rootdn schemadn = "CN=Schema," + configdn - rdn_dc = domaindn.split(",")[0][len("DC="):] - message("set DOMAIN SID: %s" % str(domainsid)) message("Provisioning for %s in realm %s" % (domain, realm)) message("Using administrator password: %s" % adminpass) @@ -725,7 +780,8 @@ def provision(lp, setup_dir, message, blank, paths, session_info, smbconfsuffix = "member" else: assert "Invalid server role setting: %s" % serverrole - setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), paths.smbconf, { + setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), + paths.smbconf, { "HOSTNAME": hostname, "DOMAIN_CONF": domain, "REALM_CONF": realm, @@ -742,6 +798,7 @@ def provision(lp, setup_dir, message, blank, paths, session_info, credentials=credentials, lp=lp) share_ldb.load_ldif_file_add(setup_path("share.ldif")) + message("Setting up secrets.ldb") secrets_ldb = setup_secretsdb(paths.secrets, setup_path, session_info=session_info, @@ -755,44 +812,47 @@ def provision(lp, setup_dir, message, blank, paths, session_info, setup_templatesdb(paths.templates, setup_path, session_info=session_info, credentials=credentials, lp=lp) - samdb = setup_samdb(paths.samdb, setup_path, session_info=session_info, credentials=credentials, - lp=lp, schemadn=schemadn, configdn=configdn, domaindn=domaindn, - dnsdomain=dnsdomain, netbiosname=netbiosname, realm=realm, message=message, - hostname=hostname, rootdn=rootdn, erase=erase, domainsid=domainsid, aci=aci, - rdn_dc=rdn_dc, domainguid=domainguid, policyguid=policyguid, - domainname=domain, blank=blank, adminpass=adminpass, krbtgtpass=krbtgtpass, - hostguid=hostguid, invocationid=invocationid, machinepass=machinepass, - dnspass=dnspass) + samdb = setup_samdb(paths.samdb, setup_path, session_info=session_info, + credentials=credentials, lp=lp, schemadn=schemadn, + configdn=configdn, domaindn=domaindn, + dnsdomain=dnsdomain, netbiosname=netbiosname, + realm=realm, message=message, hostname=hostname, + rootdn=rootdn, erase=erase, domainsid=domainsid, + aci=aci, domainguid=domainguid, policyguid=policyguid, + domainname=domain, fill=samdb_fill, + adminpass=adminpass, krbtgtpass=krbtgtpass, + hostguid=hostguid, invocationid=invocationid, + machinepass=machinepass, dnspass=dnspass, + serverrole=serverrole, ldap_backend=ldap_backend, + ldap_backend_type=ldap_backend_type) if lp.get("server role") == "domain controller": - os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}"), 0755) - os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "Machine"), 0755) - os.makedirs(os.path.join(paths.sysvol, dnsdomain, "Policies", "{" + policyguid + "}", "User"), 0755) - if not os.path.isdir(paths.netlogon): + policy_path = os.path.join(paths.sysvol, dnsdomain, "Policies", + "{" + policyguid + "}") + os.makedirs(policy_path, 0755) + os.makedirs(os.path.join(policy_path, "Machine"), 0755) + os.makedirs(os.path.join(policy_path, "User"), 0755) + if not os.path.isdir(paths.netlogon): os.makedirs(paths.netlogon, 0755) - secrets_ldb = Ldb(paths.secrets, session_info=session_info, credentials=credentials, lp=lp) - setup_ldb(secrets_ldb, setup_path("secrets_dc.ldif"), { - "MACHINEPASS_B64": b64encode(machinepass), - "DOMAIN": domain, - "REALM": realm, - "LDAPTIME": timestring(int(time.time())), - "DNSDOMAIN": dnsdomain, - "DOMAINSID": str(domainsid), - "SECRETS_KEYTAB": paths.keytab, - "NETBIOSNAME": netbiosname, - "SAM_LDB": paths.samdb, - "DNS_KEYTAB": paths.dns_keytab, - "DNSPASS_B64": b64encode(dnspass), - }) - - if not blank: - setup_name_mappings(samdb, str(domainsid), - domaindn, root=root, nobody=nobody, - nogroup=nogroup, wheel=wheel, users=users, - backup=backup) + secrets_ldb = Ldb(paths.secrets, session_info=session_info, + credentials=credentials, lp=lp) + secretsdb_become_dc(secrets_ldb, setup_path, domain=domain, realm=realm, + netbiosname=netbiosname, domainsid=domainsid, + keytab_path=paths.keytab, samdb_url=paths.samdb, + dns_keytab_path=paths.dns_keytab, dnspass=dnspass, + machinepass=machinepass, dnsdomain=dnsdomain) + + if samdb_fill == FILL_FULL: + setup_name_mappings(samdb, str(domainsid), domaindn, root=root, + nobody=nobody, nogroup=nogroup, wheel=wheel, + users=users, backup=backup) + + message("Setting up sam.ldb rootDSE marking as synchronized") + setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif")) message("Setting up phpLDAPadmin configuration") - create_phplpapdadmin_config(paths.phpldapadminconfig, setup_path, paths.s4_ldapi_path) + create_phpldapadmin_config(paths.phpldapadminconfig, setup_path, + ldapi_url) message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) @@ -816,15 +876,15 @@ def provision(lp, setup_dir, message, blank, paths, session_info, return domaindn -def create_phplpapdadmin_config(path, setup_path, s4_ldapi_path): + +def create_phpldapadmin_config(path, setup_path, ldap_backend): """Create a PHP LDAP admin configuration file. :param path: Path to write the configuration to. :param setup_path: Function to generate setup paths. - :param s4_ldapi_path: Path to Samba 4 LDAPI socket. """ - setup_file(setup_path("phpldapadmin-config.php"), - path, {"S4_LDAPI_URI": "ldapi://%s" % s4_ldapi_path.replace("/", "%2F")}) + setup_file(setup_path("phpldapadmin-config.php"), path, + {"S4_LDAPI_URI": ldap_backend}) def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, @@ -874,6 +934,7 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn): "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, "CONFIGDN": configdn, - "DEFAULTSITE": DEFAULTSITE}) + "DEFAULTSITE": DEFAULTSITE + }) samdb.attach_schema_from_ldif(head_data, schema_data) -- cgit From dcb04065cda7fc7f23c494ec138af6b882651f20 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 25 Jan 2008 03:54:33 +0100 Subject: python: Fix representation of UUIDs as strings in zone files rather than binary blobs, fix escaping of LDAP URL's in PHP LDAP admin configuration. Pair-programmed with Andrew, but git doesn't appear to support multiple --author arguments. :-( (This used to be commit dff54ff043563f93b86361039c46e662045f62cc) --- source4/scripting/python/samba/provision.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 918d983782..0e498f65e5 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -725,7 +725,7 @@ def provision(lp, setup_dir, message, paths, session_info, if ldap_backend == "ldapi": # provision-backend will set this path suggested slapd command line / fedorads.inf - ldap_backend = "ldapi://" % urllib.quote(os.path.join(lp.get("private dir"), "ldap", "ldapi")) + ldap_backend = "ldapi://" % urllib.quote(os.path.join(lp.get("private dir"), "ldap", "ldapi"), "") assert realm is not None realm = realm.upper() @@ -860,9 +860,9 @@ def provision(lp, setup_dir, message, paths, session_info, samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) - domainguid = samdb.searchone(domaindn, "objectGUID") + domainguid = samdb.searchone(basedn=domaindn, attribute="objectGUID") assert isinstance(domainguid, str) - hostguid = samdb.searchone(domaindn, "objectGUID", + hostguid = samdb.searchone(basedn=domaindn, attribute="objectGUID", expression="(&(objectClass=computer)(cn=%s))" % hostname, scope=SCOPE_SUBTREE) assert isinstance(hostguid, str) @@ -877,14 +877,14 @@ def provision(lp, setup_dir, message, paths, session_info, return domaindn -def create_phpldapadmin_config(path, setup_path, ldap_backend): +def create_phpldapadmin_config(path, setup_path, ldapi_uri): """Create a PHP LDAP admin configuration file. :param path: Path to write the configuration to. :param setup_path: Function to generate setup paths. """ setup_file(setup_path("phpldapadmin-config.php"), path, - {"S4_LDAPI_URI": ldap_backend}) + {"S4_LDAPI_URI": ldapi_uri}) def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, @@ -903,6 +903,7 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, :param domainguid: GUID of the domain. :param hostguid: GUID of the host. """ + assert isinstance(domainguid, str) setup_file(setup_path("provision.zone"), path, { "DNSPASS_B64": b64encode(dnspass), -- cgit From 1b18de131c556280004dea6393e22547c9681fd9 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 Jan 2008 17:11:20 +1100 Subject: Tidy up the last regresesions on the python smbscript, from my work with Jelmer today. The only remaining issue is that for the build farm, we will need to manually specify the users and groups from the NSS_WRAPPPER, as python isn't compiled with this. Andrew Bartlett (This used to be commit 5370484d25b8c7a5bde730d9be36ecbbb0aaf315) --- source4/scripting/python/samba/provision.py | 27 +++++++++++++++++---------- 1 file changed, 17 insertions(+), 10 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 0e498f65e5..26c4afe3c8 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -188,12 +188,17 @@ def provision_paths_from_lp(lp, dnsdomain, private_dir=None): paths = ProvisionPaths() if private_dir is None: private_dir = lp.get("private dir") + paths.keytab = "secrets.keytab" + paths.dns_keytab = "dns.keytab" + else: + paths.keytab = os.path.join(private_dir, "secrets.keytab") + paths.dns_keytab = os.path.join(private_dir, "dns.keytab") + paths.shareconf = os.path.join(private_dir, "share.ldb") paths.samdb = os.path.join(private_dir, lp.get("sam database") or "samdb.ldb") paths.secrets = os.path.join(private_dir, lp.get("secrets database") or "secrets.ldb") paths.templates = os.path.join(private_dir, "templates.ldb") - paths.keytab = os.path.join(private_dir, "secrets.keytab") - paths.dns_keytab = os.path.join(private_dir, "dns.keytab") + paths.dns = os.path.join(private_dir, dnsdomain + ".zone") paths.winsdb = os.path.join(private_dir, "wins.ldb") paths.s4_ldapi_path = os.path.join(private_dir, "ldapi") @@ -407,6 +412,8 @@ def setup_secretsdb(path, setup_path, session_info, credentials, lp): lp=lp) secrets_ldb.erase() secrets_ldb.load_ldif_file_add(setup_path("secrets_init.ldif")) + secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, + lp=lp) secrets_ldb.load_ldif_file_add(setup_path("secrets.ldif")) return secrets_ldb @@ -695,18 +702,18 @@ def provision(lp, setup_dir, message, paths, session_info, if dnspass is None: dnspass = misc.random_password(12) if root is None: - root = findnss(pwd.getpwnam, "root")[4] + root = findnss(pwd.getpwnam, "root")[0] if nobody is None: - nobody = findnss(pwd.getpwnam, "nobody")[4] + nobody = findnss(pwd.getpwnam, "nobody")[0] if nogroup is None: - nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] + nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[0] if users is None: users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", - "usr")[2] + "usr")[0] if wheel is None: - wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[2] + wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[0] if backup is None: - backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[2] + backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[0] if aci is None: aci = "# no aci for local ldb" if serverrole is None: @@ -721,11 +728,11 @@ def provision(lp, setup_dir, message, paths, session_info, raise Exception("realm '%s' in smb.conf must match chosen realm '%s'" % (lp.get("realm"), realm)) - ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path) + ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="") if ldap_backend == "ldapi": # provision-backend will set this path suggested slapd command line / fedorads.inf - ldap_backend = "ldapi://" % urllib.quote(os.path.join(lp.get("private dir"), "ldap", "ldapi"), "") + ldap_backend = "ldapi://" % urllib.quote(os.path.join(lp.get("private dir"), "ldap", "ldapi"), safe="") assert realm is not None realm = realm.upper() -- cgit From 6c2d4f2806bae8072d61ba8795832d9a9e75573e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 25 Jan 2008 11:47:44 +0100 Subject: python/provision: Reload secrets when necessary, fix unix names in mappings. Pair programmed with Andrew. (This used to be commit 04fe8c8aefae8da8966954d0654c37adf2d0361d) --- source4/scripting/python/samba/provision.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 0e498f65e5..4d99cd9cd9 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -193,7 +193,7 @@ def provision_paths_from_lp(lp, dnsdomain, private_dir=None): paths.secrets = os.path.join(private_dir, lp.get("secrets database") or "secrets.ldb") paths.templates = os.path.join(private_dir, "templates.ldb") paths.keytab = os.path.join(private_dir, "secrets.keytab") - paths.dns_keytab = os.path.join(private_dir, "dns.keytab") + paths.dns_keytab = "dns.keytab" paths.dns = os.path.join(private_dir, dnsdomain + ".zone") paths.winsdb = os.path.join(private_dir, "wins.ldb") paths.s4_ldapi_path = os.path.join(private_dir, "ldapi") @@ -407,6 +407,8 @@ def setup_secretsdb(path, setup_path, session_info, credentials, lp): lp=lp) secrets_ldb.erase() secrets_ldb.load_ldif_file_add(setup_path("secrets_init.ldif")) + secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, + lp=lp) secrets_ldb.load_ldif_file_add(setup_path("secrets.ldif")) return secrets_ldb @@ -695,18 +697,18 @@ def provision(lp, setup_dir, message, paths, session_info, if dnspass is None: dnspass = misc.random_password(12) if root is None: - root = findnss(pwd.getpwnam, "root")[4] + root = findnss(pwd.getpwnam, "root")[0] if nobody is None: - nobody = findnss(pwd.getpwnam, "nobody")[4] + nobody = findnss(pwd.getpwnam, "nobody")[0] if nogroup is None: - nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[2] + nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[0] if users is None: users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", - "usr")[2] + "usr")[0] if wheel is None: - wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[2] + wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[0] if backup is None: - backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[2] + backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[0] if aci is None: aci = "# no aci for local ldb" if serverrole is None: -- cgit From cab677a33f0376cd1bf96ec561dc0463bbf80edd Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 26 Jan 2008 04:22:42 +0100 Subject: python: Use relative paths for registry. (This used to be commit 079200b824de6dd8c7de3e5b76ed1805fde02965) --- source4/scripting/python/samba/provision.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index f244679eb5..d2a4f28b64 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -203,7 +203,13 @@ def provision_paths_from_lp(lp, dnsdomain, private_dir=None): paths.s4_ldapi_path = os.path.join(private_dir, "ldapi") paths.phpldapadminconfig = os.path.join(private_dir, "phpldapadmin-config.php") - paths.hklm = os.path.join(private_dir, "hklm.ldb") + paths.hklm = "hklm.ldb" + paths.hkcr = "hkcr.ldb" + paths.hkcu = "hkcu.ldb" + paths.hku = "hku.ldb" + paths.hkpd = "hkpd.ldb" + paths.hkpt = "hkpt.ldb" + paths.sysvol = lp.get("sysvol", "path") if paths.sysvol is None: paths.sysvol = os.path.join(lp.get("lock dir"), "sysvol") @@ -442,6 +448,7 @@ def setup_registry(path, setup_path, session_info, credentials, lp): :param lp: Loadparm context """ reg = registry.Registry() + print path hive = registry.open_ldb(path, session_info=session_info, credentials=credentials, lp_ctx=lp) reg.mount_hive(hive, "HKEY_LOCAL_MACHINE") -- cgit From fffe4f3bdd27b11dce75c9b2c931f5291f04ab6b Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 8 Feb 2008 03:03:44 +0100 Subject: Fix formatting. (This used to be commit 73d1b0fcb64fdc7be1e1e1002f3f182fcbe476ae) --- source4/scripting/python/samba/provision.py | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d2a4f28b64..bcadcca583 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -319,14 +319,14 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, domaindn_ldb = "users.ldb" if ldap_backend is not None: - domaindn_ldb = ldap_backend + domaindn_ldb = ldap_backend configdn_ldb = "configuration.ldb" if ldap_backend is not None: - configdn_ldb = ldap_backend + configdn_ldb = ldap_backend schema_ldb = "schema.ldb" if ldap_backend is not None: - schema_ldb = ldap_backend - + schema_ldb = ldap_backend + if ldap_backend_type == "fedora-ds": backend_modules = ["nsuniqueid","paged_searches"] elif ldap_backend_type == "openldap": @@ -737,8 +737,8 @@ def provision(lp, setup_dir, message, paths, session_info, ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="") if ldap_backend == "ldapi": - # provision-backend will set this path suggested slapd command line / fedorads.inf - ldap_backend = "ldapi://" % urllib.quote(os.path.join(lp.get("private dir"), "ldap", "ldapi"), safe="") + # provision-backend will set this path suggested slapd command line / fedorads.inf + ldap_backend = "ldapi://" % urllib.quote(os.path.join(lp.get("private dir"), "ldap", "ldapi"), safe="") assert realm is not None realm = realm.upper() @@ -755,7 +755,7 @@ def provision(lp, setup_dir, message, paths, session_info, dnsdomain = realm.lower() if serverrole == "domain controller": - domaindn = "DC=" + dnsdomain.replace(".", ",DC=") + domaindn = "DC=" + dnsdomain.replace(".", ",DC=") if domain is None: domain = lp.get("workgroup") @@ -769,9 +769,9 @@ def provision(lp, setup_dir, message, paths, session_info, raise InvalidNetbiosName(domain) else: - domaindn = "CN=" + netbiosname - domain = netbiosname - + domaindn = "CN=" + netbiosname + domain = netbiosname + if rootdn is None: rootdn = domaindn -- cgit From 26897518ea88e6c70eda4031e62c02fcbcdb0fc0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 8 Feb 2008 17:11:26 +1100 Subject: Fix LDAP backend with python We were still setting the hard-coded users.ldb etc, rather than switching to the ldapi:// URI Andrew Bartlett (This used to be commit 603e981250b26b533ec35dd607cb635226cf99df) --- source4/scripting/python/samba/provision.py | 44 +++++++++++++++++------------ 1 file changed, 26 insertions(+), 18 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d2a4f28b64..9a44983d8e 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -323,9 +323,9 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, configdn_ldb = "configuration.ldb" if ldap_backend is not None: configdn_ldb = ldap_backend - schema_ldb = "schema.ldb" + schemadn_ldb = "schema.ldb" if ldap_backend is not None: - schema_ldb = ldap_backend + schemadn_ldb = ldap_backend if ldap_backend_type == "fedora-ds": backend_modules = ["nsuniqueid","paged_searches"] @@ -336,23 +336,31 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, else: backend_modules = ["objectguid"] - setup_add_ldif(samdb, setup_path("provision_partitions.ldif"), { - "SCHEMADN": schemadn, - "SCHEMADN_LDB": "schema.ldb", - "SCHEMADN_MOD2": ",objectguid", - "CONFIGDN": configdn, - "CONFIGDN_LDB": "configuration.ldb", - "DOMAINDN": domaindn, - "DOMAINDN_LDB": "users.ldb", - "SCHEMADN_MOD": "schema_fsmo,instancetype", - "CONFIGDN_MOD": "naming_fsmo,instancetype", - "DOMAINDN_MOD": "pdc_fsmo,password_hash,instancetype", - "MODULES_LIST": ",".join(modules_list), - "TDB_MODULES_LIST": ","+",".join(tdb_modules_list), - "MODULES_LIST2": ",".join(modules_list2), - "BACKEND_MOD": ",".join(backend_modules), + samdb.transaction_start() + try: + setup_add_ldif(samdb, setup_path("provision_partitions.ldif"), { + "SCHEMADN": schemadn, + "SCHEMADN_LDB": schemadn_ldb, + "SCHEMADN_MOD2": ",objectguid", + "CONFIGDN": configdn, + "CONFIGDN_LDB": configdn_ldb, + "DOMAINDN": domaindn, + "DOMAINDN_LDB": domaindn_ldb, + "SCHEMADN_MOD": "schema_fsmo,instancetype", + "CONFIGDN_MOD": "naming_fsmo,instancetype", + "DOMAINDN_MOD": "pdc_fsmo,password_hash,instancetype", + "MODULES_LIST": ",".join(modules_list), + "TDB_MODULES_LIST": ","+",".join(tdb_modules_list), + "MODULES_LIST2": ",".join(modules_list2), + "BACKEND_MOD": ",".join(backend_modules), }) + except: + samdb.transaction_cancel() + raise + + samdb.transaction_commit() + samdb = SamDB(samdb_path, session_info=session_info, credentials=credentials, lp=lp) @@ -680,7 +688,7 @@ FILL_NT4SYNC = "NT4SYNC" FILL_DRS = "DRS" def provision(lp, setup_dir, message, paths, session_info, - credentials, ldapbackend, samdb_fill=FILL_FULL, realm=None, rootdn=None, + credentials, samdb_fill=FILL_FULL, realm=None, rootdn=None, domain=None, hostname=None, hostip=None, domainsid=None, hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None, policyguid=None, invocationid=None, machinepass=None, -- cgit From c1d8ac0ab1226c27a46fcbb0101c2921d63de599 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 9 Feb 2008 01:42:38 +0100 Subject: Remove unused class members. (This used to be commit 373ef4287f998b79bf9ba6364d6a67e5c522833d) --- source4/scripting/python/samba/provision.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 0c16ab3bfe..e15f205813 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -64,9 +64,6 @@ class ProvisionPaths: self.dns_keytab = None self.dns = None self.winsdb = None - self.ldap_basedn_ldif = None - self.ldap_config_basedn_ldif = None - self.ldap_schema_basedn_ldif = None def check_install(lp, session_info, credentials): @@ -201,6 +198,7 @@ def provision_paths_from_lp(lp, dnsdomain, private_dir=None): paths.dns = os.path.join(private_dir, dnsdomain + ".zone") paths.winsdb = os.path.join(private_dir, "wins.ldb") paths.s4_ldapi_path = os.path.join(private_dir, "ldapi") + paths.smbconf = os.path.join(private_dir, "smb.conf") paths.phpldapadminconfig = os.path.join(private_dir, "phpldapadmin-config.php") paths.hklm = "hklm.ldb" @@ -812,7 +810,7 @@ def provision(lp, setup_dir, message, paths, session_info, "NETLOGONPATH": paths.netlogon, "SYSVOLPATH": paths.sysvol, }) - lp.reload() + lp.load(paths.smbconf) # only install a new shares config db if there is none if not os.path.exists(paths.shareconf): -- cgit From 2aac2a5df8a03a42ed92e84f093b8aa5ba16dd1d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 9 Feb 2008 02:10:49 +0100 Subject: Add tests for findnss(), add some docstrings. (This used to be commit 4eec2bbc9a139e927ce21c615ebfbb3026b26384) --- source4/scripting/python/samba/provision.py | 39 +++++++++++++++++++---------- 1 file changed, 26 insertions(+), 13 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index e15f205813..b094581fb4 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -81,14 +81,19 @@ def check_install(lp, session_info, credentials): raise "No administrator account found" -def findnss(nssfn, *names): - """Find a user or group from a list of possibilities.""" +def findnss(nssfn, names): + """Find a user or group from a list of possibilities. + + :param nssfn: NSS Function to try (should raise KeyError if not found) + :param names: Names to check. + :return: Value return by first names list. + """ for name in names: try: return nssfn(name) except KeyError: pass - raise Exception("Unable to find user/group for %s" % arguments[1]) + raise KeyError("Unable to find user/group %r" % names) def open_ldb(session_info, credentials, lp, dbname): @@ -146,6 +151,14 @@ def setup_modify_ldif(ldb, ldif_path, substvars=None): def setup_ldb(ldb, ldif_path, subst_vars): + """Import a LDIF a file into a LDB handle, optionally substituting variables. + + :note: Either all LDIF data will be added or none (using transactions). + + :param ldb: LDB file to import into. + :param ldif_path: Path to the LDIF file. + :param subst_vars: Dictionary with substitution variables. + """ assert ldb is not None ldb.transaction_start() try: @@ -716,18 +729,18 @@ def provision(lp, setup_dir, message, paths, session_info, if dnspass is None: dnspass = misc.random_password(12) if root is None: - root = findnss(pwd.getpwnam, "root")[0] + root = findnss(pwd.getpwnam, ["root"])[0] if nobody is None: - nobody = findnss(pwd.getpwnam, "nobody")[0] + nobody = findnss(pwd.getpwnam, ["nobody"])[0] if nogroup is None: - nogroup = findnss(grp.getgrnam, "nogroup", "nobody")[0] + nogroup = findnss(grp.getgrnam, ["nogroup", "nobody"])[0] if users is None: - users = findnss(grp.getgrnam, "users", "guest", "other", "unknown", - "usr")[0] + users = findnss(grp.getgrnam, ["users", "guest", "other", "unknown", + "usr"])[0] if wheel is None: - wheel = findnss(grp.getgrnam, "wheel", "root", "staff", "adm")[0] + wheel = findnss(grp.getgrnam, ["wheel", "root", "staff", "adm"])[0] if backup is None: - backup = findnss(grp.getgrnam, "backup", "wheel", "root", "staff")[0] + backup = findnss(grp.getgrnam, ["backup", "wheel", "root", "staff"])[0] if aci is None: aci = "# no aci for local ldb" if serverrole is None: @@ -781,10 +794,10 @@ def provision(lp, setup_dir, message, paths, session_info, domain = netbiosname if rootdn is None: - rootdn = domaindn + rootdn = domaindn - configdn = "CN=Configuration," + rootdn - schemadn = "CN=Schema," + configdn + configdn = "CN=Configuration," + rootdn + schemadn = "CN=Schema," + configdn message("set DOMAIN SID: %s" % str(domainsid)) message("Provisioning for %s in realm %s" % (domain, realm)) -- cgit From bd0bfe683386f983318b507c5a614f818cdfb38d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 9 Feb 2008 03:09:56 +0100 Subject: Fix provision python test. (This used to be commit b173fa6bd2b24b5a3e7b4fbcb926f6c9771c10ba) --- source4/scripting/python/samba/provision.py | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index b094581fb4..7dd564fae1 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -189,20 +189,16 @@ def setup_file(template, fname, substvars): open(f, 'w').write(data) -def provision_paths_from_lp(lp, dnsdomain, private_dir=None): +def provision_paths_from_lp(lp, dnsdomain): """Set the default paths for provisioning. :param lp: Loadparm context. :param dnsdomain: DNS Domain name """ paths = ProvisionPaths() - if private_dir is None: - private_dir = lp.get("private dir") - paths.keytab = "secrets.keytab" - paths.dns_keytab = "dns.keytab" - else: - paths.keytab = os.path.join(private_dir, "secrets.keytab") - paths.dns_keytab = os.path.join(private_dir, "dns.keytab") + private_dir = lp.get("private dir") + paths.keytab = "secrets.keytab" + paths.dns_keytab = "dns.keytab" paths.shareconf = os.path.join(private_dir, "share.ldb") paths.samdb = os.path.join(private_dir, lp.get("sam database") or "samdb.ldb") @@ -469,7 +465,6 @@ def setup_registry(path, setup_path, session_info, credentials, lp): :param lp: Loadparm context """ reg = registry.Registry() - print path hive = registry.open_ldb(path, session_info=session_info, credentials=credentials, lp_ctx=lp) reg.mount_hive(hive, "HKEY_LOCAL_MACHINE") @@ -540,6 +535,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, serverrole, ldap_backend=None, ldap_backend_type=None): """Setup a complete SAM Database. + :note: This will wipe the main SAM database file! """ # Also wipes the database @@ -745,6 +741,7 @@ def provision(lp, setup_dir, message, paths, session_info, aci = "# no aci for local ldb" if serverrole is None: serverrole = lp.get("server role") + assert serverrole in ("domain controller", "member server") if invocationid is None and serverrole == "domain controller": invocationid = uuid.random() @@ -774,9 +771,9 @@ def provision(lp, setup_dir, message, paths, session_info, if not valid_netbios_name(netbiosname): raise InvalidNetbiosName(netbiosname) - dnsdomain = realm.lower() + dnsdomain = realm.lower() if serverrole == "domain controller": - domaindn = "DC=" + dnsdomain.replace(".", ",DC=") + domaindn = "DC=" + dnsdomain.replace(".", ",DC=") if domain is None: domain = lp.get("workgroup") @@ -788,7 +785,6 @@ def provision(lp, setup_dir, message, paths, session_info, domain = domain.upper() if not valid_netbios_name(domain): raise InvalidNetbiosName(domain) - else: domaindn = "CN=" + netbiosname domain = netbiosname @@ -812,8 +808,6 @@ def provision(lp, setup_dir, message, paths, session_info, smbconfsuffix = "dc" elif serverrole == "member": smbconfsuffix = "member" - else: - assert "Invalid server role setting: %s" % serverrole setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), paths.smbconf, { "HOSTNAME": hostname, @@ -953,7 +947,7 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, def load_schema(setup_path, samdb, schemadn, netbiosname, configdn): - """Load schema. + """Load schema for the SamDB. :param samdb: Load a schema into a SamDB. :param setup_path: Setup path function. -- cgit From 2fa4c158580a1e3efea7f8d121305d16eda815cb Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 9 Feb 2008 17:37:42 +0100 Subject: Fix syntax of docstrings, set project name when generating Python API documentation. (This used to be commit 68f13d87eb034fdbc712169f2d1b1a0475751ec5) --- source4/scripting/python/samba/provision.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 7dd564fae1..4f52d36167 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -278,13 +278,12 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, Alternatively, provision() may call this, and then populate the database. :param erase: Remove the existing data present in the database. - :param :note: This will wipe the Sam Database! :note: This function always removes the local SAM LDB file. The erase - parameter controls whether to erase the existing data, which - may not be stored locally but in LDAP. + parameter controls whether to erase the existing data, which + may not be stored locally but in LDAP. """ assert session_info is not None @@ -479,7 +478,6 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, :param samdb: Sam Database handle :param setup_path: Obtain setup path - ... """ setup_add_ldif(samdb, setup_path("provision_rootdse_add.ldif"), { "SCHEMADN": schemadn, -- cgit From 08e3f99f14f178e87f3543261be59a7f97f60b4f Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 13 Feb 2008 02:18:45 +0100 Subject: Initial work on a test for samba.tests.samdb (This used to be commit 8b33860954ca03be1ea45fd8d40963dbbd5b162f) --- source4/scripting/python/samba/provision.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 4f52d36167..97021fceb2 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -332,7 +332,6 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, schemadn_ldb = "schema.ldb" if ldap_backend is not None: schema_ldb = ldap_backend - schemadn_ldb = ldap_backend if ldap_backend_type == "fedora-ds": @@ -536,6 +535,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, :note: This will wipe the main SAM database file! """ + assert serverrole in ("domain controller", "member server") + # Also wipes the database setup_samdb_partitions(path, setup_path, schemadn=schemadn, configdn=configdn, domaindn=domaindn, message=message, lp=lp, -- cgit From 85fe22a85fe7e8db7d2f6e2fdd6f02836f116b8e Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 15 Feb 2008 15:14:55 +0100 Subject: Use struct for provision parameters since there are so many of them. (This used to be commit 4b9d5bc57ca4ee14c142ea720dce5e4ee97f8c16) --- source4/scripting/python/samba/provision.py | 40 ++++++++++++++++------------- 1 file changed, 22 insertions(+), 18 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 97021fceb2..d30eaf3d7f 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -271,7 +271,7 @@ def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users, def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, credentials, configdn, schemadn, domaindn, hostname, netbiosname, dnsdomain, realm, - rootdn, serverrole, ldap_backend=None, + rootdn, serverrole, sitename, ldap_backend=None, ldap_backend_type=None, erase=False): """Setup the partitions for the SAM database. @@ -378,7 +378,8 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, message("Setting up sam.ldb rootDSE") setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, - dnsdomain, realm, rootdn, configdn, netbiosname) + dnsdomain, realm, rootdn, configdn, netbiosname, + sitename) if erase: message("Erasing data from partitions") @@ -472,7 +473,8 @@ def setup_registry(path, setup_path, session_info, credentials, lp): def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, - dnsdomain, realm, rootdn, configdn, netbiosname): + dnsdomain, realm, rootdn, configdn, netbiosname, + sitename): """Setup the SamDB rootdse. :param samdb: Sam Database handle @@ -482,7 +484,7 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, "DNSDOMAIN": dnsdomain, - "DEFAULTSITE": DEFAULTSITE, + "DEFAULTSITE": sitename, "REALM": realm, "DNSNAME": "%s.%s" % (hostname, dnsdomain), "DOMAINDN": domaindn, @@ -495,7 +497,7 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, def setup_self_join(samdb, configdn, schemadn, domaindn, netbiosname, hostname, dnsdomain, machinepass, dnspass, realm, domainname, domainsid, invocationid, setup_path, - policyguid, hostguid=None): + policyguid, sitename, hostguid=None): """Join a host to its own domain.""" if hostguid is not None: hostguid_add = "objectGUID: %s" % hostguid @@ -508,7 +510,7 @@ def setup_self_join(samdb, configdn, schemadn, domaindn, "DOMAINDN": domaindn, "INVOCATIONID": invocationid, "NETBIOSNAME": netbiosname, - "DEFAULTSITE": DEFAULTSITE, + "DEFAULTSITE": sitename, "DNSNAME": "%s.%s" % (hostname, dnsdomain), "MACHINEPASS_B64": b64encode(machinepass), "DNSPASS_B64": b64encode(dnspass), @@ -529,7 +531,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, domainsid, aci, domainguid, policyguid, domainname, fill, adminpass, krbtgtpass, machinepass, hostguid, invocationid, dnspass, - serverrole, ldap_backend=None, ldap_backend_type=None): + serverrole, sitename, ldap_backend=None, + ldap_backend_type=None): """Setup a complete SAM Database. :note: This will wipe the main SAM database file! @@ -544,7 +547,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, hostname=hostname, netbiosname=netbiosname, dnsdomain=dnsdomain, realm=realm, rootdn=rootdn, ldap_backend=ldap_backend, serverrole=serverrole, - ldap_backend_type=ldap_backend_type, erase=erase) + ldap_backend_type=ldap_backend_type, erase=erase, + sitename=sitename) samdb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) @@ -562,7 +566,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, if lp.get("server role") == "domain controller": samdb.set_invocation_id(invocationid) - load_schema(setup_path, samdb, schemadn, netbiosname, configdn) + load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename) samdb.transaction_start() @@ -584,7 +588,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "DOMAINSID": str(domainsid), "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, - "DEFAULTSITE": DEFAULTSITE, + "DEFAULTSITE": sitename, "CONFIGDN": configdn, "POLICYGUID": policyguid, "DOMAINDN": domaindn, @@ -614,7 +618,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, setup_path("provision_schema_basedn_modify.ldif"), { "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, - "DEFAULTSITE": DEFAULTSITE, + "DEFAULTSITE": sitename, "CONFIGDN": configdn, }) @@ -629,7 +633,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, setup_add_ldif(samdb, setup_path("provision_configuration.ldif"), { "CONFIGDN": configdn, "NETBIOSNAME": netbiosname, - "DEFAULTSITE": DEFAULTSITE, + "DEFAULTSITE": sitename, "DNSDOMAIN": dnsdomain, "DOMAIN": domainname, "SCHEMADN": schemadn, @@ -656,7 +660,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, setup_add_ldif(samdb, setup_path("provision.ldif"), { "DOMAINDN": domaindn, "NETBIOSNAME": netbiosname, - "DEFAULTSITE": DEFAULTSITE, + "DEFAULTSITE": sitename, "CONFIGDN": configdn, }) @@ -679,7 +683,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, machinepass=machinepass, domainname=domainname, domainsid=domainsid, policyguid=policyguid, hostname=hostname, hostguid=hostguid, - setup_path=setup_path) + setup_path=setup_path, sitename=sitename) #We want to setup the index last, as adds are faster unindexed message("Setting up sam.ldb index") @@ -702,7 +706,7 @@ def provision(lp, setup_dir, message, paths, session_info, policyguid=None, invocationid=None, machinepass=None, dnspass=None, root=None, nobody=None, nogroup=None, users=None, wheel=None, backup=None, aci=None, serverrole=None, erase=False, - ldap_backend=None, ldap_backend_type=None): + ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE): """Provision samba4 :note: caution, this wipes all existing data! @@ -851,7 +855,7 @@ def provision(lp, setup_dir, message, paths, session_info, hostguid=hostguid, invocationid=invocationid, machinepass=machinepass, dnspass=dnspass, serverrole=serverrole, ldap_backend=ldap_backend, - ldap_backend_type=ldap_backend_type) + ldap_backend_type=ldap_backend_type, sitename=sitename) if lp.get("server role") == "domain controller": policy_path = os.path.join(paths.sysvol, dnsdomain, "Policies", @@ -945,7 +949,7 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, }) -def load_schema(setup_path, samdb, schemadn, netbiosname, configdn): +def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): """Load schema for the SamDB. :param samdb: Load a schema into a SamDB. @@ -962,7 +966,7 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn): "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, "CONFIGDN": configdn, - "DEFAULTSITE": DEFAULTSITE + "DEFAULTSITE":sitename }) samdb.attach_schema_from_ldif(head_data, schema_data) -- cgit From 7c96ca88c4e6fc5bd9b0c585b0700cc04e0f517c Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 16 Feb 2008 15:23:26 +0100 Subject: Formatting fixes. (This used to be commit bc0fab89e325ebb6ab870b1c3f4b263c50631b70) --- source4/scripting/python/samba/provision.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d30eaf3d7f..3e88b68509 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -335,9 +335,9 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, schemadn_ldb = ldap_backend if ldap_backend_type == "fedora-ds": - backend_modules = ["nsuniqueid","paged_searches"] + backend_modules = ["nsuniqueid", "paged_searches"] elif ldap_backend_type == "openldap": - backend_modules = ["normalise","entryuuid","paged_searches"] + backend_modules = ["normalise", "entryuuid", "paged_searches"] elif serverrole == "domain controller": backend_modules = ["repl_meta_data"] else: @@ -695,6 +695,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, samdb.transaction_commit() return samdb + FILL_FULL = "FULL" FILL_NT4SYNC = "NT4SYNC" FILL_DRS = "DRS" -- cgit From 895874d9663ccb95883579d145018ec8a8add9c8 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Mon, 18 Feb 2008 14:33:58 +0100 Subject: idmap: Handle uid->SID mapping (This used to be commit 6ac6de8476ba036eb041e054bc37e4503dc2fde8) --- source4/scripting/python/samba/provision.py | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 3e88b68509..e3c47ff4a2 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -59,6 +59,7 @@ class ProvisionPaths: self.hkpd = None self.hkpt = None self.samdb = None + self.idmapdb = None self.secrets = None self.keytab = None self.dns_keytab = None @@ -202,6 +203,7 @@ def provision_paths_from_lp(lp, dnsdomain): paths.shareconf = os.path.join(private_dir, "share.ldb") paths.samdb = os.path.join(private_dir, lp.get("sam database") or "samdb.ldb") + paths.idmapdb = os.path.join(private_dir, lp.get("idmap database") or "idmap.ldb") paths.secrets = os.path.join(private_dir, lp.get("secrets database") or "secrets.ldb") paths.templates = os.path.join(private_dir, "templates.ldb") paths.dns = os.path.join(private_dir, dnsdomain + ".zone") @@ -471,6 +473,24 @@ def setup_registry(path, setup_path, session_info, credentials, lp): assert os.path.exists(provision_reg) reg.diff_apply(provision_reg) +def setup_idmapdb(path, setup_path, session_info, credentials, lp): + """Setup the idmap database. + + :param path: path to the idmap database + :param setup_path: Function that returns a path to a setup file + :param session_info: Session information + :param credentials: Credentials + :param lp: Loadparm context + """ + if os.path.exists(path): + os.unlink(path) + + idmap_ldb = Ldb(path, session_info=session_info, credentials=credentials, + lp=lp) + + idmap_ldb.erase() + idmap_ldb.load_ldif_file_add(setup_path("idmap_init.ldif")) + return idmap_ldb def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, dnsdomain, realm, rootdn, configdn, netbiosname, @@ -844,6 +864,10 @@ def provision(lp, setup_dir, message, paths, session_info, setup_templatesdb(paths.templates, setup_path, session_info=session_info, credentials=credentials, lp=lp) + message("Setting up idmap db") + setup_idmapdb(paths.idmapdb, setup_path, session_info=session_info, + credentials=credentials, lp=lp) + samdb = setup_samdb(paths.samdb, setup_path, session_info=session_info, credentials=credentials, lp=lp, schemadn=schemadn, configdn=configdn, domaindn=domaindn, -- cgit From 9b7baec42bc00985697be895e5d21aae50322f4d Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 28 Feb 2008 08:39:45 +1100 Subject: Reorder modules to have rdn_name before objectclass. This ensures the relative DN is placed in the correct case into the DB. Andrew Bartlett (This used to be commit 16378219fbf9e8a26621f848e85426180822ea29) --- source4/scripting/python/samba/provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index e3c47ff4a2..55935b0037 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -313,9 +313,9 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, "server_sort", "extended_dn", "asq", - "samldb", "rdn_name", "objectclass", + "samldb", "kludge_acl", "operational"] tdb_modules_list = [ -- cgit From c20cf59768d585baf4524c54dadba1ec60673894 Mon Sep 17 00:00:00 2001 From: Douglas VanLeuven Date: Mon, 3 Mar 2008 11:08:59 +1100 Subject: Fix member server provision Can't add "member server" because the script aborts with null reference when no match on serverrole. This is fixed by checking for the keyword "member server". (This used to be commit 62536750ae06248a49c6b56c86d01b0062bb54f0) --- source4/scripting/python/samba/provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 55935b0037..e9aded205a 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -830,7 +830,7 @@ def provision(lp, setup_dir, message, paths, session_info, message("Setting up smb.conf") if serverrole == "domain controller": smbconfsuffix = "dc" - elif serverrole == "member": + elif serverrole == "member server": smbconfsuffix = "member" setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), paths.smbconf, { -- cgit From 4d4a898742a0439d3f60c84194b02901412f4679 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 3 Mar 2008 13:03:19 +1100 Subject: Fix failure to re-provision. Somewhere in the conversion from ejs we lost calling the 'delete partitions' code. However, we have to be careful not to wipe partitions when we are the second client connecting to an LDAP server. Andrew Bartlett (This used to be commit 272eb765b81e3eab216a07249334f9b7d20e530b) --- source4/scripting/python/samba/provision.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index e9aded205a..ea2feb981b 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -279,8 +279,6 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, Alternatively, provision() may call this, and then populate the database. - :param erase: Remove the existing data present in the database. - :note: This will wipe the Sam Database! :note: This function always removes the local SAM LDB file. The erase @@ -289,10 +287,15 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, """ assert session_info is not None - if os.path.exists(samdb_path): + samdb = SamDB(samdb_path, session_info=session_info, + credentials=credentials, lp=lp) + + # Wipes the database + try: + samdb.erase() + except: os.unlink(samdb_path) - # Also wipes the database samdb = SamDB(samdb_path, session_info=session_info, credentials=credentials, lp=lp) @@ -547,7 +550,7 @@ def setup_self_join(samdb, configdn, schemadn, domaindn, def setup_samdb(path, setup_path, session_info, credentials, lp, schemadn, configdn, domaindn, dnsdomain, realm, - netbiosname, message, hostname, rootdn, erase, + netbiosname, message, hostname, rootdn, domainsid, aci, domainguid, policyguid, domainname, fill, adminpass, krbtgtpass, machinepass, hostguid, invocationid, dnspass, @@ -560,6 +563,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, assert serverrole in ("domain controller", "member server") + erase = (fill != FILL_DRS) + # Also wipes the database setup_samdb_partitions(path, setup_path, schemadn=schemadn, configdn=configdn, domaindn=domaindn, message=message, lp=lp, @@ -726,7 +731,7 @@ def provision(lp, setup_dir, message, paths, session_info, hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None, policyguid=None, invocationid=None, machinepass=None, dnspass=None, root=None, nobody=None, nogroup=None, users=None, - wheel=None, backup=None, aci=None, serverrole=None, erase=False, + wheel=None, backup=None, aci=None, serverrole=None, ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE): """Provision samba4 @@ -873,7 +878,7 @@ def provision(lp, setup_dir, message, paths, session_info, configdn=configdn, domaindn=domaindn, dnsdomain=dnsdomain, netbiosname=netbiosname, realm=realm, message=message, hostname=hostname, - rootdn=rootdn, erase=erase, domainsid=domainsid, + rootdn=rootdn, domainsid=domainsid, aci=aci, domainguid=domainguid, policyguid=policyguid, domainname=domain, fill=samdb_fill, adminpass=adminpass, krbtgtpass=krbtgtpass, -- cgit From 7e0ef3fd0ef4dba827f331cbe43fa0524be91130 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 6 Mar 2008 21:55:26 +1100 Subject: Make Samba4 pass the NET-API-BECOMEDC test against Win2k3 (again). To make Samba4, using the python provision system, pass this test required some major rework. Untested code is broken code, and some of the refactoring for a seperate provision test (which also now passes) broke things. Similarly, the iconv work has compiled, but these codepaths have never been run (NULL pointer de-reference). In working to use a local, rather than global, loadparm context, and to support using a target directory, a few things needed to be reworked, particularly around path handling. Andrew Bartlett (This used to be commit 1169e8d7bee20477b0efbfea3534ac63c83fb3d6) --- source4/scripting/python/samba/provision.py | 214 ++++++++++++++++++---------- 1 file changed, 138 insertions(+), 76 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index ea2feb981b..ab8c51595f 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -32,6 +32,7 @@ from socket import gethostname, gethostbyname import param import registry import samba +from auth import system_session from samba import Ldb, substitute_var, valid_netbios_name, check_all_substituted from samba.samdb import SamDB import security @@ -65,6 +66,7 @@ class ProvisionPaths: self.dns_keytab = None self.dns = None self.winsdb = None + self.private_dir = None def check_install(lp, session_info, credentials): @@ -197,20 +199,20 @@ def provision_paths_from_lp(lp, dnsdomain): :param dnsdomain: DNS Domain name """ paths = ProvisionPaths() - private_dir = lp.get("private dir") + paths.private_dir = lp.get("private dir") paths.keytab = "secrets.keytab" paths.dns_keytab = "dns.keytab" - paths.shareconf = os.path.join(private_dir, "share.ldb") - paths.samdb = os.path.join(private_dir, lp.get("sam database") or "samdb.ldb") - paths.idmapdb = os.path.join(private_dir, lp.get("idmap database") or "idmap.ldb") - paths.secrets = os.path.join(private_dir, lp.get("secrets database") or "secrets.ldb") - paths.templates = os.path.join(private_dir, "templates.ldb") - paths.dns = os.path.join(private_dir, dnsdomain + ".zone") - paths.winsdb = os.path.join(private_dir, "wins.ldb") - paths.s4_ldapi_path = os.path.join(private_dir, "ldapi") - paths.smbconf = os.path.join(private_dir, "smb.conf") - paths.phpldapadminconfig = os.path.join(private_dir, + paths.shareconf = os.path.join(paths.private_dir, "share.ldb") + paths.samdb = os.path.join(paths.private_dir, lp.get("sam database") or "samdb.ldb") + paths.idmapdb = os.path.join(paths.private_dir, lp.get("idmap database") or "idmap.ldb") + paths.secrets = os.path.join(paths.private_dir, lp.get("secrets database") or "secrets.ldb") + paths.templates = os.path.join(paths.private_dir, "templates.ldb") + paths.dns = os.path.join(paths.private_dir, dnsdomain + ".zone") + paths.winsdb = os.path.join(paths.private_dir, "wins.ldb") + paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi") + paths.smbconf = os.path.join(paths.private_dir, "smb.conf") + paths.phpldapadminconfig = os.path.join(paths.private_dir, "phpldapadmin-config.php") paths.hklm = "hklm.ldb" paths.hkcr = "hkcr.ldb" @@ -588,7 +590,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, samdb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) samdb.set_domain_sid(domainsid) - if lp.get("server role") == "domain controller": + if serverrole == "domain controller": samdb.set_invocation_id(invocationid) load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename) @@ -699,7 +701,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "KRBTGTPASS_B64": b64encode(krbtgtpass), }) - if lp.get("server role") == "domain controller": + if serverrole == "domain controller": message("Setting up self join") setup_self_join(samdb, configdn=configdn, schemadn=schemadn, domaindn=domaindn, invocationid=invocationid, @@ -725,13 +727,14 @@ FILL_FULL = "FULL" FILL_NT4SYNC = "NT4SYNC" FILL_DRS = "DRS" -def provision(lp, setup_dir, message, paths, session_info, - credentials, samdb_fill=FILL_FULL, realm=None, rootdn=None, +def provision(setup_dir, message, session_info, + credentials, smbconf=None, targetdir=None, samdb_fill=FILL_FULL, realm=None, + rootdn=None, domaindn=None, schemadn=None, configdn=None, domain=None, hostname=None, hostip=None, domainsid=None, hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None, policyguid=None, invocationid=None, machinepass=None, dnspass=None, root=None, nobody=None, nogroup=None, users=None, - wheel=None, backup=None, aci=None, serverrole=None, + wheel=None, backup=None, aci=None, serverrole=None, ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE): """Provision samba4 @@ -768,6 +771,65 @@ def provision(lp, setup_dir, message, paths, session_info, backup = findnss(grp.getgrnam, ["backup", "wheel", "root", "staff"])[0] if aci is None: aci = "# no aci for local ldb" + if hostname is None: + hostname = gethostname().split(".")[0].lower() + + if hostip is None: + hostip = gethostbyname(hostname) + + netbiosname = hostname.upper() + if not valid_netbios_name(netbiosname): + raise InvalidNetbiosName(netbiosname) + + if targetdir is not None: + if not os.path.exists(targetdir): + os.mkdir(targetdir) + if not os.path.exists(os.path.join(targetdir, "etc")): + os.mkdir(os.path.join(targetdir, "etc")) + + if smbconf is None: + smbconf = os.path.join(targetdir, os.path.join("etc", "smb.conf")) + + # only install a new smb.conf if there isn't one there already + if not os.path.exists(smbconf): + message("Setting up smb.conf") + assert serverrole is not None + if serverrole == "domain controller": + smbconfsuffix = "dc" + elif serverrole == "member server": + smbconfsuffix = "member" + + assert domain is not None + assert realm is not None + + default_lp = param.LoadParm() + #Load non-existant file + default_lp.load(smbconf) + + if targetdir is not None: + privatedir_line = "private dir = " + os.path.abspath(os.path.join(targetdir, "private")) + lockdir_line = "lock dir = " + os.path.abspath(targetdir) + + default_lp.set("lock dir", os.path.abspath(targetdir)) + + sysvol = os.path.join(default_lp.get("lock dir"), "sysvol") + netlogon = os.path.join(os.path.join(sysvol, "scripts")) + + setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), + smbconf, { + "HOSTNAME": hostname, + "DOMAIN_CONF": domain, + "REALM_CONF": realm, + "SERVERROLE": serverrole, + "NETLOGONPATH": netlogon, + "SYSVOLPATH": sysvol, + "PRIVATEDIR_LINE": privatedir_line, + "LOCKDIR_LINE": lockdir_line + }) + + lp = param.LoadParm() + lp.load(smbconf) + if serverrole is None: serverrole = lp.get("server role") assert serverrole in ("domain controller", "member server") @@ -777,32 +839,26 @@ def provision(lp, setup_dir, message, paths, session_info, if realm is None: realm = lp.get("realm") - if lp.get("realm").upper() != realm.upper(): - raise Exception("realm '%s' in smb.conf must match chosen realm '%s'" % - (lp.get("realm"), realm)) - - ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="") - - if ldap_backend == "ldapi": - # provision-backend will set this path suggested slapd command line / fedorads.inf - ldap_backend = "ldapi://" % urllib.quote(os.path.join(lp.get("private dir"), "ldap", "ldapi"), safe="") - assert realm is not None realm = realm.upper() - if hostname is None: - hostname = gethostname().split(".")[0].lower() + dnsdomain = realm.lower() - if hostip is None: - hostip = gethostbyname(hostname) + paths = provision_paths_from_lp(lp, dnsdomain) - netbiosname = hostname.upper() - if not valid_netbios_name(netbiosname): - raise InvalidNetbiosName(netbiosname) + if targetdir is not None: + if not os.path.exists(paths.private_dir): + os.mkdir(paths.private_dir) + + ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="") + + if ldap_backend == "ldapi": + # provision-backend will set this path suggested slapd command line / fedorads.inf + ldap_backend = "ldapi://" % urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") - dnsdomain = realm.lower() if serverrole == "domain controller": - domaindn = "DC=" + dnsdomain.replace(".", ",DC=") + if domaindn is None: + domaindn = "DC=" + dnsdomain.replace(".", ",DC=") if domain is None: domain = lp.get("workgroup") @@ -815,38 +871,25 @@ def provision(lp, setup_dir, message, paths, session_info, if not valid_netbios_name(domain): raise InvalidNetbiosName(domain) else: - domaindn = "CN=" + netbiosname + if domaindn is None: + domaindn = "CN=" + netbiosname domain = netbiosname if rootdn is None: rootdn = domaindn - configdn = "CN=Configuration," + rootdn - schemadn = "CN=Schema," + configdn + if configdn is None: + configdn = "CN=Configuration," + rootdn + if schemadn is None: + schemadn = "CN=Schema," + configdn message("set DOMAIN SID: %s" % str(domainsid)) message("Provisioning for %s in realm %s" % (domain, realm)) message("Using administrator password: %s" % adminpass) - assert paths.smbconf is not None - - # only install a new smb.conf if there isn't one there already - if not os.path.exists(paths.smbconf): - message("Setting up smb.conf") - if serverrole == "domain controller": - smbconfsuffix = "dc" - elif serverrole == "member server": - smbconfsuffix = "member" - setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), - paths.smbconf, { - "HOSTNAME": hostname, - "DOMAIN_CONF": domain, - "REALM_CONF": realm, - "SERVERROLE": serverrole, - "NETLOGONPATH": paths.netlogon, - "SYSVOLPATH": paths.sysvol, - }) - lp.load(paths.smbconf) + if lp.get("realm").upper() != realm.upper(): + raise Exception("realm '%s' in smb.conf must match chosen realm '%s'" % + (lp.get("realm"), realm)) # only install a new shares config db if there is none if not os.path.exists(paths.shareconf): @@ -911,32 +954,52 @@ def provision(lp, setup_dir, message, paths, session_info, message("Setting up sam.ldb rootDSE marking as synchronized") setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif")) + # Only make a zone file on the first DC, it should be replicated with DNS replication + if serverrole == "domain controller": + samdb = SamDB(paths.samdb, session_info=session_info, + credentials=credentials, lp=lp) + + domainguid = samdb.searchone(basedn=domaindn, attribute="objectGUID") + assert isinstance(domainguid, str) + hostguid = samdb.searchone(basedn=domaindn, attribute="objectGUID", + expression="(&(objectClass=computer)(cn=%s))" % hostname, + scope=SCOPE_SUBTREE) + assert isinstance(hostguid, str) + + message("Setting up DNS zone: %s" % dnsdomain) + create_zone_file(paths.dns, setup_path, samdb, + hostname=hostname, hostip=hostip, dnsdomain=dnsdomain, + domaindn=domaindn, dnspass=dnspass, realm=realm, + domainguid=domainguid, hostguid=hostguid) + message("Please install the zone located in %s into your DNS server" % paths.dns) + message("Setting up phpLDAPadmin configuration") create_phpldapadmin_config(paths.phpldapadminconfig, setup_path, ldapi_url) message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) - if lp.get("server role") == "domain controller": - samdb = SamDB(paths.samdb, session_info=session_info, - credentials=credentials, lp=lp) - - domainguid = samdb.searchone(basedn=domaindn, attribute="objectGUID") - assert isinstance(domainguid, str) - hostguid = samdb.searchone(basedn=domaindn, attribute="objectGUID", - expression="(&(objectClass=computer)(cn=%s))" % hostname, - scope=SCOPE_SUBTREE) - assert isinstance(hostguid, str) - - message("Setting up DNS zone: %s" % dnsdomain) - create_zone_file(paths.dns, setup_path, samdb, - hostname=hostname, hostip=hostip, dnsdomain=dnsdomain, - domaindn=domaindn, dnspass=dnspass, realm=realm, - domainguid=domainguid, hostguid=hostguid) - message("Please install the zone located in %s into your DNS server" % paths.dns) - return domaindn +def provision_become_dc(setup_dir=None, + smbconf=None, targetdir=None, realm=None, + rootdn=None, domaindn=None, schemadn=None, configdn=None, + domain=None, hostname=None, domainsid=None, + hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None, + policyguid=None, invocationid=None, machinepass=None, + dnspass=None, root=None, nobody=None, nogroup=None, users=None, + wheel=None, backup=None, aci=None, serverrole=None, + ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE): + + def message(text): + """print a message if quiet is not set.""" + print text + + provision(setup_dir, message, system_session(), None, + smbconf=smbconf, targetdir=targetdir, samdb_fill=FILL_DRS, realm=realm, + rootdn=rootdn, domaindn=domaindn, schemadn=schemadn, configdn=configdn, + domain=domain, hostname=hostname, hostip="127.0.0.1", domainsid=domainsid, machinepass=machinepass, serverrole="domain controller", sitename=sitename); + def create_phpldapadmin_config(path, setup_path, ldapi_uri): """Create a PHP LDAP admin configuration file. @@ -978,7 +1041,6 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, "HOSTGUID": hostguid, }) - def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): """Load schema for the SamDB. -- cgit From 8b24d248b7c928fd3b20f95ede34302ca274c4ae Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 7 Mar 2008 07:33:14 +1100 Subject: Start to rework provision for LDAP backends This is the start of the rework of the provision script to handle an LDAP backend correctly. For example, we must not set the 'tdb modules' against an LDAP backend such as OpenLDAP that handles subtree renames. Andrew Bartlett (This used to be commit e462a107d3bafcc546ca4d53dcc8eb32e4280745) --- source4/scripting/python/samba/provision.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index ea2feb981b..b140071f41 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -341,12 +341,21 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, if ldap_backend_type == "fedora-ds": backend_modules = ["nsuniqueid", "paged_searches"] + # We can handle linked attributes here, as we don't have directory-side subtree operations + tdb_modules_list = ["linked_attributes"] elif ldap_backend_type == "openldap": backend_modules = ["normalise", "entryuuid", "paged_searches"] + # OpenLDAP handles subtree renames, so we don't want to do any of these things + tdb_modules_list = None elif serverrole == "domain controller": backend_modules = ["repl_meta_data"] else: backend_modules = ["objectguid"] + + if tdb_modules_list is None: + tdb_modules_list_as_string = "" + else: + tdb_modules_list_as_string = ","+",".join(tdb_modules_list) samdb.transaction_start() try: @@ -362,7 +371,7 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, "CONFIGDN_MOD": "naming_fsmo,instancetype", "DOMAINDN_MOD": "pdc_fsmo,password_hash,instancetype", "MODULES_LIST": ",".join(modules_list), - "TDB_MODULES_LIST": ","+",".join(tdb_modules_list), + "TDB_MODULES_LIST": tdb_modules_list_as_string, "MODULES_LIST2": ",".join(modules_list2), "BACKEND_MOD": ",".join(backend_modules), }) -- cgit From 14c5f968e1f99ceabc5a42d9a38a00ea137b00ea Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 7 Mar 2008 10:57:52 +1100 Subject: Rework provision scripts for more testing This fixes up some issues with testdir (was not honoured) and increases test coverage. We now check all the major provision modes. In doing so, to make it possible to call from the multiple layers of 'sh', I have allowed 'dc' to alias 'domain controller' and 'member' to alias 'member server'. Fighting shell quoting in the test system was just too hard... Also fix upgrade.py Andrew Bartlett (This used to be commit 0923de12282b0e063dd73bc3e056dd5c3663c190) --- source4/scripting/python/samba/provision.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 37c4c5b082..25c1a995ef 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -572,9 +572,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, :note: This will wipe the main SAM database file! """ - assert serverrole in ("domain controller", "member server") - - erase = (fill != FILL_DRS) + erase = (fill != FILL_DRS) # Also wipes the database setup_samdb_partitions(path, setup_path, schemadn=schemadn, configdn=configdn, @@ -796,17 +794,22 @@ def provision(setup_dir, message, session_info, if not os.path.exists(os.path.join(targetdir, "etc")): os.mkdir(os.path.join(targetdir, "etc")) - if smbconf is None: - smbconf = os.path.join(targetdir, os.path.join("etc", "smb.conf")) + smbconf = os.path.join(targetdir, os.path.join("etc", "smb.conf")) # only install a new smb.conf if there isn't one there already + if not os.path.exists(smbconf): message("Setting up smb.conf") - assert serverrole is not None + if serverrole is None: + serverrole = "standalone" + + assert serverrole in ("domain controller", "member server", "standalone") if serverrole == "domain controller": smbconfsuffix = "dc" elif serverrole == "member server": smbconfsuffix = "member" + elif serverrole == "standalone": + smbconfsuffix = "standalone" assert domain is not None assert realm is not None @@ -827,8 +830,8 @@ def provision(setup_dir, message, session_info, setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), smbconf, { "HOSTNAME": hostname, - "DOMAIN_CONF": domain, - "REALM_CONF": realm, + "DOMAIN": domain, + "REALM": realm, "SERVERROLE": serverrole, "NETLOGONPATH": netlogon, "SYSVOLPATH": sysvol, @@ -841,7 +844,7 @@ def provision(setup_dir, message, session_info, if serverrole is None: serverrole = lp.get("server role") - assert serverrole in ("domain controller", "member server") + assert serverrole in ("domain controller", "member server", "standalone") if invocationid is None and serverrole == "domain controller": invocationid = uuid.random() @@ -851,6 +854,10 @@ def provision(setup_dir, message, session_info, assert realm is not None realm = realm.upper() + if lp.get("realm").upper() != realm.upper(): + raise Exception("realm '%s' in %s must match chosen realm '%s'" % + (lp.get("realm"), smbconf, realm)) + dnsdomain = realm.lower() paths = provision_paths_from_lp(lp, dnsdomain) @@ -896,10 +903,6 @@ def provision(setup_dir, message, session_info, message("Provisioning for %s in realm %s" % (domain, realm)) message("Using administrator password: %s" % adminpass) - if lp.get("realm").upper() != realm.upper(): - raise Exception("realm '%s' in smb.conf must match chosen realm '%s'" % - (lp.get("realm"), realm)) - # only install a new shares config db if there is none if not os.path.exists(paths.shareconf): message("Setting up share.ldb") -- cgit From a7e1fa0bef17ecc46f642b23ef635acfb09fea04 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 7 Mar 2008 19:20:39 +1100 Subject: Try to fix up part of the upgrade test. There are still problems with the upgrade test, but these are not related to the provision system. Andrew Bartlett (This used to be commit d331bc400fb138bc43be88d0ca8ab3bcd590d2cd) --- source4/scripting/python/samba/provision.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 25c1a995ef..ebca1f8e40 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -68,6 +68,12 @@ class ProvisionPaths: self.winsdb = None self.private_dir = None +class ProvisionResult: + def __init__(self): + self.paths = None + self.domaindn = None + self.lp = None + self.samdb = None def check_install(lp, session_info, credentials): """Check whether the current install seems ok. @@ -991,7 +997,12 @@ def provision(setup_dir, message, session_info, message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) - return domaindn + result = ProvisionResult() + result.domaindn = domaindn + result.paths = paths + result.lp = lp + result.samdb = samdb + return result def provision_become_dc(setup_dir=None, smbconf=None, targetdir=None, realm=None, -- cgit From 9703948850fb6febb237d701ce6b6300e9df8e1f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 11 Mar 2008 14:41:10 +1100 Subject: Fix provision script to work without smb.conf location specified. Andrew Bartlett (This used to be commit b4da374a998caac18c288a0a6e3fcd2c50cbffa7) --- source4/scripting/python/samba/provision.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index ebca1f8e40..24870c2fbd 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -51,7 +51,6 @@ class InvalidNetbiosName(Exception): class ProvisionPaths: def __init__(self): - self.smbconf = None self.shareconf = None self.hklm = None self.hkcu = None @@ -217,7 +216,6 @@ def provision_paths_from_lp(lp, dnsdomain): paths.dns = os.path.join(paths.private_dir, dnsdomain + ".zone") paths.winsdb = os.path.join(paths.private_dir, "wins.ldb") paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi") - paths.smbconf = os.path.join(paths.private_dir, "smb.conf") paths.phpldapadminconfig = os.path.join(paths.private_dir, "phpldapadmin-config.php") paths.hklm = "hklm.ldb" @@ -759,6 +757,9 @@ def provision(setup_dir, message, session_info, if domainsid is None: domainsid = security.random_sid() + else: + domainsid = security.Sid(domainsid) + if policyguid is None: policyguid = uuid.random() if adminpass is None: -- cgit From 69d66e6fb09b2449dec9bf0af49408b9a6c3cc65 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 13 Mar 2008 08:08:05 +1100 Subject: Upgrade provision-backend to python. This required a large rework of the provision code, so as to move much of the 'guess' logic into subprocedures, rather than just inline in the provision code. Andrew Bartlett (This used to be commit a0754c2a857217ca831c2295b17255d8f38dfbc2) --- source4/scripting/python/samba/provision.py | 621 ++++++++++++++++++---------- 1 file changed, 411 insertions(+), 210 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 24870c2fbd..2ede4b8d3d 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -66,7 +66,27 @@ class ProvisionPaths: self.dns = None self.winsdb = None self.private_dir = None - + self.ldapdir = None + self.slapdconf = None + self.modulesconf = None + self.memberofconf = None + self.fedoradsinf = None + self.fedoradspartitions = None + +class ProvisionNames: + def __init__(self): + self.rootdn = None + self.domaindn = None + self.configdn = None + self.schemadn = None + self.ldapmanagerdn = None + self.dnsdomain = None + self.realm = None + self.netbiosname = None + self.domain = None + self.hostname = None + self.sitename = None + class ProvisionResult: def __init__(self): self.paths = None @@ -218,6 +238,18 @@ def provision_paths_from_lp(lp, dnsdomain): paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi") paths.phpldapadminconfig = os.path.join(paths.private_dir, "phpldapadmin-config.php") + paths.ldapdir = os.path.join(paths.private_dir, + "ldap") + paths.slapdconf = os.path.join(paths.ldapdir, + "slapd.conf") + paths.modulesconf = os.path.join(paths.ldapdir, + "modules.conf") + paths.memberofconf = os.path.join(paths.ldapdir, + "memberof.conf") + paths.fedoradsinf = os.path.join(paths.ldapdir, + "fedorads.inf") + paths.fedoradspartitions = os.path.join(paths.ldapdir, + "fedorads-partitions.ldif") paths.hklm = "hklm.ldb" paths.hkcr = "hkcr.ldb" paths.hkcu = "hkcu.ldb" @@ -225,16 +257,142 @@ def provision_paths_from_lp(lp, dnsdomain): paths.hkpd = "hkpd.ldb" paths.hkpt = "hkpt.ldb" - paths.sysvol = lp.get("sysvol", "path") - if paths.sysvol is None: - paths.sysvol = os.path.join(lp.get("lock dir"), "sysvol") + paths.sysvol = lp.get("path", "sysvol") - paths.netlogon = lp.get("netlogon", "path") - if paths.netlogon is None: - paths.netlogon = os.path.join(os.path.join(paths.sysvol, "scripts")) + paths.netlogon = lp.get("path", "netlogon") return paths +def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole=None, + rootdn=None, domaindn=None, configdn=None, schemadn=None, sitename=None): + + if hostname is None: + hostname = gethostname().split(".")[0].lower() + + netbiosname = hostname.upper() + if not valid_netbios_name(netbiosname): + raise InvalidNetbiosName(netbiosname) + + hostname = hostname.lower() + + if dnsdomain is None: + dnsdomain = lp.get("realm") + + if serverrole is None: + serverrole = lp.get("server role") + + assert dnsdomain is not None + realm = dnsdomain.upper() + + if lp.get("realm").upper() != realm: + raise Exception("realm '%s' in %s must match chosen realm '%s'" % + (lp.get("realm"), smbconf, realm)) + + dnsdomain = dnsdomain.lower() + + if (serverrole == "domain controller"): + if domain is None: + domain = lp.get("workgroup") + if domaindn is None: + domaindn = "DC=" + dnsdomain.replace(".", ",DC=") + if lp.get("workgroup").upper() != domain.upper(): + raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'", + lp.get("workgroup"), domain) + else: + domain = netbiosname + if domaindn is None: + domaindn = "CN=" + netbiosname + + assert domain is not None + domain = domain.upper() + if not valid_netbios_name(domain): + raise InvalidNetbiosName(domain) + + if rootdn is None: + rootdn = domaindn + + if configdn is None: + configdn = "CN=Configuration," + rootdn + if schemadn is None: + schemadn = "CN=Schema," + configdn + + if sitename is None: + sitename=DEFAULTSITE + + names = ProvisionNames() + names.rootdn = rootdn + names.domaindn = domaindn + names.configdn = configdn + names.schemadn = schemadn + names.ldapmanagerdn = "CN=Manager," + rootdn + names.dnsdomain = dnsdomain + names.domain = domain + names.realm = realm + names.netbiosname = netbiosname + names.hostname = hostname + names.sitename = sitename + + return names + + +def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, targetdir): + if targetdir is not None: + if not os.path.exists(targetdir): + os.mkdir(targetdir) + if not os.path.exists(os.path.join(targetdir, "etc")): + os.mkdir(os.path.join(targetdir, "etc")) + + smbconf = os.path.join(targetdir, "etc", "smb.conf") + + # only install a new smb.conf if there isn't one there already + + if not os.path.exists(smbconf): + if hostname is None: + hostname = gethostname().split(".")[0].lower() + + if serverrole is None: + serverrole = "standalone" + + assert serverrole in ("domain controller", "member server", "standalone") + if serverrole == "domain controller": + smbconfsuffix = "dc" + elif serverrole == "member server": + smbconfsuffix = "member" + elif serverrole == "standalone": + smbconfsuffix = "standalone" + + assert domain is not None + assert realm is not None + + default_lp = param.LoadParm() + #Load non-existant file + default_lp.load(smbconf) + + if targetdir is not None: + privatedir_line = "private dir = " + os.path.abspath(os.path.join(targetdir, "private")) + lockdir_line = "lock dir = " + os.path.abspath(targetdir) + + default_lp.set("lock dir", os.path.abspath(targetdir)) + + sysvol = os.path.join(default_lp.get("lock dir"), "sysvol") + netlogon = os.path.join(sysvol, realm.lower(), "scripts") + + setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), + smbconf, { + "HOSTNAME": hostname, + "DOMAIN": domain, + "REALM": realm, + "SERVERROLE": serverrole, + "NETLOGONPATH": netlogon, + "SYSVOLPATH": sysvol, + "PRIVATEDIR_LINE": privatedir_line, + "LOCKDIR_LINE": lockdir_line + }) + + lp = param.LoadParm() + lp.load(smbconf) + + return lp def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users, wheel, backup): @@ -277,9 +435,8 @@ def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users, def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, - credentials, configdn, schemadn, domaindn, - hostname, netbiosname, dnsdomain, realm, - rootdn, serverrole, sitename, ldap_backend=None, + credentials, names, + serverrole, ldap_backend=None, ldap_backend_type=None, erase=False): """Setup the partitions for the SAM database. @@ -366,12 +523,12 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, samdb.transaction_start() try: setup_add_ldif(samdb, setup_path("provision_partitions.ldif"), { - "SCHEMADN": schemadn, + "SCHEMADN": names.schemadn, "SCHEMADN_LDB": schemadn_ldb, "SCHEMADN_MOD2": ",objectguid", - "CONFIGDN": configdn, + "CONFIGDN": names.configdn, "CONFIGDN_LDB": configdn_ldb, - "DOMAINDN": domaindn, + "DOMAINDN": names.domaindn, "DOMAINDN_LDB": domaindn_ldb, "SCHEMADN_MOD": "schema_fsmo,instancetype", "CONFIGDN_MOD": "naming_fsmo,instancetype", @@ -397,9 +554,9 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, samdb.load_ldif_file_add(setup_path("provision_init.ldif")) message("Setting up sam.ldb rootDSE") - setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, - dnsdomain, realm, rootdn, configdn, netbiosname, - sitename) + setup_samdb_rootdse(samdb, setup_path, names.schemadn, names.domaindn, names.hostname, + names.dnsdomain, names.realm, names.rootdn, names.configdn, names.netbiosname, + names.sitename) if erase: message("Erasing data from partitions") @@ -532,10 +689,10 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, }) -def setup_self_join(samdb, configdn, schemadn, domaindn, - netbiosname, hostname, dnsdomain, machinepass, dnspass, - realm, domainname, domainsid, invocationid, setup_path, - policyguid, sitename, hostguid=None): +def setup_self_join(samdb, names, + machinepass, dnspass, + domainsid, invocationid, setup_path, + policyguid, hostguid=None): """Join a host to its own domain.""" if hostguid is not None: hostguid_add = "objectGUID: %s" % hostguid @@ -543,33 +700,32 @@ def setup_self_join(samdb, configdn, schemadn, domaindn, hostguid_add = "" setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), { - "CONFIGDN": configdn, - "SCHEMADN": schemadn, - "DOMAINDN": domaindn, + "CONFIGDN": names.configdn, + "SCHEMADN": names.schemadn, + "DOMAINDN": names.domaindn, "INVOCATIONID": invocationid, - "NETBIOSNAME": netbiosname, - "DEFAULTSITE": sitename, - "DNSNAME": "%s.%s" % (hostname, dnsdomain), + "NETBIOSNAME": names.netbiosname, + "DEFAULTSITE": names.sitename, + "DNSNAME": "%s.%s" % (names.hostname, names.dnsdomain), "MACHINEPASS_B64": b64encode(machinepass), "DNSPASS_B64": b64encode(dnspass), - "REALM": realm, - "DOMAIN": domainname, + "REALM": names.realm, + "DOMAIN": names.domain, "HOSTGUID_ADD": hostguid_add, - "DNSDOMAIN": dnsdomain}) + "DNSDOMAIN": names.dnsdomain}) setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), { "POLICYGUID": policyguid, - "DNSDOMAIN": dnsdomain, + "DNSDOMAIN": names.dnsdomain, "DOMAINSID": str(domainsid), - "DOMAINDN": domaindn}) + "DOMAINDN": names.domaindn}) def setup_samdb(path, setup_path, session_info, credentials, lp, - schemadn, configdn, domaindn, dnsdomain, realm, - netbiosname, message, hostname, rootdn, + names, message, domainsid, aci, domainguid, policyguid, - domainname, fill, adminpass, krbtgtpass, + fill, adminpass, krbtgtpass, machinepass, hostguid, invocationid, dnspass, - serverrole, sitename, ldap_backend=None, + serverrole, ldap_backend=None, ldap_backend_type=None): """Setup a complete SAM Database. @@ -579,14 +735,11 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, erase = (fill != FILL_DRS) # Also wipes the database - setup_samdb_partitions(path, setup_path, schemadn=schemadn, configdn=configdn, - domaindn=domaindn, message=message, lp=lp, + setup_samdb_partitions(path, setup_path, message=message, lp=lp, credentials=credentials, session_info=session_info, - hostname=hostname, netbiosname=netbiosname, - dnsdomain=dnsdomain, realm=realm, rootdn=rootdn, + names=names, ldap_backend=ldap_backend, serverrole=serverrole, - ldap_backend_type=ldap_backend_type, erase=erase, - sitename=sitename) + ldap_backend_type=ldap_backend_type, erase=erase) samdb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) @@ -604,18 +757,18 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, if serverrole == "domain controller": samdb.set_invocation_id(invocationid) - load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename) + load_schema(setup_path, samdb, names.schemadn, names.netbiosname, names.configdn, names.sitename) samdb.transaction_start() try: - message("Adding DomainDN: %s (permitted to fail)" % domaindn) + message("Adding DomainDN: %s (permitted to fail)" % names.domaindn) setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), { - "DOMAINDN": domaindn, + "DOMAINDN": names.domaindn, "ACI": aci, }) - message("Modifying DomainDN: " + domaindn + "") + message("Modifying DomainDN: " + names.domaindn + "") if domainguid is not None: domainguid_mod = "replace: objectGUID\nobjectGUID: %s\n-" % domainguid else: @@ -624,104 +777,102 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, setup_modify_ldif(samdb, setup_path("provision_basedn_modify.ldif"), { "LDAPTIME": timestring(int(time.time())), "DOMAINSID": str(domainsid), - "SCHEMADN": schemadn, - "NETBIOSNAME": netbiosname, - "DEFAULTSITE": sitename, - "CONFIGDN": configdn, + "SCHEMADN": names.schemadn, + "NETBIOSNAME": names.netbiosname, + "DEFAULTSITE": names.sitename, + "CONFIGDN": names.configdn, "POLICYGUID": policyguid, - "DOMAINDN": domaindn, + "DOMAINDN": names.domaindn, "DOMAINGUID_MOD": domainguid_mod, }) message("Adding configuration container (permitted to fail)") setup_add_ldif(samdb, setup_path("provision_configuration_basedn.ldif"), { - "CONFIGDN": configdn, + "CONFIGDN": names.configdn, "ACI": aci, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", }) message("Modifying configuration container") setup_modify_ldif(samdb, setup_path("provision_configuration_basedn_modify.ldif"), { - "CONFIGDN": configdn, - "SCHEMADN": schemadn, + "CONFIGDN": names.configdn, + "SCHEMADN": names.schemadn, }) message("Adding schema container (permitted to fail)") setup_add_ldif(samdb, setup_path("provision_schema_basedn.ldif"), { - "SCHEMADN": schemadn, + "SCHEMADN": names.schemadn, "ACI": aci, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" }) message("Modifying schema container") setup_modify_ldif(samdb, setup_path("provision_schema_basedn_modify.ldif"), { - "SCHEMADN": schemadn, - "NETBIOSNAME": netbiosname, - "DEFAULTSITE": sitename, - "CONFIGDN": configdn, + "SCHEMADN": names.schemadn, + "NETBIOSNAME": names.netbiosname, + "DEFAULTSITE": names.sitename, + "CONFIGDN": names.configdn, }) message("Setting up sam.ldb Samba4 schema") setup_add_ldif(samdb, setup_path("schema_samba4.ldif"), - {"SCHEMADN": schemadn }) + {"SCHEMADN": names.schemadn }) message("Setting up sam.ldb AD schema") setup_add_ldif(samdb, setup_path("schema.ldif"), - {"SCHEMADN": schemadn}) + {"SCHEMADN": names.schemadn}) message("Setting up sam.ldb configuration data") setup_add_ldif(samdb, setup_path("provision_configuration.ldif"), { - "CONFIGDN": configdn, - "NETBIOSNAME": netbiosname, - "DEFAULTSITE": sitename, - "DNSDOMAIN": dnsdomain, - "DOMAIN": domainname, - "SCHEMADN": schemadn, - "DOMAINDN": domaindn, + "CONFIGDN": names.configdn, + "NETBIOSNAME": names.netbiosname, + "DEFAULTSITE": names.sitename, + "DNSDOMAIN": names.dnsdomain, + "DOMAIN": names.domain, + "SCHEMADN": names.schemadn, + "DOMAINDN": names.domaindn, }) message("Setting up display specifiers") setup_add_ldif(samdb, setup_path("display_specifiers.ldif"), - {"CONFIGDN": configdn}) + {"CONFIGDN": names.configdn}) message("Adding users container (permitted to fail)") setup_add_ldif(samdb, setup_path("provision_users_add.ldif"), { - "DOMAINDN": domaindn}) + "DOMAINDN": names.domaindn}) message("Modifying users container") setup_modify_ldif(samdb, setup_path("provision_users_modify.ldif"), { - "DOMAINDN": domaindn}) + "DOMAINDN": names.domaindn}) message("Adding computers container (permitted to fail)") setup_add_ldif(samdb, setup_path("provision_computers_add.ldif"), { - "DOMAINDN": domaindn}) + "DOMAINDN": names.domaindn}) message("Modifying computers container") setup_modify_ldif(samdb, setup_path("provision_computers_modify.ldif"), { - "DOMAINDN": domaindn}) + "DOMAINDN": names.domaindn}) message("Setting up sam.ldb data") setup_add_ldif(samdb, setup_path("provision.ldif"), { - "DOMAINDN": domaindn, - "NETBIOSNAME": netbiosname, - "DEFAULTSITE": sitename, - "CONFIGDN": configdn, + "DOMAINDN": names.domaindn, + "NETBIOSNAME": names.netbiosname, + "DEFAULTSITE": names.sitename, + "CONFIGDN": names.configdn, }) if fill == FILL_FULL: message("Setting up sam.ldb users and groups") setup_add_ldif(samdb, setup_path("provision_users.ldif"), { - "DOMAINDN": domaindn, + "DOMAINDN": names.domaindn, "DOMAINSID": str(domainsid), - "CONFIGDN": configdn, + "CONFIGDN": names.configdn, "ADMINPASS_B64": b64encode(adminpass), "KRBTGTPASS_B64": b64encode(krbtgtpass), }) if serverrole == "domain controller": message("Setting up self join") - setup_self_join(samdb, configdn=configdn, schemadn=schemadn, - domaindn=domaindn, invocationid=invocationid, - dnspass=dnspass, netbiosname=netbiosname, - dnsdomain=dnsdomain, realm=realm, - machinepass=machinepass, domainname=domainname, + setup_self_join(samdb, names=names, invocationid=invocationid, + dnspass=dnspass, + machinepass=machinepass, domainsid=domainsid, policyguid=policyguid, - hostname=hostname, hostguid=hostguid, - setup_path=setup_path, sitename=sitename) + hostguid=hostguid, + setup_path=setup_path) #We want to setup the index last, as adds are faster unindexed message("Setting up sam.ldb index") @@ -746,7 +897,7 @@ def provision(setup_dir, message, session_info, policyguid=None, invocationid=None, machinepass=None, dnspass=None, root=None, nobody=None, nogroup=None, users=None, wheel=None, backup=None, aci=None, serverrole=None, - ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE): + ldap_backend=None, ldap_backend_type=None, sitename=None): """Provision samba4 :note: caution, this wipes all existing data! @@ -785,129 +936,37 @@ def provision(setup_dir, message, session_info, backup = findnss(grp.getgrnam, ["backup", "wheel", "root", "staff"])[0] if aci is None: aci = "# no aci for local ldb" - if hostname is None: - hostname = gethostname().split(".")[0].lower() - if hostip is None: - hostip = gethostbyname(hostname) + lp = load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, targetdir) - netbiosname = hostname.upper() - if not valid_netbios_name(netbiosname): - raise InvalidNetbiosName(netbiosname) + names = guess_names(lp=lp, hostname=hostname, domain=domain, + dnsdomain=realm, serverrole=serverrole, sitename=sitename, + rootdn=rootdn, domaindn=domaindn, configdn=configdn, schemadn=schemadn) - if targetdir is not None: - if not os.path.exists(targetdir): - os.mkdir(targetdir) - if not os.path.exists(os.path.join(targetdir, "etc")): - os.mkdir(os.path.join(targetdir, "etc")) - - smbconf = os.path.join(targetdir, os.path.join("etc", "smb.conf")) - - # only install a new smb.conf if there isn't one there already - - if not os.path.exists(smbconf): - message("Setting up smb.conf") - if serverrole is None: - serverrole = "standalone" - - assert serverrole in ("domain controller", "member server", "standalone") - if serverrole == "domain controller": - smbconfsuffix = "dc" - elif serverrole == "member server": - smbconfsuffix = "member" - elif serverrole == "standalone": - smbconfsuffix = "standalone" - - assert domain is not None - assert realm is not None - - default_lp = param.LoadParm() - #Load non-existant file - default_lp.load(smbconf) - - if targetdir is not None: - privatedir_line = "private dir = " + os.path.abspath(os.path.join(targetdir, "private")) - lockdir_line = "lock dir = " + os.path.abspath(targetdir) - - default_lp.set("lock dir", os.path.abspath(targetdir)) - - sysvol = os.path.join(default_lp.get("lock dir"), "sysvol") - netlogon = os.path.join(os.path.join(sysvol, "scripts")) - - setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), - smbconf, { - "HOSTNAME": hostname, - "DOMAIN": domain, - "REALM": realm, - "SERVERROLE": serverrole, - "NETLOGONPATH": netlogon, - "SYSVOLPATH": sysvol, - "PRIVATEDIR_LINE": privatedir_line, - "LOCKDIR_LINE": lockdir_line - }) + paths = provision_paths_from_lp(lp, names.dnsdomain) - lp = param.LoadParm() - lp.load(smbconf) + if hostip is None: + hostip = gethostbyname(names.hostname) if serverrole is None: serverrole = lp.get("server role") + assert serverrole in ("domain controller", "member server", "standalone") if invocationid is None and serverrole == "domain controller": invocationid = uuid.random() - if realm is None: - realm = lp.get("realm") - - assert realm is not None - realm = realm.upper() - - if lp.get("realm").upper() != realm.upper(): - raise Exception("realm '%s' in %s must match chosen realm '%s'" % - (lp.get("realm"), smbconf, realm)) - - dnsdomain = realm.lower() - - paths = provision_paths_from_lp(lp, dnsdomain) - - if targetdir is not None: - if not os.path.exists(paths.private_dir): - os.mkdir(paths.private_dir) + if not os.path.exists(paths.private_dir): + os.mkdir(paths.private_dir) ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="") - if ldap_backend == "ldapi": - # provision-backend will set this path suggested slapd command line / fedorads.inf - ldap_backend = "ldapi://" % urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") - - if serverrole == "domain controller": - if domaindn is None: - domaindn = "DC=" + dnsdomain.replace(".", ",DC=") - if domain is None: - domain = lp.get("workgroup") - - if lp.get("workgroup").upper() != domain.upper(): - raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'", - lp.get("workgroup"), domain) - - assert domain is not None - domain = domain.upper() - if not valid_netbios_name(domain): - raise InvalidNetbiosName(domain) - else: - if domaindn is None: - domaindn = "CN=" + netbiosname - domain = netbiosname - - if rootdn is None: - rootdn = domaindn - - if configdn is None: - configdn = "CN=Configuration," + rootdn - if schemadn is None: - schemadn = "CN=Schema," + configdn - + if ldap_backend is not None: + if ldap_backend == "ldapi": + # provision-backend will set this path suggested slapd command line / fedorads.inf + ldap_backend = "ldapi://" % urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") + message("set DOMAIN SID: %s" % str(domainsid)) - message("Provisioning for %s in realm %s" % (domain, realm)) + message("Provisioning for %s in realm %s" % (names.domain, realm)) message("Using administrator password: %s" % adminpass) # only install a new shares config db if there is none @@ -936,21 +995,19 @@ def provision(setup_dir, message, session_info, credentials=credentials, lp=lp) samdb = setup_samdb(paths.samdb, setup_path, session_info=session_info, - credentials=credentials, lp=lp, schemadn=schemadn, - configdn=configdn, domaindn=domaindn, - dnsdomain=dnsdomain, netbiosname=netbiosname, - realm=realm, message=message, hostname=hostname, - rootdn=rootdn, domainsid=domainsid, + credentials=credentials, lp=lp, names=names, + message=message, + domainsid=domainsid, aci=aci, domainguid=domainguid, policyguid=policyguid, - domainname=domain, fill=samdb_fill, + fill=samdb_fill, adminpass=adminpass, krbtgtpass=krbtgtpass, hostguid=hostguid, invocationid=invocationid, machinepass=machinepass, dnspass=dnspass, serverrole=serverrole, ldap_backend=ldap_backend, - ldap_backend_type=ldap_backend_type, sitename=sitename) + ldap_backend_type=ldap_backend_type) if lp.get("server role") == "domain controller": - policy_path = os.path.join(paths.sysvol, dnsdomain, "Policies", + policy_path = os.path.join(paths.sysvol, names.dnsdomain, "Policies", "{" + policyguid + "}") os.makedirs(policy_path, 0755) os.makedirs(os.path.join(policy_path, "Machine"), 0755) @@ -959,14 +1016,14 @@ def provision(setup_dir, message, session_info, os.makedirs(paths.netlogon, 0755) secrets_ldb = Ldb(paths.secrets, session_info=session_info, credentials=credentials, lp=lp) - secretsdb_become_dc(secrets_ldb, setup_path, domain=domain, realm=realm, - netbiosname=netbiosname, domainsid=domainsid, + secretsdb_become_dc(secrets_ldb, setup_path, domain=domain, realm=names.realm, + netbiosname=names.netbiosname, domainsid=domainsid, keytab_path=paths.keytab, samdb_url=paths.samdb, dns_keytab_path=paths.dns_keytab, dnspass=dnspass, - machinepass=machinepass, dnsdomain=dnsdomain) + machinepass=machinepass, dnsdomain=names.dnsdomain) if samdb_fill == FILL_FULL: - setup_name_mappings(samdb, str(domainsid), domaindn, root=root, + setup_name_mappings(samdb, str(domainsid), names.domaindn, root=root, nobody=nobody, nogroup=nogroup, wheel=wheel, users=users, backup=backup) @@ -981,14 +1038,14 @@ def provision(setup_dir, message, session_info, domainguid = samdb.searchone(basedn=domaindn, attribute="objectGUID") assert isinstance(domainguid, str) hostguid = samdb.searchone(basedn=domaindn, attribute="objectGUID", - expression="(&(objectClass=computer)(cn=%s))" % hostname, + expression="(&(objectClass=computer)(cn=%s))" % names.hostname, scope=SCOPE_SUBTREE) assert isinstance(hostguid, str) - message("Setting up DNS zone: %s" % dnsdomain) + message("Setting up DNS zone: %s" % names.dnsdomain) create_zone_file(paths.dns, setup_path, samdb, - hostname=hostname, hostip=hostip, dnsdomain=dnsdomain, - domaindn=domaindn, dnspass=dnspass, realm=realm, + hostname=names.hostname, hostip=hostip, dnsdomain=names.dnsdomain, + domaindn=names.domaindn, dnspass=dnspass, realm=names.realm, domainguid=domainguid, hostguid=hostguid) message("Please install the zone located in %s into your DNS server" % paths.dns) @@ -1025,6 +1082,150 @@ def provision_become_dc(setup_dir=None, domain=domain, hostname=hostname, hostip="127.0.0.1", domainsid=domainsid, machinepass=machinepass, serverrole="domain controller", sitename=sitename); +def setup_db_config(setup_path, file, dbdir): + if not os.path.isdir(os.path.join(dbdir, "bdb-logs")): + os.makedirs(os.path.join(dbdir, "bdb-logs"), 0700); + if not os.path.isdir(os.path.join(dbdir, "tmp")): + os.makedirs(os.path.join(dbdir, "tmp"), 0700); + + setup_file(setup_path("DB_CONFIG"), os.path.join(dbdir, "DB_CONFIG"), + {"LDAPDBDIR": dbdir}) + + + +def provision_backend(setup_dir=None, message=None, + smbconf=None, targetdir=None, realm=None, + rootdn=None, domaindn=None, schemadn=None, configdn=None, + domain=None, hostname=None, adminpass=None, root=None, serverrole=None, + ldap_backend_type=None): + + def setup_path(file): + return os.path.join(setup_dir, file) + + if hostname is None: + hostname = gethostname().split(".")[0].lower() + + if root is None: + root = findnss(pwd.getpwnam, ["root"])[0] + + lp = load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, targetdir) + + names = guess_names(lp=lp, hostname=hostname, domain=domain, + dnsdomain=realm, serverrole=serverrole, + rootdn=rootdn, domaindn=domaindn, configdn=configdn, schemadn=schemadn) + + paths = provision_paths_from_lp(lp, names.dnsdomain) + + if not os.path.isdir(paths.ldapdir): + os.makedirs(paths.ldapdir) + schemadb_path = os.path.join(paths.ldapdir, "schema-tmp.ldb") + try: + os.unlink(schemadb_path) + except: + pass + + schemadb = Ldb(schemadb_path, lp=lp) + + setup_add_ldif(schemadb, setup_path("provision_schema_basedn.ldif"), + {"SCHEMADN": names.schemadn, + "ACI": "#", + "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" + }) + setup_modify_ldif(schemadb, + setup_path("provision_schema_basedn_modify.ldif"), \ + {"SCHEMADN": names.schemadn, + "NETBIOSNAME": names.netbiosname, + "DEFAULTSITE": DEFAULTSITE, + "CONFIGDN": names.configdn, + }) + + setup_add_ldif(schemadb, setup_path("schema_samba4.ldif"), + {"SCHEMADN": names.schemadn }) + setup_add_ldif(schemadb, setup_path("schema.ldif"), + {"SCHEMADN": names.schemadn}) + + if ldap_backend_type == "fedora-ds": + setup_file(setup_path("fedora-ds.inf"), paths.fedoradsinf, + {"ROOT": root, + "HOSTNAME": hostname, + "DNSDOMAIN": names.dnsdomain, + "LDAPDIR": paths.ldapdir, + "DOMAINDN": names.domaindn, + "LDAPMANAGERDN": names.ldapmanagerdn, + "LDAPMANAGERPASS": adminpass, + "SERVERPORT": ""}) + + setup_file(setup_path("fedora-partitions.ldif"), paths.fedoradspartitions, + {"CONFIGDN": names.configdn, + "SCHEMADN": names.schemadn, + }) + + setup_file(setup_path("fedora-partitions.ldif"), paths.fedoradspartitions, + {"CONFIGDN": names.configdn, + "SCHEMADN": names.schemadn, + }) + mapping = "schema-map-fedora-ds-1.0" + backend_schema = "99_ad.ldif" + elif ldap_backend_type == "openldap": + setup_file(setup_path("slapd.conf"), paths.slapdconf, + {"DNSDOMAIN": names.dnsdomain, + "LDAPDIR": paths.ldapdir, + "DOMAINDN": names.domaindn, + "CONFIGDN": names.configdn, + "SCHEMADN": names.schemadn, + "LDAPMANAGERDN": names.ldapmanagerdn, + "LDAPMANAGERPASS": adminpass}) + setup_file(setup_path("modules.conf"), paths.modulesconf, + {"REALM": names.realm}) + + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "user")) + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "config")) + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "schema")) + mapping = "schema-map-openldap-2.3" + backend_schema = "backend-schema.schema" + + attrs = ["linkID", "lDAPDisplayName"] + res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs); + + memberof_config = "# This is a generated file, do not edit!\n"; + refint_attributes = ""; + for i in range (0, len(res)): + linkid = res[i]["linkID"][0] + linkid = str(int(linkid) + 1) + target = schemadb.searchone(basedn=names.schemadn, + expression="(&(objectclass=attributeSchema)(linkID=" + (linkid) + "))", + attribute="lDAPDisplayName"); + if target is not None: + refint_attributes = refint_attributes + " " + target + " " + res[i]["lDAPDisplayName"]; + memberof_config = memberof_config + """overlay memberof +memberof-dangling error +memberof-refint TRUE +memberof-group-oc top +memberof-member-ad """ + res[i]["lDAPDisplayName"] + """ +memberof-memberof-ad """ + target + """ +memberof-dangling-error 32 + +"""; + + memberof_config = memberof_config + """ +overlay refint +refint_attributes""" + refint_attributes + "\n"; + + if os.path.exists(paths.memberofconf): + os.unlink(paths.memberof.conf) + + open(paths.memberofconf, 'w').write(memberof_config) + + ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") + message("Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri) + + + schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema); + + os.system(schema_command) + + + def create_phpldapadmin_config(path, setup_path, ldapi_uri): """Create a PHP LDAP admin configuration file. -- cgit From 07a7c8fa0d76cb7cb10cc88fb5bbe5439b746d01 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 13 Mar 2008 09:55:06 +1100 Subject: Update the provision scripts and selftest for LDAP This should allow us to provision onto an OpenLDAP backend again. Also ensure we always have a sysvol and netlogon share in the selftest environment. Andrew Bartlett (This used to be commit b2d9b03ba3434e76d4d476233a198728523d17f9) --- source4/scripting/python/samba/provision.py | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 2ede4b8d3d..f9604a84b2 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1192,16 +1192,18 @@ def provision_backend(setup_dir=None, message=None, for i in range (0, len(res)): linkid = res[i]["linkID"][0] linkid = str(int(linkid) + 1) + expression = "(&(objectclass=attributeSchema)(linkID=" + (linkid) + "))" target = schemadb.searchone(basedn=names.schemadn, - expression="(&(objectclass=attributeSchema)(linkID=" + (linkid) + "))", - attribute="lDAPDisplayName"); + expression=expression, + attribute="lDAPDisplayName", + scope=SCOPE_SUBTREE); if target is not None: - refint_attributes = refint_attributes + " " + target + " " + res[i]["lDAPDisplayName"]; + refint_attributes = refint_attributes + " " + target + " " + res[i]["lDAPDisplayName"][0]; memberof_config = memberof_config + """overlay memberof memberof-dangling error memberof-refint TRUE memberof-group-oc top -memberof-member-ad """ + res[i]["lDAPDisplayName"] + """ +memberof-member-ad """ + res[i]["lDAPDisplayName"][0] + """ memberof-memberof-ad """ + target + """ memberof-dangling-error 32 @@ -1214,7 +1216,7 @@ refint_attributes""" + refint_attributes + "\n"; if os.path.exists(paths.memberofconf): os.unlink(paths.memberof.conf) - open(paths.memberofconf, 'w').write(memberof_config) + open(paths.memberofconf, 'w').write(memberof_config) ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") message("Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri) -- cgit From 0c882402360a10b19a038bce9f87e241051c9ba8 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 13 Mar 2008 11:36:58 +1100 Subject: Rework to have member server 'domains' be CN=NETBIOSNAME This reworks quite a few parts of our provision system to use CN=NETBIOSNAME as the domain for member servers. This makes it clear that these domains are not in the DNS structure, while complying with our own schema (found by OpenLDAP's schema validation). Andrew Bartlett (This used to be commit bda6a38b055fed2394e65cdc0b308a1442116402) --- source4/scripting/python/samba/provision.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index f9604a84b2..25316e888a 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -763,9 +763,15 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, try: message("Adding DomainDN: %s (permitted to fail)" % names.domaindn) + if serverrole == "domain controller": + domain_oc = "domainDNS" + else: + domain_oc = "samba4LocalDomain" + setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), { "DOMAINDN": names.domaindn, "ACI": aci, + "DOMAIN_OC": domain_oc }) message("Modifying DomainDN: " + names.domaindn + "") -- cgit From d7299d82c31f08750d5d378b0e1f0226dbff5d05 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 15 Mar 2008 19:03:04 +1100 Subject: Rework memberof handling in slapd.conf (used for OpenLDAP backend) Instead of using an include file, put the generated configurationd directly into slapd.conf. Andrew Bartlett (This used to be commit 95ac786136aebfe5ededeb3fb81cbd4e296e3988) --- source4/scripting/python/samba/provision.py | 41 +++++++++++++---------------- 1 file changed, 19 insertions(+), 22 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 25316e888a..47d00f8871 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1173,27 +1173,10 @@ def provision_backend(setup_dir=None, message=None, mapping = "schema-map-fedora-ds-1.0" backend_schema = "99_ad.ldif" elif ldap_backend_type == "openldap": - setup_file(setup_path("slapd.conf"), paths.slapdconf, - {"DNSDOMAIN": names.dnsdomain, - "LDAPDIR": paths.ldapdir, - "DOMAINDN": names.domaindn, - "CONFIGDN": names.configdn, - "SCHEMADN": names.schemadn, - "LDAPMANAGERDN": names.ldapmanagerdn, - "LDAPMANAGERPASS": adminpass}) - setup_file(setup_path("modules.conf"), paths.modulesconf, - {"REALM": names.realm}) - - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "user")) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "config")) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "schema")) - mapping = "schema-map-openldap-2.3" - backend_schema = "backend-schema.schema" - attrs = ["linkID", "lDAPDisplayName"] res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs); - memberof_config = "# This is a generated file, do not edit!\n"; + memberof_config = "# Generated from schema in " + schemadb_path + "\n"; refint_attributes = ""; for i in range (0, len(res)): linkid = res[i]["linkID"][0] @@ -1219,10 +1202,24 @@ memberof-dangling-error 32 overlay refint refint_attributes""" + refint_attributes + "\n"; - if os.path.exists(paths.memberofconf): - os.unlink(paths.memberof.conf) - - open(paths.memberofconf, 'w').write(memberof_config) + setup_file(setup_path("slapd.conf"), paths.slapdconf, + {"DNSDOMAIN": names.dnsdomain, + "LDAPDIR": paths.ldapdir, + "DOMAINDN": names.domaindn, + "CONFIGDN": names.configdn, + "SCHEMADN": names.schemadn, + "LDAPMANAGERDN": names.ldapmanagerdn, + "LDAPMANAGERPASS": adminpass, + "MEMBEROF_CONFIG": memberof_config}) + setup_file(setup_path("modules.conf"), paths.modulesconf, + {"REALM": names.realm}) + + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "user")) + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "config")) + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "schema")) + mapping = "schema-map-openldap-2.3" + backend_schema = "backend-schema.schema" + ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") message("Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri) -- cgit From 677dc6aa897aed0919050545155fbd868c210b89 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Thu, 27 Mar 2008 17:49:56 +0100 Subject: provision: Initialize uninitialized variables if "targetdir" is not defined and there is no smb.conf file (This used to be commit 19c29f473883be0a17fa740de9feb226f347df4a) --- source4/scripting/python/samba/provision.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 47d00f8871..e97ce694b4 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -373,7 +373,10 @@ def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrol lockdir_line = "lock dir = " + os.path.abspath(targetdir) default_lp.set("lock dir", os.path.abspath(targetdir)) - + else: + privatedir_line = "private_dir = " + default_lp.get("private dir") + lockdir_line = "lock dir = " + default_lp.get("lock dir") + sysvol = os.path.join(default_lp.get("lock dir"), "sysvol") netlogon = os.path.join(sysvol, realm.lower(), "scripts") -- cgit From 4ddce8c28ca5abe2ac52cfb3a2956803f585b51a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 28 Mar 2008 10:38:12 +1100 Subject: Don't specify what should be a default option in the generated smb.conf Instead, sub in "", so that the default continued to come from the code. Andrew Bartlett (This used to be commit b1829da8f75175fcc569a3a9195f2358731055a9) --- source4/scripting/python/samba/provision.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index e97ce694b4..d5e66d842c 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -374,8 +374,8 @@ def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrol default_lp.set("lock dir", os.path.abspath(targetdir)) else: - privatedir_line = "private_dir = " + default_lp.get("private dir") - lockdir_line = "lock dir = " + default_lp.get("lock dir") + privatedir_line = "" + lockdir_line = "" sysvol = os.path.join(default_lp.get("lock dir"), "sysvol") netlogon = os.path.join(sysvol, realm.lower(), "scripts") -- cgit From 238a1a52f1fd3cce0a0fd980c1717c8540a1c7a1 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 29 Mar 2008 17:17:56 +1100 Subject: Rework 'compleated' message in provision to be more useful. In particular, this should draw attention to accidential 'standalone' server provisions and therefore cause less frustration. Andrew Bartlett (This used to be commit e906ae041a2b589ffceff97b74f7c4b01386382a) --- source4/scripting/python/samba/provision.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d5e66d842c..b03457e57b 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -974,10 +974,6 @@ def provision(setup_dir, message, session_info, # provision-backend will set this path suggested slapd command line / fedorads.inf ldap_backend = "ldapi://" % urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") - message("set DOMAIN SID: %s" % str(domainsid)) - message("Provisioning for %s in realm %s" % (names.domain, realm)) - message("Using administrator password: %s" % adminpass) - # only install a new shares config db if there is none if not os.path.exists(paths.shareconf): message("Setting up share.ldb") @@ -1036,7 +1032,7 @@ def provision(setup_dir, message, session_info, nobody=nobody, nogroup=nogroup, wheel=wheel, users=users, backup=backup) - message("Setting up sam.ldb rootDSE marking as synchronized") + message("Compleating sam.ldb setup by marking as synchronized") setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif")) # Only make a zone file on the first DC, it should be replicated with DNS replication @@ -1051,19 +1047,25 @@ def provision(setup_dir, message, session_info, scope=SCOPE_SUBTREE) assert isinstance(hostguid, str) - message("Setting up DNS zone: %s" % names.dnsdomain) create_zone_file(paths.dns, setup_path, samdb, hostname=names.hostname, hostip=hostip, dnsdomain=names.dnsdomain, domaindn=names.domaindn, dnspass=dnspass, realm=names.realm, domainguid=domainguid, hostguid=hostguid) message("Please install the zone located in %s into your DNS server" % paths.dns) - message("Setting up phpLDAPadmin configuration") create_phpldapadmin_config(paths.phpldapadminconfig, setup_path, ldapi_url) message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) + message("Once the above files are installed, your server will be ready to use") + message("Server Type: %s" % serverrole) + message("Hostname: %s" % names.hostname) + message("NetBIOS Domain: %s" % names.domain) + message("DNS Domain: %s" % names.dnsdomain) + message("DOMAIN SID: %s" % str(domainsid)) + message("Admin password: %s" % adminpass) + result = ProvisionResult() result.domaindn = domaindn result.paths = paths -- cgit From 2ab6dd9ea58c7f09791f45077df084447fc7de69 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 2 Apr 2008 11:38:58 +1100 Subject: Remove references to setting the host GUID, as the repl_meta_data module prohibits it anyway. Andrew Bartlett (This used to be commit c5b287c056855892f30fbbf32efe7d65da31ce91) --- source4/scripting/python/samba/provision.py | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index b03457e57b..50d9f8d2ff 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -695,13 +695,8 @@ def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, def setup_self_join(samdb, names, machinepass, dnspass, domainsid, invocationid, setup_path, - policyguid, hostguid=None): + policyguid): """Join a host to its own domain.""" - if hostguid is not None: - hostguid_add = "objectGUID: %s" % hostguid - else: - hostguid_add = "" - setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), { "CONFIGDN": names.configdn, "SCHEMADN": names.schemadn, @@ -714,7 +709,6 @@ def setup_self_join(samdb, names, "DNSPASS_B64": b64encode(dnspass), "REALM": names.realm, "DOMAIN": names.domain, - "HOSTGUID_ADD": hostguid_add, "DNSDOMAIN": names.dnsdomain}) setup_add_ldif(samdb, setup_path("provision_group_policy.ldif"), { "POLICYGUID": policyguid, @@ -727,7 +721,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, names, message, domainsid, aci, domainguid, policyguid, fill, adminpass, krbtgtpass, - machinepass, hostguid, invocationid, dnspass, + machinepass, invocationid, dnspass, serverrole, ldap_backend=None, ldap_backend_type=None): """Setup a complete SAM Database. @@ -880,7 +874,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, dnspass=dnspass, machinepass=machinepass, domainsid=domainsid, policyguid=policyguid, - hostguid=hostguid, setup_path=setup_path) #We want to setup the index last, as adds are faster unindexed @@ -902,7 +895,7 @@ def provision(setup_dir, message, session_info, credentials, smbconf=None, targetdir=None, samdb_fill=FILL_FULL, realm=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, domain=None, hostname=None, hostip=None, domainsid=None, - hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None, + adminpass=None, krbtgtpass=None, domainguid=None, policyguid=None, invocationid=None, machinepass=None, dnspass=None, root=None, nobody=None, nogroup=None, users=None, wheel=None, backup=None, aci=None, serverrole=None, @@ -1006,7 +999,7 @@ def provision(setup_dir, message, session_info, aci=aci, domainguid=domainguid, policyguid=policyguid, fill=samdb_fill, adminpass=adminpass, krbtgtpass=krbtgtpass, - hostguid=hostguid, invocationid=invocationid, + invocationid=invocationid, machinepass=machinepass, dnspass=dnspass, serverrole=serverrole, ldap_backend=ldap_backend, ldap_backend_type=ldap_backend_type) @@ -1077,7 +1070,7 @@ def provision_become_dc(setup_dir=None, smbconf=None, targetdir=None, realm=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, domain=None, hostname=None, domainsid=None, - hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None, + adminpass=None, krbtgtpass=None, domainguid=None, policyguid=None, invocationid=None, machinepass=None, dnspass=None, root=None, nobody=None, nogroup=None, users=None, wheel=None, backup=None, aci=None, serverrole=None, -- cgit From 3c0c6acc594fba1f1d28e49cb105c99fa1649a18 Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Tue, 1 Apr 2008 19:51:24 -0500 Subject: provision: Add support for IPv6 (bz #4593). (This used to be commit 8585a3c77d5dfe97bca3f08716fc06ac2819f578) --- source4/scripting/python/samba/provision.py | 34 +++++++++++++++++++++-------- 1 file changed, 25 insertions(+), 9 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index b03457e57b..870f64ecc9 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -28,7 +28,7 @@ import pwd import grp import time import uuid, misc -from socket import gethostname, gethostbyname +import socket import param import registry import samba @@ -267,7 +267,7 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole= rootdn=None, domaindn=None, configdn=None, schemadn=None, sitename=None): if hostname is None: - hostname = gethostname().split(".")[0].lower() + hostname = socket.gethostname().split(".")[0].lower() netbiosname = hostname.upper() if not valid_netbios_name(netbiosname): @@ -348,7 +348,7 @@ def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrol if not os.path.exists(smbconf): if hostname is None: - hostname = gethostname().split(".")[0].lower() + hostname = socket.gethostname().split(".")[0].lower() if serverrole is None: serverrole = "standalone" @@ -901,7 +901,7 @@ FILL_DRS = "DRS" def provision(setup_dir, message, session_info, credentials, smbconf=None, targetdir=None, samdb_fill=FILL_FULL, realm=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, - domain=None, hostname=None, hostip=None, domainsid=None, + domain=None, hostname=None, hostip=None, hostip6=None, domainsid=None, hostguid=None, adminpass=None, krbtgtpass=None, domainguid=None, policyguid=None, invocationid=None, machinepass=None, dnspass=None, root=None, nobody=None, nogroup=None, users=None, @@ -955,7 +955,12 @@ def provision(setup_dir, message, session_info, paths = provision_paths_from_lp(lp, names.dnsdomain) if hostip is None: - hostip = gethostbyname(names.hostname) + hostip = socket.getaddrinfo(names.hostname, None, socket.AF_INET, socket.AI_CANONNAME, socket.IPPROTO_IP)[0][-1][0] + + if hostip6 is None: + try: + hostip6 = socket.getaddrinfo(names.hostname, None, socket.AF_INET6, socket.AI_CANONNAME, socket.IPPROTO_IP)[0][-1][0] + except socket.gaierror: pass if serverrole is None: serverrole = lp.get("server role") @@ -1048,7 +1053,8 @@ def provision(setup_dir, message, session_info, assert isinstance(hostguid, str) create_zone_file(paths.dns, setup_path, samdb, - hostname=names.hostname, hostip=hostip, dnsdomain=names.dnsdomain, + hostname=names.hostname, hostip=hostip, + hostip6=hostip6, dnsdomain=names.dnsdomain, domaindn=names.domaindn, dnspass=dnspass, realm=names.realm, domainguid=domainguid, hostguid=hostguid) message("Please install the zone located in %s into your DNS server" % paths.dns) @@ -1114,7 +1120,7 @@ def provision_backend(setup_dir=None, message=None, return os.path.join(setup_dir, file) if hostname is None: - hostname = gethostname().split(".")[0].lower() + hostname = socket.gethostname().split(".")[0].lower() if root is None: root = findnss(pwd.getpwnam, ["root"])[0] @@ -1247,7 +1253,7 @@ def create_phpldapadmin_config(path, setup_path, ldapi_uri): def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, - hostip, hostname, dnspass, realm, domainguid, hostguid): + hostip, hostip6, hostname, dnspass, realm, domainguid, hostguid): """Write out a DNS zone file, from the info in the current database. :param path: Path of the new file. @@ -1255,7 +1261,8 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, :param samdb: SamDB object :param dnsdomain: DNS Domain name :param domaindn: DN of the Domain - :param hostip: Local IP + :param hostip: Local IPv4 IP + :param hostip6: Local IPv6 IP :param hostname: Local hostname :param dnspass: Password for DNS :param realm: Realm name @@ -1264,6 +1271,13 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, """ assert isinstance(domainguid, str) + hostip6_base_line = "" + hostip6_host_line = "" + + if hostip6 is not None: + hostip6_base_line = " IN AAAA " + hostip6 + hostip6_host_line = hostname + " IN AAAA " + hostip6 + setup_file(setup_path("provision.zone"), path, { "DNSPASS_B64": b64encode(dnspass), "HOSTNAME": hostname, @@ -1274,6 +1288,8 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, "DATESTRING": time.strftime("%Y%m%d%H"), "DEFAULTSITE": DEFAULTSITE, "HOSTGUID": hostguid, + "HOSTIP6_BASE_LINE": hostip6_base_line, + "HOSTIP6_HOST_LINE": hostip6_host_line, }) def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): -- cgit From 8ac91d913231ecd7ead595b93032c7486f67c949 Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Tue, 1 Apr 2008 00:17:00 +0200 Subject: provision: Set up id mappings in the idmap db, only map Administrator. (This used to be commit 206b7d387c6d17e5cc40fd45b489abac9235a7a4) --- source4/scripting/python/samba/provision.py | 98 ++++++++++++++--------------- 1 file changed, 47 insertions(+), 51 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index dfeb61e52b..a8ced61c4b 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -35,6 +35,7 @@ import samba from auth import system_session from samba import Ldb, substitute_var, valid_netbios_name, check_all_substituted from samba.samdb import SamDB +from samba.idmap import IDmapDB import security import urllib from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ @@ -397,45 +398,32 @@ def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrol return lp -def setup_name_mappings(ldb, sid, domaindn, root, nobody, nogroup, users, - wheel, backup): +def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid, + users_gid, wheel_gid, backup_gid): """setup reasonable name mappings for sam names to unix names. - - :param ldb: SamDB object. + + :param samdb: SamDB object. + :param idmap: IDmap db object. :param sid: The domain sid. :param domaindn: The domain DN. - :param root: Name of the UNIX root user. - :param nobody: Name of the UNIX nobody user. - :param nogroup: Name of the unix nobody group. - :param users: Name of the unix users group. - :param wheel: Name of the wheel group (users that can become root). - :param backup: Name of the backup group.""" + :param root_uid: uid of the UNIX root user. + :param nobody_uid: uid of the UNIX nobody user. + :param users_gid: gid of the UNIX users group. + :param wheel_gid: gid of the UNIX wheel group. + :param backup_gid: gid of the UNIX backup group.""" # add some foreign sids if they are not present already - ldb.add_foreign(domaindn, "S-1-5-7", "Anonymous") - ldb.add_foreign(domaindn, "S-1-1-0", "World") - ldb.add_foreign(domaindn, "S-1-5-2", "Network") - ldb.add_foreign(domaindn, "S-1-5-18", "System") - ldb.add_foreign(domaindn, "S-1-5-11", "Authenticated Users") - - # some well known sids - ldb.setup_name_mapping(domaindn, "S-1-5-7", nobody) - ldb.setup_name_mapping(domaindn, "S-1-1-0", nogroup) - ldb.setup_name_mapping(domaindn, "S-1-5-2", nogroup) - ldb.setup_name_mapping(domaindn, "S-1-5-18", root) - ldb.setup_name_mapping(domaindn, "S-1-5-11", users) - ldb.setup_name_mapping(domaindn, "S-1-5-32-544", wheel) - ldb.setup_name_mapping(domaindn, "S-1-5-32-545", users) - ldb.setup_name_mapping(domaindn, "S-1-5-32-546", nogroup) - ldb.setup_name_mapping(domaindn, "S-1-5-32-551", backup) - - # and some well known domain rids - ldb.setup_name_mapping(domaindn, sid + "-500", root) - ldb.setup_name_mapping(domaindn, sid + "-518", wheel) - ldb.setup_name_mapping(domaindn, sid + "-519", wheel) - ldb.setup_name_mapping(domaindn, sid + "-512", wheel) - ldb.setup_name_mapping(domaindn, sid + "-513", users) - ldb.setup_name_mapping(domaindn, sid + "-520", wheel) + samdb.add_foreign(domaindn, "S-1-5-7", "Anonymous") + samdb.add_foreign(domaindn, "S-1-1-0", "World") + samdb.add_foreign(domaindn, "S-1-5-2", "Network") + samdb.add_foreign(domaindn, "S-1-5-18", "System") + samdb.add_foreign(domaindn, "S-1-5-11", "Authenticated Users") + idmap.setup_name_mapping("S-1-5-7", idmap.TYPE_UID, nobody_uid) + idmap.setup_name_mapping("S-1-5-32-544", idmap.TYPE_GID, wheel_gid) + idmap.setup_name_mapping("S-1-5-32-551", idmap.TYPE_GID, backup_gid) + + idmap.setup_name_mapping(sid + "-500", idmap.TYPE_UID, root_uid) + idmap.setup_name_mapping(sid + "-513", idmap.TYPE_GID, users_gid) def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, credentials, names, @@ -663,8 +651,8 @@ def setup_idmapdb(path, setup_path, session_info, credentials, lp): if os.path.exists(path): os.unlink(path) - idmap_ldb = Ldb(path, session_info=session_info, credentials=credentials, - lp=lp) + idmap_ldb = IDmapDB(path, session_info=session_info, + credentials=credentials, lp=lp) idmap_ldb.erase() idmap_ldb.load_ldif_file_add(setup_path("idmap_init.ldif")) @@ -924,18 +912,25 @@ def provision(setup_dir, message, session_info, if dnspass is None: dnspass = misc.random_password(12) if root is None: - root = findnss(pwd.getpwnam, ["root"])[0] + root_uid = findnss(pwd.getpwnam, ["root"])[2] + else: + root_uid = findnss(pwd.getpwnam, [root])[2] if nobody is None: - nobody = findnss(pwd.getpwnam, ["nobody"])[0] - if nogroup is None: - nogroup = findnss(grp.getgrnam, ["nogroup", "nobody"])[0] + nobody_uid = findnss(pwd.getpwnam, ["nobody"])[2] + else: + nobody_uid = findnss(pwd.getpwnam, [nobody])[2] if users is None: - users = findnss(grp.getgrnam, ["users", "guest", "other", "unknown", - "usr"])[0] + users_gid = findnss(grp.getgrnam, ["users"])[2] + else: + users_gid = findnss(grp.getgrnam, [users])[2] if wheel is None: - wheel = findnss(grp.getgrnam, ["wheel", "root", "staff", "adm"])[0] + wheel_gid = findnss(grp.getgrnam, ["wheel", "adm"])[2] + else: + wheel_gid = findnss(grp.getgrnam, [wheel])[2] if backup is None: - backup = findnss(grp.getgrnam, ["backup", "wheel", "root", "staff"])[0] + backup_gid = findnss(grp.getgrnam, ["backup", "staff"])[2] + else: + backup_gid = findnss(grp.getgrnam, [backup])[2] if aci is None: aci = "# no aci for local ldb" @@ -994,8 +989,8 @@ def provision(setup_dir, message, session_info, credentials=credentials, lp=lp) message("Setting up idmap db") - setup_idmapdb(paths.idmapdb, setup_path, session_info=session_info, - credentials=credentials, lp=lp) + idmap = setup_idmapdb(paths.idmapdb, setup_path, session_info=session_info, + credentials=credentials, lp=lp) samdb = setup_samdb(paths.samdb, setup_path, session_info=session_info, credentials=credentials, lp=lp, names=names, @@ -1026,11 +1021,12 @@ def provision(setup_dir, message, session_info, machinepass=machinepass, dnsdomain=names.dnsdomain) if samdb_fill == FILL_FULL: - setup_name_mappings(samdb, str(domainsid), names.domaindn, root=root, - nobody=nobody, nogroup=nogroup, wheel=wheel, - users=users, backup=backup) - - message("Compleating sam.ldb setup by marking as synchronized") + setup_name_mappings(samdb, idmap, str(domainsid), names.domaindn, + root_uid=root_uid, nobody_uid=nobody_uid, + users_gid=users_gid, wheel_gid=wheel_gid, + backup_gid=backup_gid) + + message("Setting up sam.ldb rootDSE marking as synchronized") setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif")) # Only make a zone file on the first DC, it should be replicated with DNS replication -- cgit From c26387a473fd26ac51c74c001b520d7fd7d353ec Mon Sep 17 00:00:00 2001 From: Kai Blin Date: Thu, 3 Apr 2008 00:01:34 +0200 Subject: provision: Remove backup group mapping Some distros seem to neither have a backup nor a staff group. (This used to be commit 21fcf7c419658b3ae296428ca7a4ccf2288c17fe) --- source4/scripting/python/samba/provision.py | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index a8ced61c4b..6917aa1a54 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -399,7 +399,7 @@ def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrol return lp def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid, - users_gid, wheel_gid, backup_gid): + users_gid, wheel_gid): """setup reasonable name mappings for sam names to unix names. :param samdb: SamDB object. @@ -409,8 +409,7 @@ def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid, :param root_uid: uid of the UNIX root user. :param nobody_uid: uid of the UNIX nobody user. :param users_gid: gid of the UNIX users group. - :param wheel_gid: gid of the UNIX wheel group. - :param backup_gid: gid of the UNIX backup group.""" + :param wheel_gid: gid of the UNIX wheel group.""" # add some foreign sids if they are not present already samdb.add_foreign(domaindn, "S-1-5-7", "Anonymous") samdb.add_foreign(domaindn, "S-1-1-0", "World") @@ -420,7 +419,6 @@ def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid, idmap.setup_name_mapping("S-1-5-7", idmap.TYPE_UID, nobody_uid) idmap.setup_name_mapping("S-1-5-32-544", idmap.TYPE_GID, wheel_gid) - idmap.setup_name_mapping("S-1-5-32-551", idmap.TYPE_GID, backup_gid) idmap.setup_name_mapping(sid + "-500", idmap.TYPE_UID, root_uid) idmap.setup_name_mapping(sid + "-513", idmap.TYPE_GID, users_gid) @@ -927,10 +925,6 @@ def provision(setup_dir, message, session_info, wheel_gid = findnss(grp.getgrnam, ["wheel", "adm"])[2] else: wheel_gid = findnss(grp.getgrnam, [wheel])[2] - if backup is None: - backup_gid = findnss(grp.getgrnam, ["backup", "staff"])[2] - else: - backup_gid = findnss(grp.getgrnam, [backup])[2] if aci is None: aci = "# no aci for local ldb" @@ -1023,8 +1017,7 @@ def provision(setup_dir, message, session_info, if samdb_fill == FILL_FULL: setup_name_mappings(samdb, idmap, str(domainsid), names.domaindn, root_uid=root_uid, nobody_uid=nobody_uid, - users_gid=users_gid, wheel_gid=wheel_gid, - backup_gid=backup_gid) + users_gid=users_gid, wheel_gid=wheel_gid) message("Setting up sam.ldb rootDSE marking as synchronized") setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif")) -- cgit From c764791100079ed447c07ca6b99d33f9695255c3 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 4 Apr 2008 12:25:19 +1100 Subject: Clean up provision and rootdse module to hard-code less stuff. In particular, allow for the server DN to be in a different site (possible outcome of a DRS replication). Andrew Bartlett (This used to be commit 9ee4e39fe178317f42fd9a0adceea24b55dfe0f1) --- source4/scripting/python/samba/provision.py | 42 ++++++++++++++--------------- 1 file changed, 21 insertions(+), 21 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 6917aa1a54..02460070b4 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -265,7 +265,8 @@ def provision_paths_from_lp(lp, dnsdomain): return paths def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole=None, - rootdn=None, domaindn=None, configdn=None, schemadn=None, sitename=None): + rootdn=None, domaindn=None, configdn=None, schemadn=None, serverdn=None, + sitename=None): if hostname is None: hostname = socket.gethostname().split(".")[0].lower() @@ -332,6 +333,7 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole= names.netbiosname = netbiosname names.hostname = hostname names.sitename = sitename + names.serverdn = "CN=%s,CN=Servers,CN=%s,CN=Sites,%s" % (netbiosname, sitename, configdn) return names @@ -543,9 +545,7 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, samdb.load_ldif_file_add(setup_path("provision_init.ldif")) message("Setting up sam.ldb rootDSE") - setup_samdb_rootdse(samdb, setup_path, names.schemadn, names.domaindn, names.hostname, - names.dnsdomain, names.realm, names.rootdn, names.configdn, names.netbiosname, - names.sitename) + setup_samdb_rootdse(samdb, setup_path, names) if erase: message("Erasing data from partitions") @@ -656,25 +656,22 @@ def setup_idmapdb(path, setup_path, session_info, credentials, lp): idmap_ldb.load_ldif_file_add(setup_path("idmap_init.ldif")) return idmap_ldb -def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, - dnsdomain, realm, rootdn, configdn, netbiosname, - sitename): +def setup_samdb_rootdse(samdb, setup_path, names): """Setup the SamDB rootdse. :param samdb: Sam Database handle :param setup_path: Obtain setup path """ setup_add_ldif(samdb, setup_path("provision_rootdse_add.ldif"), { - "SCHEMADN": schemadn, - "NETBIOSNAME": netbiosname, - "DNSDOMAIN": dnsdomain, - "DEFAULTSITE": sitename, - "REALM": realm, - "DNSNAME": "%s.%s" % (hostname, dnsdomain), - "DOMAINDN": domaindn, - "ROOTDN": rootdn, - "CONFIGDN": configdn, - "VERSION": samba.version(), + "SCHEMADN": names.schemadn, + "NETBIOSNAME": names.netbiosname, + "DNSDOMAIN": names.dnsdomain, + "REALM": names.realm, + "DNSNAME": "%s.%s" % (names.hostname, names.dnsdomain), + "DOMAINDN": names.domaindn, + "ROOTDN": names.rootdn, + "CONFIGDN": names.configdn, + "SERVERDN": names.serverdn, }) @@ -879,7 +876,8 @@ FILL_DRS = "DRS" def provision(setup_dir, message, session_info, credentials, smbconf=None, targetdir=None, samdb_fill=FILL_FULL, realm=None, - rootdn=None, domaindn=None, schemadn=None, configdn=None, + rootdn=None, domaindn=None, schemadn=None, configdn=None, + serverdn=None, domain=None, hostname=None, hostip=None, hostip6=None, domainsid=None, adminpass=None, krbtgtpass=None, domainguid=None, policyguid=None, invocationid=None, machinepass=None, @@ -932,7 +930,8 @@ def provision(setup_dir, message, session_info, names = guess_names(lp=lp, hostname=hostname, domain=domain, dnsdomain=realm, serverrole=serverrole, sitename=sitename, - rootdn=rootdn, domaindn=domaindn, configdn=configdn, schemadn=schemadn) + rootdn=rootdn, domaindn=domaindn, configdn=configdn, schemadn=schemadn, + serverdn=serverdn) paths = provision_paths_from_lp(lp, names.dnsdomain) @@ -1064,12 +1063,13 @@ def provision(setup_dir, message, session_info, def provision_become_dc(setup_dir=None, smbconf=None, targetdir=None, realm=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, + serverdn=None, domain=None, hostname=None, domainsid=None, adminpass=None, krbtgtpass=None, domainguid=None, policyguid=None, invocationid=None, machinepass=None, dnspass=None, root=None, nobody=None, nogroup=None, users=None, wheel=None, backup=None, aci=None, serverrole=None, - ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE): + ldap_backend=None, ldap_backend_type=None, sitename=None): def message(text): """print a message if quiet is not set.""" @@ -1077,7 +1077,7 @@ def provision_become_dc(setup_dir=None, provision(setup_dir, message, system_session(), None, smbconf=smbconf, targetdir=targetdir, samdb_fill=FILL_DRS, realm=realm, - rootdn=rootdn, domaindn=domaindn, schemadn=schemadn, configdn=configdn, + rootdn=rootdn, domaindn=domaindn, schemadn=schemadn, configdn=configdn, serverdn=serverdn, domain=domain, hostname=hostname, hostip="127.0.0.1", domainsid=domainsid, machinepass=machinepass, serverrole="domain controller", sitename=sitename); -- cgit From 14e443b868f56db0b29c3221c175f1a2cd2a8d1d Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 Apr 2008 16:13:42 +0200 Subject: Improve PEP8 (Python code style) compliancy a bit. (This used to be commit c7d388a6e2153234fe67daf1af094fc346e1da61) --- source4/scripting/python/samba/provision.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 6917aa1a54..9151f29603 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -264,8 +264,10 @@ def provision_paths_from_lp(lp, dnsdomain): return paths -def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole=None, - rootdn=None, domaindn=None, configdn=None, schemadn=None, sitename=None): + +def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, + serverrole=None, rootdn=None, domaindn=None, configdn=None, + schemadn=None, sitename=None): if hostname is None: hostname = socket.gethostname().split(".")[0].lower() @@ -336,7 +338,8 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole= return names -def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, targetdir): +def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, + serverrole, targetdir): if targetdir is not None: if not os.path.exists(targetdir): os.mkdir(targetdir) @@ -423,6 +426,7 @@ def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid, idmap.setup_name_mapping(sid + "-500", idmap.TYPE_UID, root_uid) idmap.setup_name_mapping(sid + "-513", idmap.TYPE_GID, users_gid) + def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, credentials, names, serverrole, ldap_backend=None, @@ -543,8 +547,9 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, samdb.load_ldif_file_add(setup_path("provision_init.ldif")) message("Setting up sam.ldb rootDSE") - setup_samdb_rootdse(samdb, setup_path, names.schemadn, names.domaindn, names.hostname, - names.dnsdomain, names.realm, names.rootdn, names.configdn, names.netbiosname, + setup_samdb_rootdse(samdb, setup_path, names.schemadn, names.domaindn, + names.hostname, names.dnsdomain, names.realm, + names.rootdn, names.configdn, names.netbiosname, names.sitename) if erase: @@ -637,6 +642,7 @@ def setup_registry(path, setup_path, session_info, credentials, lp): assert os.path.exists(provision_reg) reg.diff_apply(provision_reg) + def setup_idmapdb(path, setup_path, session_info, credentials, lp): """Setup the idmap database. @@ -656,6 +662,7 @@ def setup_idmapdb(path, setup_path, session_info, credentials, lp): idmap_ldb.load_ldif_file_add(setup_path("idmap_init.ldif")) return idmap_ldb + def setup_samdb_rootdse(samdb, setup_path, schemadn, domaindn, hostname, dnsdomain, realm, rootdn, configdn, netbiosname, sitename): @@ -740,7 +747,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, if serverrole == "domain controller": samdb.set_invocation_id(invocationid) - load_schema(setup_path, samdb, names.schemadn, names.netbiosname, names.configdn, names.sitename) + load_schema(setup_path, samdb, names.schemadn, names.netbiosname, + names.configdn, names.sitename) samdb.transaction_start() -- cgit From 3e97aa73c22ea036afb586b16a1d130ee46e5697 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 5 Apr 2008 16:32:28 +0200 Subject: Simplify some code, fix style. (This used to be commit 1c983e4e4dfb93387791c36dc96696c4fffcfeb7) --- source4/scripting/python/samba/provision.py | 201 ++++++++++++++-------------- 1 file changed, 99 insertions(+), 102 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 9151f29603..f81cedc729 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -103,7 +103,7 @@ def check_install(lp, session_info, credentials): :param credentials: Credentials """ if lp.get("realm") == "": - raise Error("Realm empty") + raise Exception("Realm empty") ldb = Ldb(lp.get("sam database"), session_info=session_info, credentials=credentials, lp=lp) if len(ldb.search("(cn=Administrator)")) != 1: @@ -288,8 +288,8 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, realm = dnsdomain.upper() if lp.get("realm").upper() != realm: - raise Exception("realm '%s' in %s must match chosen realm '%s'" % - (lp.get("realm"), smbconf, realm)) + raise Exception("realm '%s' must match chosen realm '%s'" % + (lp.get("realm"), realm)) dnsdomain = dnsdomain.lower() @@ -299,7 +299,7 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, if domaindn is None: domaindn = "DC=" + dnsdomain.replace(".", ",DC=") if lp.get("workgroup").upper() != domain.upper(): - raise Error("workgroup '%s' in smb.conf must match chosen domain '%s'", + raise Exception("workgroup '%s' in smb.conf must match chosen domain '%s'", lp.get("workgroup"), domain) else: domain = netbiosname @@ -338,68 +338,52 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, return names -def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, - serverrole, targetdir): - if targetdir is not None: - if not os.path.exists(targetdir): - os.mkdir(targetdir) - if not os.path.exists(os.path.join(targetdir, "etc")): - os.mkdir(os.path.join(targetdir, "etc")) - - smbconf = os.path.join(targetdir, "etc", "smb.conf") +def make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, + targetdir): + if hostname is None: + hostname = socket.gethostname().split(".")[0].lower() - # only install a new smb.conf if there isn't one there already + if serverrole is None: + serverrole = "standalone" - if not os.path.exists(smbconf): - if hostname is None: - hostname = socket.gethostname().split(".")[0].lower() + assert serverrole in ("domain controller", "member server", "standalone") + if serverrole == "domain controller": + smbconfsuffix = "dc" + elif serverrole == "member server": + smbconfsuffix = "member" + elif serverrole == "standalone": + smbconfsuffix = "standalone" - if serverrole is None: - serverrole = "standalone" + assert domain is not None + assert realm is not None - assert serverrole in ("domain controller", "member server", "standalone") - if serverrole == "domain controller": - smbconfsuffix = "dc" - elif serverrole == "member server": - smbconfsuffix = "member" - elif serverrole == "standalone": - smbconfsuffix = "standalone" - - assert domain is not None - assert realm is not None - - default_lp = param.LoadParm() - #Load non-existant file - default_lp.load(smbconf) - - if targetdir is not None: - privatedir_line = "private dir = " + os.path.abspath(os.path.join(targetdir, "private")) - lockdir_line = "lock dir = " + os.path.abspath(targetdir) + default_lp = param.LoadParm() + #Load non-existant file + default_lp.load(smbconf) + + if targetdir is not None: + privatedir_line = "private dir = " + os.path.abspath(os.path.join(targetdir, "private")) + lockdir_line = "lock dir = " + os.path.abspath(targetdir) - default_lp.set("lock dir", os.path.abspath(targetdir)) - else: - privatedir_line = "" - lockdir_line = "" - - sysvol = os.path.join(default_lp.get("lock dir"), "sysvol") - netlogon = os.path.join(sysvol, realm.lower(), "scripts") - - setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), - smbconf, { - "HOSTNAME": hostname, - "DOMAIN": domain, - "REALM": realm, - "SERVERROLE": serverrole, - "NETLOGONPATH": netlogon, - "SYSVOLPATH": sysvol, - "PRIVATEDIR_LINE": privatedir_line, - "LOCKDIR_LINE": lockdir_line - }) + default_lp.set("lock dir", os.path.abspath(targetdir)) + else: + privatedir_line = "" + lockdir_line = "" - lp = param.LoadParm() - lp.load(smbconf) + sysvol = os.path.join(default_lp.get("lock dir"), "sysvol") + netlogon = os.path.join(sysvol, realm.lower(), "scripts") - return lp + setup_file(setup_path("provision.smb.conf.%s" % smbconfsuffix), + smbconf, { + "HOSTNAME": hostname, + "DOMAIN": domain, + "REALM": realm, + "SERVERROLE": serverrole, + "NETLOGONPATH": netlogon, + "SYSVOLPATH": sysvol, + "PRIVATEDIR_LINE": privatedir_line, + "LOCKDIR_LINE": lockdir_line + }) def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid, users_gid, wheel_gid): @@ -493,8 +477,8 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, schemadn_ldb = "schema.ldb" if ldap_backend is not None: schema_ldb = ldap_backend - schemadn_ldb = ldap_backend - + schemadn_ldb = ldap_backend + if ldap_backend_type == "fedora-ds": backend_modules = ["nsuniqueid", "paged_searches"] # We can handle linked attributes here, as we don't have directory-side subtree operations @@ -886,14 +870,15 @@ FILL_NT4SYNC = "NT4SYNC" FILL_DRS = "DRS" def provision(setup_dir, message, session_info, - credentials, smbconf=None, targetdir=None, samdb_fill=FILL_FULL, realm=None, - rootdn=None, domaindn=None, schemadn=None, configdn=None, - domain=None, hostname=None, hostip=None, hostip6=None, - domainsid=None, adminpass=None, krbtgtpass=None, domainguid=None, - policyguid=None, invocationid=None, machinepass=None, - dnspass=None, root=None, nobody=None, nogroup=None, users=None, - wheel=None, backup=None, aci=None, serverrole=None, - ldap_backend=None, ldap_backend_type=None, sitename=None): + credentials, smbconf=None, targetdir=None, samdb_fill=FILL_FULL, + realm=None, rootdn=None, domaindn=None, schemadn=None, + configdn=None, domain=None, hostname=None, hostip=None, + hostip6=None, domainsid=None, adminpass=None, krbtgtpass=None, + domainguid=None, policyguid=None, invocationid=None, + machinepass=None, dnspass=None, root=None, nobody=None, + nogroup=None, users=None, wheel=None, backup=None, aci=None, + serverrole=None, ldap_backend=None, ldap_backend_type=None, + sitename=None): """Provision samba4 :note: caution, this wipes all existing data! @@ -917,18 +902,9 @@ def provision(setup_dir, message, session_info, machinepass = misc.random_password(12) if dnspass is None: dnspass = misc.random_password(12) - if root is None: - root_uid = findnss(pwd.getpwnam, ["root"])[2] - else: - root_uid = findnss(pwd.getpwnam, [root])[2] - if nobody is None: - nobody_uid = findnss(pwd.getpwnam, ["nobody"])[2] - else: - nobody_uid = findnss(pwd.getpwnam, [nobody])[2] - if users is None: - users_gid = findnss(grp.getgrnam, ["users"])[2] - else: - users_gid = findnss(grp.getgrnam, [users])[2] + root_uid = findnss(pwd.getpwnam, [root or "root"])[2] + nobody_uid = findnss(pwd.getpwnam, [nobody or "nobody"])[2] + users_gid = findnss(grp.getgrnam, [users or "users"])[2] if wheel is None: wheel_gid = findnss(grp.getgrnam, ["wheel", "adm"])[2] else: @@ -936,7 +912,17 @@ def provision(setup_dir, message, session_info, if aci is None: aci = "# no aci for local ldb" - lp = load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, targetdir) + if smbconf is None: + os.makedirs(os.path.join(targetdir, "etc")) + smbconf = os.path.join(targetdir, "etc", "smb.conf") + + # only install a new smb.conf if there isn't one there already + if not os.path.exists(smbconf): + make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, + targetdir) + + lp = param.LoadParm() + lp.load(smbconf) names = guess_names(lp=lp, hostname=hostname, domain=domain, dnsdomain=realm, serverrole=serverrole, sitename=sitename, @@ -1080,7 +1066,7 @@ def provision_become_dc(setup_dir=None, ldap_backend=None, ldap_backend_type=None, sitename=DEFAULTSITE): def message(text): - """print a message if quiet is not set.""" + """print a message if quiet is not set.""" print text provision(setup_dir, message, system_session(), None, @@ -1115,11 +1101,22 @@ def provision_backend(setup_dir=None, message=None, if root is None: root = findnss(pwd.getpwnam, ["root"])[0] - lp = load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, targetdir) + if smbconf is None: + os.makedirs(os.path.join(targetdir, "etc")) + smbconf = os.path.join(targetdir, "etc", "smb.conf") + + # only install a new smb.conf if there isn't one there already + if not os.path.exists(smbconf): + make_smbconf(smbconf, setup_path, hostname, domain, realm, + serverrole, targetdir) + + lp = param.LoadParm() + lp.load(smbconf) names = guess_names(lp=lp, hostname=hostname, domain=domain, dnsdomain=realm, serverrole=serverrole, - rootdn=rootdn, domaindn=domaindn, configdn=configdn, schemadn=schemadn) + rootdn=rootdn, domaindn=domaindn, configdn=configdn, + schemadn=schemadn) paths = provision_paths_from_lp(lp, names.dnsdomain) @@ -1175,11 +1172,11 @@ def provision_backend(setup_dir=None, message=None, backend_schema = "99_ad.ldif" elif ldap_backend_type == "openldap": attrs = ["linkID", "lDAPDisplayName"] - res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs); + res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs); - memberof_config = "# Generated from schema in " + schemadb_path + "\n"; - refint_attributes = ""; - for i in range (0, len(res)): + memberof_config = "# Generated from schema in " + schemadb_path + "\n"; + refint_attributes = ""; + for i in range (0, len(res)): linkid = res[i]["linkID"][0] linkid = str(int(linkid) + 1) expression = "(&(objectclass=attributeSchema)(linkID=" + (linkid) + "))" @@ -1199,11 +1196,11 @@ memberof-dangling-error 32 """; - memberof_config = memberof_config + """ + memberof_config = memberof_config + """ overlay refint refint_attributes""" + refint_attributes + "\n"; - - setup_file(setup_path("slapd.conf"), paths.slapdconf, + + setup_file(setup_path("slapd.conf"), paths.slapdconf, {"DNSDOMAIN": names.dnsdomain, "LDAPDIR": paths.ldapdir, "DOMAINDN": names.domaindn, @@ -1212,18 +1209,18 @@ refint_attributes""" + refint_attributes + "\n"; "LDAPMANAGERDN": names.ldapmanagerdn, "LDAPMANAGERPASS": adminpass, "MEMBEROF_CONFIG": memberof_config}) - setup_file(setup_path("modules.conf"), paths.modulesconf, + setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "user")) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "config")) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "schema")) - mapping = "schema-map-openldap-2.3" - backend_schema = "backend-schema.schema" + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "user")) + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "config")) + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "schema")) + mapping = "schema-map-openldap-2.3" + backend_schema = "backend-schema.schema" - ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") - message("Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri) + ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") + message("Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri) schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema); @@ -1265,8 +1262,8 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, hostip6_host_line = "" if hostip6 is not None: - hostip6_base_line = " IN AAAA " + hostip6 - hostip6_host_line = hostname + " IN AAAA " + hostip6 + hostip6_base_line = " IN AAAA " + hostip6 + hostip6_host_line = hostname + " IN AAAA " + hostip6 setup_file(setup_path("provision.zone"), path, { "DNSPASS_B64": b64encode(dnspass), -- cgit From 7c7880695b02df4cbe0faab959846c63d0cc0536 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 6 Apr 2008 00:40:01 +0200 Subject: More PEP8 compliancy. (This used to be commit d16b30d005933c9cc73f9196a3b77829d23687a0) --- source4/scripting/python/samba/provision.py | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index f81cedc729..4d5a9cb1f1 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -125,6 +125,10 @@ def findnss(nssfn, names): raise KeyError("Unable to find user/group %r" % names) +findnss_uid = lambda names: findnss(pwd.getpwnam, names)[2] +findnss_gid = lambda names: findnss(grp.getgrnam, names)[2] + + def open_ldb(session_info, credentials, lp, dbname): """Open a LDB, thrashing it if it is corrupt. @@ -293,7 +297,7 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, dnsdomain = dnsdomain.lower() - if (serverrole == "domain controller"): + if serverrole == "domain controller": if domain is None: domain = lp.get("workgroup") if domaindn is None: @@ -385,6 +389,7 @@ def make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, "LOCKDIR_LINE": lockdir_line }) + def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid, users_gid, wheel_gid): """setup reasonable name mappings for sam names to unix names. @@ -902,13 +907,13 @@ def provision(setup_dir, message, session_info, machinepass = misc.random_password(12) if dnspass is None: dnspass = misc.random_password(12) - root_uid = findnss(pwd.getpwnam, [root or "root"])[2] - nobody_uid = findnss(pwd.getpwnam, [nobody or "nobody"])[2] - users_gid = findnss(grp.getgrnam, [users or "users"])[2] + root_uid = findnss_uid([root or "root"]) + nobody_uid = findnss_uid([nobody or "nobody"]) + users_gid = findnss_gid([users or "users"]) if wheel is None: - wheel_gid = findnss(grp.getgrnam, ["wheel", "adm"])[2] + wheel_gid = findnss_gid(["wheel", "adm"]) else: - wheel_gid = findnss(grp.getgrnam, [wheel])[2] + wheel_gid = findnss_gid([wheel]) if aci is None: aci = "# no aci for local ldb" @@ -925,8 +930,9 @@ def provision(setup_dir, message, session_info, lp.load(smbconf) names = guess_names(lp=lp, hostname=hostname, domain=domain, - dnsdomain=realm, serverrole=serverrole, sitename=sitename, - rootdn=rootdn, domaindn=domaindn, configdn=configdn, schemadn=schemadn) + dnsdomain=realm, serverrole=serverrole, + sitename=sitename, rootdn=rootdn, domaindn=domaindn, + configdn=configdn, schemadn=schemadn) paths = provision_paths_from_lp(lp, names.dnsdomain) @@ -936,7 +942,8 @@ def provision(setup_dir, message, session_info, if hostip6 is None: try: hostip6 = socket.getaddrinfo(names.hostname, None, socket.AF_INET6, socket.AI_CANONNAME, socket.IPPROTO_IP)[0][-1][0] - except socket.gaierror: pass + except socket.gaierror: + pass if serverrole is None: serverrole = lp.get("server role") -- cgit From b2805c50eecddfa4cbd0945e713567eddce05895 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 8 Apr 2008 17:28:25 +1000 Subject: Re-add support for the --ldap-backend-port option to provision-backend This option allows Fedora DS multi-master replication to work. I've tried to update the wiki and scripts to the largely consistant with each other. Andrew Bartlett (This used to be commit 42393c830733b2cc99ebccdafe944fcf3d82734f) --- source4/scripting/python/samba/provision.py | 42 ++++++++++++++++++++--------- 1 file changed, 29 insertions(+), 13 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 02460070b4..80dcd522df 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -288,7 +288,7 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole= if lp.get("realm").upper() != realm: raise Exception("realm '%s' in %s must match chosen realm '%s'" % - (lp.get("realm"), smbconf, realm)) + (lp.get("realm"), lp.configfile(), realm)) dnsdomain = dnsdomain.lower() @@ -1045,8 +1045,8 @@ def provision(setup_dir, message, session_info, message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) - message("Once the above files are installed, your server will be ready to use") - message("Server Type: %s" % serverrole) + message("Once the above files are installed, your Samba4 server will be ready to use") + message("Server Role: %s" % serverrole) message("Hostname: %s" % names.hostname) message("NetBIOS Domain: %s" % names.domain) message("DNS Domain: %s" % names.dnsdomain) @@ -1096,7 +1096,7 @@ def provision_backend(setup_dir=None, message=None, smbconf=None, targetdir=None, realm=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, domain=None, hostname=None, adminpass=None, root=None, serverrole=None, - ldap_backend_type=None): + ldap_backend_type=None, ldap_backend_port=None): def setup_path(file): return os.path.join(setup_dir, file) @@ -1144,7 +1144,12 @@ def provision_backend(setup_dir=None, message=None, {"SCHEMADN": names.schemadn}) if ldap_backend_type == "fedora-ds": - setup_file(setup_path("fedora-ds.inf"), paths.fedoradsinf, + if ldap_backend_port is not None: + serverport = "ServerPort=%d" % ldap_backend_port + else: + serverport = "" + + setup_file(setup_path("fedorads.inf"), paths.fedoradsinf, {"ROOT": root, "HOSTNAME": hostname, "DNSDOMAIN": names.dnsdomain, @@ -1152,19 +1157,18 @@ def provision_backend(setup_dir=None, message=None, "DOMAINDN": names.domaindn, "LDAPMANAGERDN": names.ldapmanagerdn, "LDAPMANAGERPASS": adminpass, - "SERVERPORT": ""}) + "SERVERPORT": serverport}) - setup_file(setup_path("fedora-partitions.ldif"), paths.fedoradspartitions, + setup_file(setup_path("fedorads-partitions.ldif"), paths.fedoradspartitions, {"CONFIGDN": names.configdn, "SCHEMADN": names.schemadn, }) - setup_file(setup_path("fedora-partitions.ldif"), paths.fedoradspartitions, - {"CONFIGDN": names.configdn, - "SCHEMADN": names.schemadn, - }) mapping = "schema-map-fedora-ds-1.0" backend_schema = "99_ad.ldif" + + slapdcommand="Initailise Fedora DS with: setup-ds.pl --file=%s" % paths.fedoradsinf + elif ldap_backend_type == "openldap": attrs = ["linkID", "lDAPDisplayName"] res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs); @@ -1215,14 +1219,26 @@ refint_attributes""" + refint_attributes + "\n"; ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") - message("Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri) - + if ldap_backend_port is not None: + server_port_string = " -h ldap://0.0.0.0:%d" % ldap_backend_port + else: + server_port_string = "" + slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema); os.system(schema_command) + message("Your %s Backend for Samba4 is now configured, and is ready to be started" % ( ldap_backend_type) ) + message("Server Role: %s" % serverrole) + message("Hostname: %s" % names.hostname) + message("DNS Domain: %s" % names.dnsdomain) + message("Base DN: %s" % names.domaindn) + message("LDAP admin DN: %s" % names.ldapmanagerdn) + message("LDAP admin password: %s" % adminpass) + message(slapdcommand) + def create_phpldapadmin_config(path, setup_path, ldapi_uri): """Create a PHP LDAP admin configuration file. -- cgit From ac10ac62c1e9b64280f3566425af08210d57bb04 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Wed, 9 Apr 2008 03:51:41 +0200 Subject: Add docstring, PEP8. (This used to be commit f8cac3735c9a19baa313c4b61abee144da303ce1) --- source4/scripting/python/samba/provision.py | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 80dcd522df..c9cdcdb768 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -264,9 +264,11 @@ def provision_paths_from_lp(lp, dnsdomain): return paths + def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole=None, rootdn=None, domaindn=None, configdn=None, schemadn=None, serverdn=None, sitename=None): + """Guess configuration settings to use.""" if hostname is None: hostname = socket.gethostname().split(".")[0].lower() @@ -400,6 +402,7 @@ def load_or_make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrol return lp + def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid, users_gid, wheel_gid): """setup reasonable name mappings for sam names to unix names. @@ -425,6 +428,7 @@ def setup_name_mappings(samdb, idmap, sid, domaindn, root_uid, nobody_uid, idmap.setup_name_mapping(sid + "-500", idmap.TYPE_UID, root_uid) idmap.setup_name_mapping(sid + "-513", idmap.TYPE_GID, users_gid) + def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, credentials, names, serverrole, ldap_backend=None, @@ -637,6 +641,7 @@ def setup_registry(path, setup_path, session_info, credentials, lp): assert os.path.exists(provision_reg) reg.diff_apply(provision_reg) + def setup_idmapdb(path, setup_path, session_info, credentials, lp): """Setup the idmap database. @@ -656,6 +661,7 @@ def setup_idmapdb(path, setup_path, session_info, credentials, lp): idmap_ldb.load_ldif_file_add(setup_path("idmap_init.ldif")) return idmap_ldb + def setup_samdb_rootdse(samdb, setup_path, names): """Setup the SamDB rootdse. @@ -1060,6 +1066,7 @@ def provision(setup_dir, message, session_info, result.samdb = samdb return result + def provision_become_dc(setup_dir=None, smbconf=None, targetdir=None, realm=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, @@ -1081,7 +1088,11 @@ def provision_become_dc(setup_dir=None, domain=domain, hostname=hostname, hostip="127.0.0.1", domainsid=domainsid, machinepass=machinepass, serverrole="domain controller", sitename=sitename); -def setup_db_config(setup_path, file, dbdir): +def setup_db_config(setup_path, dbdir): + """Setup a Berkeley database. + + :param setup_path: Setup path function. + :param dbdir: Database directory.""" if not os.path.isdir(os.path.join(dbdir, "bdb-logs")): os.makedirs(os.path.join(dbdir, "bdb-logs"), 0700); if not os.path.isdir(os.path.join(dbdir, "tmp")): @@ -1211,12 +1222,11 @@ refint_attributes""" + refint_attributes + "\n"; setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "user")) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "config")) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "db", "schema")) + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "user")) + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "config")) + setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "schema")) mapping = "schema-map-openldap-2.3" backend_schema = "backend-schema.schema" - ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") if ldap_backend_port is not None: -- cgit From 9d2948f4bd5f196904d27c67bf4f0baf7eaefcb0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 9 Apr 2008 14:57:57 +1000 Subject: Don't fill in the secrets DB unless we make the entries. Leave filling in (we still initialise it) the secrets DB for the join or vampire code. Andrew Bartlett (This used to be commit c93208c13ce91b334eadf0ea02fa41354e761e97) --- source4/scripting/python/samba/provision.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index c9cdcdb768..7b4fdb772c 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1011,13 +1011,6 @@ def provision(setup_dir, message, session_info, os.makedirs(os.path.join(policy_path, "User"), 0755) if not os.path.isdir(paths.netlogon): os.makedirs(paths.netlogon, 0755) - secrets_ldb = Ldb(paths.secrets, session_info=session_info, - credentials=credentials, lp=lp) - secretsdb_become_dc(secrets_ldb, setup_path, domain=domain, realm=names.realm, - netbiosname=names.netbiosname, domainsid=domainsid, - keytab_path=paths.keytab, samdb_url=paths.samdb, - dns_keytab_path=paths.dns_keytab, dnspass=dnspass, - machinepass=machinepass, dnsdomain=names.dnsdomain) if samdb_fill == FILL_FULL: setup_name_mappings(samdb, idmap, str(domainsid), names.domaindn, @@ -1029,6 +1022,14 @@ def provision(setup_dir, message, session_info, # Only make a zone file on the first DC, it should be replicated with DNS replication if serverrole == "domain controller": + secrets_ldb = Ldb(paths.secrets, session_info=session_info, + credentials=credentials, lp=lp) + secretsdb_become_dc(secrets_ldb, setup_path, domain=domain, realm=names.realm, + netbiosname=names.netbiosname, domainsid=domainsid, + keytab_path=paths.keytab, samdb_url=paths.samdb, + dns_keytab_path=paths.dns_keytab, dnspass=dnspass, + machinepass=machinepass, dnsdomain=names.dnsdomain) + samdb = SamDB(paths.samdb, session_info=session_info, credentials=credentials, lp=lp) -- cgit From b202b6e7d45cebd9b34c8d319e75f423291b30a0 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 9 Apr 2008 15:32:49 +1000 Subject: Fix up provision to specify SERVERDN in more places. Andrew Bartlett (This used to be commit d01d542502f25d6c731204ecb3d33720a1706581) --- source4/scripting/python/samba/provision.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 7b4fdb772c..ff76681c13 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -690,6 +690,7 @@ def setup_self_join(samdb, names, "CONFIGDN": names.configdn, "SCHEMADN": names.schemadn, "DOMAINDN": names.domaindn, + "SERVERDN": names.serverdn, "INVOCATIONID": invocationid, "NETBIOSNAME": names.netbiosname, "DEFAULTSITE": names.sitename, @@ -773,6 +774,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "NETBIOSNAME": names.netbiosname, "DEFAULTSITE": names.sitename, "CONFIGDN": names.configdn, + "SERVERDN": names.serverdn, "POLICYGUID": policyguid, "DOMAINDN": names.domaindn, "DOMAINGUID_MOD": domainguid_mod, @@ -803,6 +805,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "NETBIOSNAME": names.netbiosname, "DEFAULTSITE": names.sitename, "CONFIGDN": names.configdn, + "SERVERDN": names.serverdn }) message("Setting up sam.ldb Samba4 schema") @@ -821,6 +824,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "DOMAIN": names.domain, "SCHEMADN": names.schemadn, "DOMAINDN": names.domaindn, + "SERVERDN": names.serverdn }) message("Setting up display specifiers") @@ -845,6 +849,7 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "NETBIOSNAME": names.netbiosname, "DEFAULTSITE": names.sitename, "CONFIGDN": names.configdn, + "SERVERDN": names.serverdn }) if fill == FILL_FULL: -- cgit From ad8e3e41923e20d401294eccd4da028e0f40c904 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 10 Apr 2008 05:23:17 +0200 Subject: Add infrastructure for returning ProvisionResult in C provision code. (This used to be commit 98c3d34eb233be284e8c8994cca337be25c72968) --- source4/scripting/python/samba/provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index c9cdcdb768..ccf67a0b4a 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1082,7 +1082,7 @@ def provision_become_dc(setup_dir=None, """print a message if quiet is not set.""" print text - provision(setup_dir, message, system_session(), None, + return provision(setup_dir, message, system_session(), None, smbconf=smbconf, targetdir=targetdir, samdb_fill=FILL_DRS, realm=realm, rootdn=rootdn, domaindn=domaindn, schemadn=schemadn, configdn=configdn, serverdn=serverdn, domain=domain, hostname=hostname, hostip="127.0.0.1", domainsid=domainsid, machinepass=machinepass, serverrole="domain controller", sitename=sitename); -- cgit From 393007315d56d72cd4ebccc204da703b27eb968b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 11 Apr 2008 19:04:43 +1000 Subject: Far less cryptic traceback when you have an existing smb.conf When the user has an existing smb.conf, but no [netlogon] or [sysvol] share, the provision script would trigger a traceback. While we still need to abort in this situation, we do so now with a useful error. Andrew Bartlett (This used to be commit 10a8b7ea487f9725f69b02c4dd9cf5e1f67a23ab) --- source4/scripting/python/samba/provision.py | 27 +++++++++++++++++++++------ 1 file changed, 21 insertions(+), 6 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 16b1eb2156..4f264b6fc9 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -87,6 +87,7 @@ class ProvisionNames: self.domain = None self.hostname = None self.sitename = None + self.smbconf = None class ProvisionResult: def __init__(self): @@ -262,6 +263,8 @@ def provision_paths_from_lp(lp, dnsdomain): paths.netlogon = lp.get("path", "netlogon") + paths.smbconf = lp.configfile() + return paths @@ -1009,12 +1012,24 @@ def provision(setup_dir, message, session_info, ldap_backend_type=ldap_backend_type) if lp.get("server role") == "domain controller": - policy_path = os.path.join(paths.sysvol, names.dnsdomain, "Policies", - "{" + policyguid + "}") - os.makedirs(policy_path, 0755) - os.makedirs(os.path.join(policy_path, "Machine"), 0755) - os.makedirs(os.path.join(policy_path, "User"), 0755) - if not os.path.isdir(paths.netlogon): + if paths.netlogon is None: + message("Existing smb.conf does not have a [netlogon] share, but you are configuring a DC.") + message("Please either remove %s or see the template at %s" % + ( paths.smbconf, setup_path("provision.smb.conf.dc"))) + assert(paths.netlogon is not None) + + if paths.sysvol is None: + message("Existing smb.conf does not have a [sysvol] share, but you are configuring a DC.") + message("Please either remove %s or see the template at %s" % + (paths.smbconf, setup_path("provision.smb.conf.dc"))) + assert(paths.sysvol is not None) + + policy_path = os.path.join(paths.sysvol, names.dnsdomain, "Policies", + "{" + policyguid + "}") + os.makedirs(policy_path, 0755) + os.makedirs(os.path.join(policy_path, "Machine"), 0755) + os.makedirs(os.path.join(policy_path, "User"), 0755) + if not os.path.isdir(paths.netlogon): os.makedirs(paths.netlogon, 0755) if samdb_fill == FILL_FULL: -- cgit From e44f0e7b75a15e61427a6520999d0d79b78e9d2a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 11 Apr 2008 19:33:52 +1000 Subject: Don't reopen the sam.ldb again Andrew Bartlett (This used to be commit b51b8a2d846284de4dff736fc18cf747c188de96) --- source4/scripting/python/samba/provision.py | 2 -- 1 file changed, 2 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 4f264b6fc9..a8d188e7a3 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -741,8 +741,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, return samdb message("Pre-loading the Samba 4 and AD schema") - samdb = SamDB(path, session_info=session_info, - credentials=credentials, lp=lp) samdb.set_domain_sid(domainsid) if serverrole == "domain controller": samdb.set_invocation_id(invocationid) -- cgit From f8f4856ab7330db865d1a35abff3ccaf2ac277ba Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 15 Apr 2008 15:52:52 +0200 Subject: Fix provision-backend script Andrew Bartlett (This used to be commit ee6e4f8da229ddeca856a6db94236367aae06f63) --- source4/scripting/python/samba/provision.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index a8d188e7a3..45965a2429 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1166,6 +1166,7 @@ def provision_backend(setup_dir=None, message=None, "NETBIOSNAME": names.netbiosname, "DEFAULTSITE": DEFAULTSITE, "CONFIGDN": names.configdn, + "SERVERDN": names.serverdn }) setup_add_ldif(schemadb, setup_path("schema_samba4.ldif"), @@ -1241,9 +1242,9 @@ refint_attributes""" + refint_attributes + "\n"; setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "user")) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "config")) - setup_db_config(setup_path, file, os.path.join(paths.ldapdir, "schema")) + setup_db_config(setup_path, os.path.join(paths.ldapdir, "user")) + setup_db_config(setup_path, os.path.join(paths.ldapdir, "config")) + setup_db_config(setup_path, os.path.join(paths.ldapdir, "schema")) mapping = "schema-map-openldap-2.3" backend_schema = "backend-schema.schema" -- cgit From 2ddd23a8754258b7322f37a0e0b97587b23f338b Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 15 Apr 2008 17:10:47 +0200 Subject: Re-add 'db' subdirectory for LDAP backend provision Andrew Bartlett (This used to be commit 19890c0d15adf4f099365f276a4bfdd3f4de52b6) --- source4/scripting/python/samba/provision.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 45965a2429..0e8840646c 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1242,9 +1242,9 @@ refint_attributes""" + refint_attributes + "\n"; setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) - setup_db_config(setup_path, os.path.join(paths.ldapdir, "user")) - setup_db_config(setup_path, os.path.join(paths.ldapdir, "config")) - setup_db_config(setup_path, os.path.join(paths.ldapdir, "schema")) + setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "user"))) + setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "config"))) + setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "schema"))) mapping = "schema-map-openldap-2.3" backend_schema = "backend-schema.schema" -- cgit From 5319d9620b9ef68b3687d76aeaba5fa5d5c57a18 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 May 2008 03:31:26 +0200 Subject: Use consistent function names with the standard Python uuid module that is available in >= 2.4. (This used to be commit 60d458e3195eef6baf655fee0da7c3f68517e8e6) --- source4/scripting/python/samba/provision.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 0e8840646c..60fa22e6c4 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -910,7 +910,7 @@ def provision(setup_dir, message, session_info, domainsid = security.Sid(domainsid) if policyguid is None: - policyguid = uuid.random() + policyguid = uuid.uuid4() if adminpass is None: adminpass = misc.random_password(12) if krbtgtpass is None: @@ -960,7 +960,7 @@ def provision(setup_dir, message, session_info, assert serverrole in ("domain controller", "member server", "standalone") if invocationid is None and serverrole == "domain controller": - invocationid = uuid.random() + invocationid = uuid.uuid4() if not os.path.exists(paths.private_dir): os.mkdir(paths.private_dir) -- cgit From 251f6bd99159337b24b8aa8298a5c98de153bce0 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sun, 11 May 2008 04:36:37 +0200 Subject: make sure to always use string version of uuid rather than object. (This used to be commit bcd5fc7dc9899deb9fa84fdeeb21ed2ddb921308) --- source4/scripting/python/samba/provision.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 60fa22e6c4..ad8eb8bffd 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -689,6 +689,7 @@ def setup_self_join(samdb, names, domainsid, invocationid, setup_path, policyguid): """Join a host to its own domain.""" + assert isinstance(invocationid, str) setup_add_ldif(samdb, setup_path("provision_self_join.ldif"), { "CONFIGDN": names.configdn, "SCHEMADN": names.schemadn, @@ -910,7 +911,7 @@ def provision(setup_dir, message, session_info, domainsid = security.Sid(domainsid) if policyguid is None: - policyguid = uuid.uuid4() + policyguid = str(uuid.uuid4()) if adminpass is None: adminpass = misc.random_password(12) if krbtgtpass is None: @@ -960,7 +961,7 @@ def provision(setup_dir, message, session_info, assert serverrole in ("domain controller", "member server", "standalone") if invocationid is None and serverrole == "domain controller": - invocationid = uuid.uuid4() + invocationid = str(uuid.uuid4()) if not os.path.exists(paths.private_dir): os.mkdir(paths.private_dir) -- cgit From 25ea110c3814abcb824adb3619a44622ba8d2936 Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Sat, 17 May 2008 23:24:48 -0500 Subject: provision: Create instructions for enabling DNS GSS-TSIG updates. Added code to the python provisioning to create the named.conf file that was previously generated by the EJS provisioning. Updated the named.conf template to provide the additional details necessary to get things working. (This used to be commit 0b7a6bfcba1b906dc4d461882b4c3fe3c91c44e0) --- source4/scripting/python/samba/provision.py | 32 ++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index ad8eb8bffd..4818a79f00 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -236,6 +236,7 @@ def provision_paths_from_lp(lp, dnsdomain): paths.secrets = os.path.join(paths.private_dir, lp.get("secrets database") or "secrets.ldb") paths.templates = os.path.join(paths.private_dir, "templates.ldb") paths.dns = os.path.join(paths.private_dir, dnsdomain + ".zone") + paths.namedconf = os.path.join(paths.private_dir, "named.conf") paths.winsdb = os.path.join(paths.private_dir, "wins.ldb") paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi") paths.phpldapadminconfig = os.path.join(paths.private_dir, @@ -1059,12 +1060,14 @@ def provision(setup_dir, message, session_info, scope=SCOPE_SUBTREE) assert isinstance(hostguid, str) - create_zone_file(paths.dns, setup_path, samdb, + create_zone_file(paths.dns, paths.namedconf, setup_path, samdb, hostname=names.hostname, hostip=hostip, hostip6=hostip6, dnsdomain=names.dnsdomain, domaindn=names.domaindn, dnspass=dnspass, realm=names.realm, - domainguid=domainguid, hostguid=hostguid) + domainguid=domainguid, hostguid=hostguid, + private_dir=paths.private_dir, keytab_name=paths.dns_keytab) message("Please install the zone located in %s into your DNS server" % paths.dns) + message("See %s if you want to use secure GSS-TSIG updates" % paths.namedconf) create_phpldapadmin_config(paths.phpldapadminconfig, setup_path, ldapi_url) @@ -1281,12 +1284,18 @@ def create_phpldapadmin_config(path, setup_path, ldapi_uri): {"S4_LDAPI_URI": ldapi_uri}) -def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, - hostip, hostip6, hostname, dnspass, realm, domainguid, hostguid): +def create_zone_file(path_zone, path_conf, setup_path, samdb, dnsdomain, domaindn, + hostip, hostip6, hostname, dnspass, realm, domainguid, hostguid, + private_dir, keytab_name): """Write out a DNS zone file, from the info in the current database. + + Also writes a file with stubs appropriate for a DNS configuration file + (including GSS-TSIG configuration), and details as to some of the other + configuration changes that may be necessary. - :param path: Path of the new file. - :param setup_path": Setup path function. + :param path_zone: Path of the new zone file. + :param path_conf: Path of the config stubs file. + :param setup_path: Setup path function. :param samdb: SamDB object :param dnsdomain: DNS Domain name :param domaindn: DN of the Domain @@ -1307,7 +1316,7 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, hostip6_base_line = " IN AAAA " + hostip6 hostip6_host_line = hostname + " IN AAAA " + hostip6 - setup_file(setup_path("provision.zone"), path, { + setup_file(setup_path("provision.zone"), path_zone, { "DNSPASS_B64": b64encode(dnspass), "HOSTNAME": hostname, "DNSDOMAIN": dnsdomain, @@ -1321,6 +1330,15 @@ def create_zone_file(path, setup_path, samdb, dnsdomain, domaindn, "HOSTIP6_HOST_LINE": hostip6_host_line, }) + setup_file(setup_path("named.conf"), path_conf, { + "DNSDOMAIN": dnsdomain, + "REALM": realm, + "REALM_WC": "*." + ".".join(realm.split(".")[1:]), + "HOSTNAME": hostname, + "DNS_KEYTAB": keytab_name, + "DNS_KEYTAB_ABS": os.path.join(private_dir, keytab_name), + }) + def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): """Load schema for the SamDB. -- cgit From bf3f3af92677bce8f03b0dd2be552d6c8c730ca1 Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Wed, 21 May 2008 18:12:36 -0500 Subject: provision: Generate krb5.conf template separate from named.conf template. (This used to be commit ebf130e9e57b640129cf0d05dbd7d210b71ea371) --- source4/scripting/python/samba/provision.py | 74 ++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 22 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 4818a79f00..69c7e8846d 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -237,6 +237,7 @@ def provision_paths_from_lp(lp, dnsdomain): paths.templates = os.path.join(paths.private_dir, "templates.ldb") paths.dns = os.path.join(paths.private_dir, dnsdomain + ".zone") paths.namedconf = os.path.join(paths.private_dir, "named.conf") + paths.krb5conf = os.path.join(paths.private_dir, "krb5.conf") paths.winsdb = os.path.join(paths.private_dir, "wins.ldb") paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi") paths.phpldapadminconfig = os.path.join(paths.private_dir, @@ -1059,16 +1060,23 @@ def provision(setup_dir, message, session_info, expression="(&(objectClass=computer)(cn=%s))" % names.hostname, scope=SCOPE_SUBTREE) assert isinstance(hostguid, str) - - create_zone_file(paths.dns, paths.namedconf, setup_path, samdb, - hostname=names.hostname, hostip=hostip, - hostip6=hostip6, dnsdomain=names.dnsdomain, - domaindn=names.domaindn, dnspass=dnspass, realm=names.realm, - domainguid=domainguid, hostguid=hostguid, - private_dir=paths.private_dir, keytab_name=paths.dns_keytab) + + create_zone_file(paths.dns, setup_path, dnsdomain=names.dnsdomain, + domaindn=names.domaindn, hostip=hostip, + hostip6=hostip6, hostname=names.hostname, + dnspass=dnspass, realm=names.realm, + domainguid=domainguid, hostguid=hostguid) message("Please install the zone located in %s into your DNS server" % paths.dns) - message("See %s if you want to use secure GSS-TSIG updates" % paths.namedconf) - + + create_named_conf(paths.namedconf, setup_path, realm=names.realm, + dnsdomain=names.dnsdomain, private_dir=paths.private_dir, + keytab_name=paths.dns_keytab) + message("See %s for example configuration statements for secure GSS-TSIG updates" % paths.namedconf) + + create_krb5_conf(paths.krb5conf, setup_path, dnsdomain=names.dnsdomain, + hostname=names.hostname, realm=names.realm) + message("A Kerberos configuration suitable for Samba 4 has been generated at %s" % paths.krb5conf) + create_phpldapadmin_config(paths.phpldapadminconfig, setup_path, ldapi_url) @@ -1284,19 +1292,12 @@ def create_phpldapadmin_config(path, setup_path, ldapi_uri): {"S4_LDAPI_URI": ldapi_uri}) -def create_zone_file(path_zone, path_conf, setup_path, samdb, dnsdomain, domaindn, - hostip, hostip6, hostname, dnspass, realm, domainguid, hostguid, - private_dir, keytab_name): +def create_zone_file(path, setup_path, dnsdomain, domaindn, + hostip, hostip6, hostname, dnspass, realm, domainguid, hostguid): """Write out a DNS zone file, from the info in the current database. - Also writes a file with stubs appropriate for a DNS configuration file - (including GSS-TSIG configuration), and details as to some of the other - configuration changes that may be necessary. - - :param path_zone: Path of the new zone file. - :param path_conf: Path of the config stubs file. + :param path: Path of the new zone file. :param setup_path: Setup path function. - :param samdb: SamDB object :param dnsdomain: DNS Domain name :param domaindn: DN of the Domain :param hostip: Local IPv4 IP @@ -1316,7 +1317,7 @@ def create_zone_file(path_zone, path_conf, setup_path, samdb, dnsdomain, domaind hostip6_base_line = " IN AAAA " + hostip6 hostip6_host_line = hostname + " IN AAAA " + hostip6 - setup_file(setup_path("provision.zone"), path_zone, { + setup_file(setup_path("provision.zone"), path, { "DNSPASS_B64": b64encode(dnspass), "HOSTNAME": hostname, "DNSDOMAIN": dnsdomain, @@ -1330,15 +1331,44 @@ def create_zone_file(path_zone, path_conf, setup_path, samdb, dnsdomain, domaind "HOSTIP6_HOST_LINE": hostip6_host_line, }) - setup_file(setup_path("named.conf"), path_conf, { +def create_named_conf(path, setup_path, realm, dnsdomain, + private_dir, keytab_name): + """Write out a file containing zone statements suitable for inclusion in a + named.conf file (including GSS-TSIG configuration). + + :param path: Path of the new named.conf file. + :param setup_path: Setup path function. + :param realm: Realm name + :param dnsdomain: DNS Domain name + :param private_dir: Path to private directory + :param keytab_name: File name of DNS keytab file + """ + + setup_file(setup_path("named.conf"), path, { "DNSDOMAIN": dnsdomain, "REALM": realm, "REALM_WC": "*." + ".".join(realm.split(".")[1:]), - "HOSTNAME": hostname, "DNS_KEYTAB": keytab_name, "DNS_KEYTAB_ABS": os.path.join(private_dir, keytab_name), }) +def create_krb5_conf(path, setup_path, dnsdomain, hostname, realm): + """Write out a file containing zone statements suitable for inclusion in a + named.conf file (including GSS-TSIG configuration). + + :param path: Path of the new named.conf file. + :param setup_path: Setup path function. + :param dnsdomain: DNS Domain name + :param hostname: Local hostname + :param realm: Realm name + """ + + setup_file(setup_path("krb5.conf"), path, { + "DNSDOMAIN": dnsdomain, + "HOSTNAME": hostname, + "REALM": realm, + }) + def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): """Load schema for the SamDB. -- cgit From c401aa93573460f10256218a6a1902839b17b884 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Thu, 22 May 2008 17:42:18 +0200 Subject: Use restructuredText formatting for docstrings. (This used to be commit 0cc58decd74d20f3d7dff93ddef1c8bce4d49ad0) --- source4/scripting/python/samba/provision.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 69c7e8846d..68b43eff40 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -43,6 +43,8 @@ from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ """Functions for setting up a Samba configuration.""" +__docformat__ = "restructuredText" + DEFAULTSITE = "Default-First-Site-Name" class InvalidNetbiosName(Exception): -- cgit From e3d000f3bfad4126ab781f15848fff3bbd8abcc5 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 23 May 2008 16:29:08 +0200 Subject: Some more PEP improvements. (This used to be commit 015ca850df9b4c8112b033130023909b1d0b78b7) --- source4/scripting/python/samba/provision.py | 35 +++++++++++++++-------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index fe9b582d56..fdcc3dad77 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1111,7 +1111,7 @@ def provision_become_dc(setup_dir=None, return provision(setup_dir, message, system_session(), None, smbconf=smbconf, targetdir=targetdir, samdb_fill=FILL_DRS, realm=realm, rootdn=rootdn, domaindn=domaindn, schemadn=schemadn, configdn=configdn, serverdn=serverdn, - domain=domain, hostname=hostname, hostip="127.0.0.1", domainsid=domainsid, machinepass=machinepass, serverrole="domain controller", sitename=sitename); + domain=domain, hostname=hostname, hostip="127.0.0.1", domainsid=domainsid, machinepass=machinepass, serverrole="domain controller", sitename=sitename) def setup_db_config(setup_path, dbdir): @@ -1120,9 +1120,9 @@ def setup_db_config(setup_path, dbdir): :param setup_path: Setup path function. :param dbdir: Database directory.""" if not os.path.isdir(os.path.join(dbdir, "bdb-logs")): - os.makedirs(os.path.join(dbdir, "bdb-logs"), 0700); + os.makedirs(os.path.join(dbdir, "bdb-logs"), 0700) if not os.path.isdir(os.path.join(dbdir, "tmp")): - os.makedirs(os.path.join(dbdir, "tmp"), 0700); + os.makedirs(os.path.join(dbdir, "tmp"), 0700) setup_file(setup_path("DB_CONFIG"), os.path.join(dbdir, "DB_CONFIG"), {"LDAPDBDIR": dbdir}) @@ -1145,8 +1145,9 @@ def provision_backend(setup_dir=None, message=None, root = findnss(pwd.getpwnam, ["root"])[0] if smbconf is None: - os.makedirs(os.path.join(targetdir, "etc")) - smbconf = os.path.join(targetdir, "etc", "smb.conf") + etcdir = os.path.join(targetdir, "etc") + os.makedirs(etcdir) + smbconf = os.path.join(etcdir, "smb.conf") # only install a new smb.conf if there isn't one there already if not os.path.exists(smbconf): @@ -1220,20 +1221,18 @@ def provision_backend(setup_dir=None, message=None, elif ldap_backend_type == "openldap": attrs = ["linkID", "lDAPDisplayName"] - res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs); + res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs) - memberof_config = "# Generated from schema in " + schemadb_path + "\n"; - refint_attributes = ""; + memberof_config = "# Generated from schema in %s\n" % schemadb_path + refint_attributes = "" for i in range (0, len(res)): - linkid = res[i]["linkID"][0] - linkid = str(int(linkid) + 1) - expression = "(&(objectclass=attributeSchema)(linkID=" + (linkid) + "))" + expression = "(&(objectclass=attributeSchema)(linkID=%d))" % (int(res[i]["linkID"][0])+1) target = schemadb.searchone(basedn=names.schemadn, expression=expression, attribute="lDAPDisplayName", - scope=SCOPE_SUBTREE); + scope=SCOPE_SUBTREE) if target is not None: - refint_attributes = refint_attributes + " " + target + " " + res[i]["lDAPDisplayName"][0]; + refint_attributes = refint_attributes + " " + target + " " + res[i]["lDAPDisplayName"][0] memberof_config = memberof_config + """overlay memberof memberof-dangling error memberof-refint TRUE @@ -1242,11 +1241,11 @@ memberof-member-ad """ + res[i]["lDAPDisplayName"][0] + """ memberof-memberof-ad """ + target + """ memberof-dangling-error 32 -"""; +""" memberof_config = memberof_config + """ overlay refint -refint_attributes""" + refint_attributes + "\n"; +refint_attributes""" + refint_attributes + "\n" setup_file(setup_path("slapd.conf"), paths.slapdconf, {"DNSDOMAIN": names.dnsdomain, @@ -1273,12 +1272,12 @@ refint_attributes""" + refint_attributes + "\n"; server_port_string = "" slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string - schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema); + schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema) os.system(schema_command) - message("Your %s Backend for Samba4 is now configured, and is ready to be started" % ( ldap_backend_type) ) + message("Your %s Backend for Samba4 is now configured, and is ready to be started" % ldap_backend_type) message("Server Role: %s" % serverrole) message("Hostname: %s" % names.hostname) message("DNS Domain: %s" % names.dnsdomain) @@ -1337,6 +1336,7 @@ def create_zone_file(path, setup_path, dnsdomain, domaindn, "HOSTIP6_HOST_LINE": hostip6_host_line, }) + def create_named_conf(path, setup_path, realm, dnsdomain, private_dir, keytab_name): """Write out a file containing zone statements suitable for inclusion in a @@ -1375,6 +1375,7 @@ def create_krb5_conf(path, setup_path, dnsdomain, hostname, realm): "REALM": realm, }) + def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): """Load schema for the SamDB. -- cgit From a203ee1ab18ea68c6df436f8bb9fc0772611d5d1 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 23 May 2008 16:43:26 +0200 Subject: Fix indentation, add docstring in provisioning script. (This used to be commit 86a8a085496c292b390c0d6362e3e4d9980df83f) --- source4/scripting/python/samba/provision.py | 29 +++++++++++++++-------------- 1 file changed, 15 insertions(+), 14 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index fdcc3dad77..a4730d8a07 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -48,6 +48,7 @@ __docformat__ = "restructuredText" DEFAULTSITE = "Default-First-Site-Name" class InvalidNetbiosName(Exception): + """A specified name was not a valid NetBIOS name.""" def __init__(self, name): super(InvalidNetbiosName, self).__init__("The name '%r' is not a valid NetBIOS name" % name) @@ -1233,7 +1234,7 @@ def provision_backend(setup_dir=None, message=None, scope=SCOPE_SUBTREE) if target is not None: refint_attributes = refint_attributes + " " + target + " " + res[i]["lDAPDisplayName"][0] - memberof_config = memberof_config + """overlay memberof + memberof_config += """overlay memberof memberof-dangling error memberof-refint TRUE memberof-group-oc top @@ -1243,7 +1244,7 @@ memberof-dangling-error 32 """ - memberof_config = memberof_config + """ + memberof_config += """ overlay refint refint_attributes""" + refint_attributes + "\n" @@ -1259,18 +1260,18 @@ refint_attributes""" + refint_attributes + "\n" setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) - setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "user"))) - setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "config"))) - setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "schema"))) - mapping = "schema-map-openldap-2.3" - backend_schema = "backend-schema.schema" - - ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") - if ldap_backend_port is not None: - server_port_string = " -h ldap://0.0.0.0:%d" % ldap_backend_port - else: - server_port_string = "" - slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string + setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "user"))) + setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "config"))) + setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "schema"))) + mapping = "schema-map-openldap-2.3" + backend_schema = "backend-schema.schema" + + ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") + if ldap_backend_port is not None: + server_port_string = " -h ldap://0.0.0.0:%d" % ldap_backend_port + else: + server_port_string = "" + slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema) -- cgit From 73b789b6d25698dba15c867c71d0cdd8c264f352 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 24 May 2008 04:01:57 +0200 Subject: Add docstrings to a couple more python modules. (This used to be commit b4560c90e5e8d3a35367d3a21d361dc4c9c0de23) --- source4/scripting/python/samba/provision.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index a4730d8a07..3914fa8376 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -22,6 +22,8 @@ # along with this program. If not, see . # +"""Functions for setting up a Samba configuration.""" + from base64 import b64encode import os import pwd @@ -41,8 +43,6 @@ import urllib from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ LDB_ERR_NO_SUCH_OBJECT, timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE -"""Functions for setting up a Samba configuration.""" - __docformat__ = "restructuredText" DEFAULTSITE = "Default-First-Site-Name" -- cgit From 815c0ef2ed3bafe44c687dffe97b309b00df7a8c Mon Sep 17 00:00:00 2001 From: Andrew Kroeger Date: Fri, 23 May 2008 02:20:35 -0500 Subject: provision: Add missing string parameter token when assigning ldap_backend. (This used to be commit 7d26145a7fba22b2e1c7c57053aab3180a22089d) --- source4/scripting/python/samba/provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 3914fa8376..4a9def8aa9 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -969,7 +969,7 @@ def provision(setup_dir, message, session_info, if ldap_backend is not None: if ldap_backend == "ldapi": # provision-backend will set this path suggested slapd command line / fedorads.inf - ldap_backend = "ldapi://" % urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") + ldap_backend = "ldapi://%s" % urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") # only install a new shares config db if there is none if not os.path.exists(paths.shareconf): -- cgit From b7c8e020a6f7221d6d10f2dd7610a232edeedf83 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 29 May 2008 18:38:17 +1000 Subject: Print prefixMap in a human-readable format. This should allow the prefixMap to be edited, until we find the right way to autogenerate it. Andrew Bartlett (This used to be commit 24ae9a55ec326807afd8d5bfa0a422a6668bd7c3) --- source4/scripting/python/samba/provision.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 4a9def8aa9..71c1ac3187 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -797,13 +797,17 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" }) message("Modifying schema container") + + prefixmap = open(setup_path("prefixMap.txt"), 'r').read() + setup_modify_ldif(samdb, setup_path("provision_schema_basedn_modify.ldif"), { "SCHEMADN": names.schemadn, "NETBIOSNAME": names.netbiosname, "DEFAULTSITE": names.sitename, "CONFIGDN": names.configdn, - "SERVERDN": names.serverdn + "SERVERDN": names.serverdn, + "PREFIXMAP_B64": b64encode(prefixmap) }) message("Setting up sam.ldb Samba4 schema") @@ -1389,12 +1393,16 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): schema_data = open(setup_path("schema.ldif"), 'r').read() schema_data += open(setup_path("schema_samba4.ldif"), 'r').read() schema_data = substitute_var(schema_data, {"SCHEMADN": schemadn}) + prefixmap = open(setup_path("prefixMap.txt"), 'r').read() + prefixmap = b64encode(prefixmap) + head_data = open(setup_path("provision_schema_basedn_modify.ldif"), 'r').read() head_data = substitute_var(head_data, { "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, "CONFIGDN": configdn, - "DEFAULTSITE":sitename + "DEFAULTSITE":sitename, + "PREFIXMAP_B64":prefixmap }) samdb.attach_schema_from_ldif(head_data, schema_data) -- cgit From b9babfe4cc70b96f4f1df037244cd27eae580c94 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 30 May 2008 14:26:47 +1000 Subject: Fix up provision and samdb tests. This fixes up the provision to operate with a target directory - it must override the smb.conf in this case. Andrew Bartlett (This used to be commit 89fc39f7edb214065aff461bc225f41443eae3c7) --- source4/scripting/python/samba/provision.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 71c1ac3187..b7112e16c3 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -930,8 +930,9 @@ def provision(setup_dir, message, session_info, if aci is None: aci = "# no aci for local ldb" - if smbconf is None: - os.makedirs(os.path.join(targetdir, "etc")) + if targetdir is not None: + if (not os.path.exists(os.path.join(targetdir, "etc"))): + os.makedirs(os.path.join(targetdir, "etc")) smbconf = os.path.join(targetdir, "etc", "smb.conf") # only install a new smb.conf if there isn't one there already -- cgit From 277287114679addc2ef26fbe6a82963f9cf1b196 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 30 May 2008 14:15:40 +0200 Subject: Fix samdb python test. (This used to be commit 0e3d488cc108174ca0f875aab16b9771c2933f19) --- source4/scripting/python/samba/provision.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index b7112e16c3..3f936c3301 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1321,12 +1321,12 @@ def create_zone_file(path, setup_path, dnsdomain, domaindn, """ assert isinstance(domainguid, str) - hostip6_base_line = "" - hostip6_host_line = "" - if hostip6 is not None: hostip6_base_line = " IN AAAA " + hostip6 hostip6_host_line = hostname + " IN AAAA " + hostip6 + else: + hostip6_base_line = "" + hostip6_host_line = "" setup_file(setup_path("provision.zone"), path, { "DNSPASS_B64": b64encode(dnspass), -- cgit From 370f95acfc197759f9140876b31ac127d3a0e10c Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Mon, 16 Jun 2008 17:51:42 -0400 Subject: Try to get a bit further with provisioning (This used to be commit 649f6c0c1084828dda7d50bd2904208192de77da) --- source4/scripting/python/samba/provision.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 3f936c3301..93a4c8f502 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1180,6 +1180,8 @@ def provision_backend(setup_dir=None, message=None, schemadb = Ldb(schemadb_path, lp=lp) + prefixmap = open(setup_path("prefixMap.txt"), 'r').read() + setup_add_ldif(schemadb, setup_path("provision_schema_basedn.ldif"), {"SCHEMADN": names.schemadn, "ACI": "#", @@ -1191,7 +1193,8 @@ def provision_backend(setup_dir=None, message=None, "NETBIOSNAME": names.netbiosname, "DEFAULTSITE": DEFAULTSITE, "CONFIGDN": names.configdn, - "SERVERDN": names.serverdn + "SERVERDN": names.serverdn, + "PREFIXMAP_B64": b64encode(prefixmap) }) setup_add_ldif(schemadb, setup_path("schema_samba4.ldif"), -- cgit From 9ea25cacf1c564a485897432b73beebf2e634f55 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 19 Jun 2008 11:05:20 +1000 Subject: Add a blackbox test for the provision-backend script. This test (as most tests do :-) found a few bugs, also fixed in this commit. Andrew Bartlett (This used to be commit d96a6482dad54d1d27a87107865e833a9c32cf53) --- source4/scripting/python/samba/provision.py | 57 +++++++++++++++-------------- 1 file changed, 30 insertions(+), 27 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 93a4c8f502..504044253e 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1150,15 +1150,18 @@ def provision_backend(setup_dir=None, message=None, if root is None: root = findnss(pwd.getpwnam, ["root"])[0] - if smbconf is None: - etcdir = os.path.join(targetdir, "etc") - os.makedirs(etcdir) - smbconf = os.path.join(etcdir, "smb.conf") + if adminpass is None: + adminpass = misc.random_password(12) + + if targetdir is not None: + if (not os.path.exists(os.path.join(targetdir, "etc"))): + os.makedirs(os.path.join(targetdir, "etc")) + smbconf = os.path.join(targetdir, "etc", "smb.conf") # only install a new smb.conf if there isn't one there already if not os.path.exists(smbconf): - make_smbconf(smbconf, setup_path, hostname, domain, realm, - serverrole, targetdir) + make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole, + targetdir) lp = param.LoadParm() lp.load(smbconf) @@ -1230,11 +1233,11 @@ def provision_backend(setup_dir=None, message=None, elif ldap_backend_type == "openldap": attrs = ["linkID", "lDAPDisplayName"] - res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs) + res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs) - memberof_config = "# Generated from schema in %s\n" % schemadb_path - refint_attributes = "" - for i in range (0, len(res)): + memberof_config = "# Generated from schema in %s\n" % schemadb_path + refint_attributes = "" + for i in range (0, len(res)): expression = "(&(objectclass=attributeSchema)(linkID=%d))" % (int(res[i]["linkID"][0])+1) target = schemadb.searchone(basedn=names.schemadn, expression=expression, @@ -1252,11 +1255,11 @@ memberof-dangling-error 32 """ - memberof_config += """ + memberof_config += """ overlay refint refint_attributes""" + refint_attributes + "\n" - setup_file(setup_path("slapd.conf"), paths.slapdconf, + setup_file(setup_path("slapd.conf"), paths.slapdconf, {"DNSDOMAIN": names.dnsdomain, "LDAPDIR": paths.ldapdir, "DOMAINDN": names.domaindn, @@ -1265,27 +1268,27 @@ refint_attributes""" + refint_attributes + "\n" "LDAPMANAGERDN": names.ldapmanagerdn, "LDAPMANAGERPASS": adminpass, "MEMBEROF_CONFIG": memberof_config}) - setup_file(setup_path("modules.conf"), paths.modulesconf, + setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) - setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "user"))) - setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "config"))) - setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "schema"))) - mapping = "schema-map-openldap-2.3" - backend_schema = "backend-schema.schema" - - ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") - if ldap_backend_port is not None: - server_port_string = " -h ldap://0.0.0.0:%d" % ldap_backend_port - else: - server_port_string = "" - slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string + setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "user"))) + setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "config"))) + setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "schema"))) + mapping = "schema-map-openldap-2.3" + backend_schema = "backend-schema.schema" - schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema) + ldapi_uri = "ldapi://" + urllib.quote(os.path.join(paths.private_dir, "ldap", "ldapi"), safe="") + if ldap_backend_port is not None: + server_port_string = " -h ldap://0.0.0.0:%d" % ldap_backend_port + else: + server_port_string = "" + slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string + + schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema) + os.system(schema_command) - message("Your %s Backend for Samba4 is now configured, and is ready to be started" % ldap_backend_type) message("Server Role: %s" % serverrole) message("Hostname: %s" % names.hostname) -- cgit From a6b842f9634cbeb4075c2bbaf7e49c19104602be Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 15 Jul 2008 15:15:12 +1000 Subject: Connect to the LDAP backend with SASL credentials. This reworks our LDAP backend code to move from anonymous access to a shared-secret SASL-protected connection. (SASL selects NTLM or DIGEST-MD5 on my system). To get this working, we must pre-populate the LDAP backend with a DN to store ths SASL secret on, and we use back-ldif for this. This gives us a reasonable basis to deploy a replicated OpenLDAP backend solution. Andrew Bartlett (This used to be commit cd0745253c4a9ec59a035e830e54d74a05b71aaa) --- source4/scripting/python/samba/provision.py | 47 +++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 9 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 504044253e..d0f612c7a8 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -604,6 +604,20 @@ def setup_secretsdb(path, setup_path, session_info, credentials, lp): secrets_ldb = Ldb(path, session_info=session_info, credentials=credentials, lp=lp) secrets_ldb.load_ldif_file_add(setup_path("secrets.ldif")) + + if credentials.authentication_requested: + if credentials.get_bind_dn() is not None: + setup_add_ldif(secrets_ldb, setup_path("secrets_simple_ldap.ldif"), { + "LDAPMANAGERDN": credentials.get_bind_dn(), + "LDAPMANAGERPASS_B64": b64encode(credentials.get_password()) + }) + else: + setup_add_ldif(secrets_ldb, setup_path("secrets_sasl_ldap.ldif"), { + "LDAPADMINUSER": credentials.get_username(), + "LDAPADMINREALM": credentials.get_realm(), + "LDAPADMINPASS_B64": b64encode(credentials.get_password()) + }) + return secrets_ldb @@ -754,10 +768,10 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, domain_oc = "samba4LocalDomain" setup_add_ldif(samdb, setup_path("provision_basedn.ldif"), { - "DOMAINDN": names.domaindn, - "ACI": aci, - "DOMAIN_OC": domain_oc - }) + "DOMAINDN": names.domaindn, + "ACI": aci, + "DOMAIN_OC": domain_oc + }) message("Modifying DomainDN: " + names.domaindn + "") if domainguid is not None: @@ -1265,15 +1279,30 @@ refint_attributes""" + refint_attributes + "\n" "DOMAINDN": names.domaindn, "CONFIGDN": names.configdn, "SCHEMADN": names.schemadn, - "LDAPMANAGERDN": names.ldapmanagerdn, - "LDAPMANAGERPASS": adminpass, "MEMBEROF_CONFIG": memberof_config}) setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) - setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "user"))) - setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "config"))) - setup_db_config(setup_path, os.path.join(paths.ldapdir, os.path.join("db", "schema"))) + setup_db_config(setup_path, os.path.join(paths.ldapdir, "db", "user")) + setup_db_config(setup_path, os.path.join(paths.ldapdir, "db", "config")) + setup_db_config(setup_path, os.path.join(paths.ldapdir, "db", "schema")) + + if not os.path.exists(os.path.join(paths.ldapdir, "db", "samba", "cn=samba")): + os.makedirs(os.path.join(paths.ldapdir, "db", "samba", "cn=samba")) + + setup_file(setup_path("cn=samba.ldif"), + os.path.join(paths.ldapdir, "db", "samba", "cn=samba.ldif"), + { "UUID": str(uuid.uuid4()), + "LDAPTIME": timestring(int(time.time()))} ) + setup_file(setup_path("cn=samba-admin.ldif"), + os.path.join(paths.ldapdir, "db", "samba", "cn=samba", "cn=samba-admin.ldif"), + {"LDAPADMINPASS_B64": b64encode(adminpass), + "UUID": str(uuid.uuid4()), + "LDAPTIME": timestring(int(time.time()))} ) + +#"LDAPMANAGERDN": names.ldapmanagerdn, + + mapping = "schema-map-openldap-2.3" backend_schema = "backend-schema.schema" -- cgit From 0f1eea267257eff0d75a702ee0793a86834fb76a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 15 Jul 2008 15:46:32 +1000 Subject: Rework provision to handle both simple and SASL binds. Fedora DS is still setup for simple binds only, at this point. (it also fails on other issues). Andrew Bartlett (This used to be commit b24c572d5a38c1f6906751c2ad2f809e1995b510) --- source4/scripting/python/samba/provision.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d0f612c7a8..f27cc17290 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1300,9 +1300,6 @@ refint_attributes""" + refint_attributes + "\n" "UUID": str(uuid.uuid4()), "LDAPTIME": timestring(int(time.time()))} ) -#"LDAPMANAGERDN": names.ldapmanagerdn, - - mapping = "schema-map-openldap-2.3" backend_schema = "backend-schema.schema" @@ -1323,7 +1320,12 @@ refint_attributes""" + refint_attributes + "\n" message("Hostname: %s" % names.hostname) message("DNS Domain: %s" % names.dnsdomain) message("Base DN: %s" % names.domaindn) - message("LDAP admin DN: %s" % names.ldapmanagerdn) + + if ldap_backend_type == "openldap": + message("LDAP admin user: samba-admin") + else: + message("LDAP admin DN: %s" % names.ldapmanagerdn) + message("LDAP admin password: %s" % adminpass) message(slapdcommand) -- cgit From e400b3ec4e7f32406ed8803ed22612033511d99a Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 15 Jul 2008 18:44:58 +1000 Subject: Fix asking for credentials for non-LDAP provisions. (This used to be commit 78416f4840df4f8d1f9cc5e46a48b19c86888050) --- source4/scripting/python/samba/provision.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index f27cc17290..6102dc77ff 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -605,7 +605,7 @@ def setup_secretsdb(path, setup_path, session_info, credentials, lp): lp=lp) secrets_ldb.load_ldif_file_add(setup_path("secrets.ldif")) - if credentials.authentication_requested: + if credentials is not None and credentials.authentication_requested(): if credentials.get_bind_dn() is not None: setup_add_ldif(secrets_ldb, setup_path("secrets_simple_ldap.ldif"), { "LDAPMANAGERDN": credentials.get_bind_dn(), -- cgit From fe9fa62a0529f8c8ebdbfee9b994e3787d4db58f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 16 Jul 2008 14:04:24 +1000 Subject: Reorder whitespace in generated slapd.conf This helps us see the real groupings in the generated memberOf handling. Andrew Bartlett (This used to be commit ec70ebb8310e563324233662f8e779c55fb87514) --- source4/scripting/python/samba/provision.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 6102dc77ff..17e7e0fed0 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1266,12 +1266,12 @@ memberof-group-oc top memberof-member-ad """ + res[i]["lDAPDisplayName"][0] + """ memberof-memberof-ad """ + target + """ memberof-dangling-error 32 - """ - memberof_config += """ -overlay refint -refint_attributes""" + refint_attributes + "\n" + memberof_config += """overlay refint +refint_attributes""" + refint_attributes + """ + +""" setup_file(setup_path("slapd.conf"), paths.slapdconf, {"DNSDOMAIN": names.dnsdomain, -- cgit From cfc2063f230491865edb8f73174e0b12ab4dc158 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 18 Jul 2008 18:44:07 +1000 Subject: Put the memberof template into a seperate setup/ file. Set a memberof-dn in a fruitless attempt to fix the ACL problem I'm having with OpenLDAP Andrew Bartlett (This used to be commit 6d6e03834a1a77a8ceba41fbe8c9d49680065ba3) --- source4/scripting/python/samba/provision.py | 60 +++++++++++++---------------- 1 file changed, 27 insertions(+), 33 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 17e7e0fed0..301c6ef728 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -153,6 +153,19 @@ def open_ldb(session_info, credentials, lp, dbname): lp=lp) +def read_and_sub_file(file, subst_vars): + """Read a file and sub in variables found in it + + :param file: File to be read (typically from setup directory) + param subst_vars: Optional variables to subsitute in the file. + """ + data = open(file, 'r').read() + if subst_vars is not None: + data = substitute_var(data, subst_vars) + check_all_substituted(data) + return data + + def setup_add_ldif(ldb, ldif_path, subst_vars=None): """Setup a ldb in the private dir. @@ -162,27 +175,18 @@ def setup_add_ldif(ldb, ldif_path, subst_vars=None): """ assert isinstance(ldif_path, str) - data = open(ldif_path, 'r').read() - if subst_vars is not None: - data = substitute_var(data, subst_vars) - - check_all_substituted(data) - + data = read_and_sub_file(ldif_path, subst_vars) ldb.add_ldif(data) -def setup_modify_ldif(ldb, ldif_path, substvars=None): +def setup_modify_ldif(ldb, ldif_path, subst_vars=None): """Modify a ldb in the private dir. :param ldb: LDB object. :param ldif_path: LDIF file path. - :param substvars: Optional dictionary with substitution variables. + :param subst_vars: Optional dictionary with substitution variables. """ - data = open(ldif_path, 'r').read() - if substvars is not None: - data = substitute_var(data, substvars) - - check_all_substituted(data) + data = read_and_sub_file(ldif_path, subst_vars) ldb.modify_ldif(data) @@ -206,23 +210,19 @@ def setup_ldb(ldb, ldif_path, subst_vars): ldb.transaction_commit() -def setup_file(template, fname, substvars): +def setup_file(template, fname, subst_vars): """Setup a file in the private dir. :param template: Path of the template file. :param fname: Path of the file to create. - :param substvars: Substitution variables. + :param subst_vars: Substitution variables. """ f = fname if os.path.exists(f): os.unlink(f) - data = open(template, 'r').read() - if substvars: - data = substitute_var(data, substvars) - check_all_substituted(data) - + data = read_and_sub_file(template, subst_vars) open(f, 'w').write(data) @@ -1259,19 +1259,13 @@ def provision_backend(setup_dir=None, message=None, scope=SCOPE_SUBTREE) if target is not None: refint_attributes = refint_attributes + " " + target + " " + res[i]["lDAPDisplayName"][0] - memberof_config += """overlay memberof -memberof-dangling error -memberof-refint TRUE -memberof-group-oc top -memberof-member-ad """ + res[i]["lDAPDisplayName"][0] + """ -memberof-memberof-ad """ + target + """ -memberof-dangling-error 32 -""" - - memberof_config += """overlay refint -refint_attributes""" + refint_attributes + """ - -""" + + memberof_config += read_and_sub_file(setup_path("memberof.conf"), + { "MEMBER_ATTR" : str(res[i]["lDAPDisplayName"][0]), + "MEMBEROF_ATTR" : str(target) }) + + memberof_config += """overlay refint +refint_attributes""" + refint_attributes setup_file(setup_path("slapd.conf"), paths.slapdconf, {"DNSDOMAIN": names.dnsdomain, -- cgit From 3408a2d18fa61e2a7e3b3e05cc3c454e5e15f2ce Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 18 Jul 2008 18:58:56 +1000 Subject: Make a seperate template for the refint configuration too (This used to be commit d2a527acc5ee6fe9b943657dc9c3ace920b2d619) --- source4/scripting/python/samba/provision.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 301c6ef728..6eb47c8595 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1264,8 +1264,8 @@ def provision_backend(setup_dir=None, message=None, { "MEMBER_ATTR" : str(res[i]["lDAPDisplayName"][0]), "MEMBEROF_ATTR" : str(target) }) - memberof_config += """overlay refint -refint_attributes""" + refint_attributes + refint_config = read_and_sub_file(setup_path("refint.conf"), + { "LINK_ATTRS" : refint_attributes}) setup_file(setup_path("slapd.conf"), paths.slapdconf, {"DNSDOMAIN": names.dnsdomain, @@ -1273,7 +1273,8 @@ refint_attributes""" + refint_attributes "DOMAINDN": names.domaindn, "CONFIGDN": names.configdn, "SCHEMADN": names.schemadn, - "MEMBEROF_CONFIG": memberof_config}) + "MEMBEROF_CONFIG": memberof_config, + "REFINT_CONFIG": refint_config}) setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) -- cgit From fb3e663678be412df4668b05e76480908da2c080 Mon Sep 17 00:00:00 2001 From: Matthias Dieter Wallnöfer Date: Tue, 22 Jul 2008 11:06:47 +1000 Subject: Improve DNS and Group poicy configurations. - fixes bug #4813 (simplify DNS setup) - This reworks the named.conf to be a fully fledged include - This also moves the documentation into named.txt - improves bug #4900 (Group policy support in Samba) - by creating an empty GPT.INI - fixes bug #5582 (DNS: Enhanced zone file) - This is now closer to the zone file AD creates committed by Andrew Bartlett (This used to be commit 74d684f6b329d7dd573cdc55e16bb8e629474b02) --- source4/scripting/python/samba/provision.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 6eb47c8595..40b61a0ac4 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1043,6 +1043,7 @@ def provision(setup_dir, message, session_info, policy_path = os.path.join(paths.sysvol, names.dnsdomain, "Policies", "{" + policyguid + "}") os.makedirs(policy_path, 0755) + open(os.path.join(policy_path, "GPT.INI"), 'w').write("") os.makedirs(os.path.join(policy_path, "Machine"), 0755) os.makedirs(os.path.join(policy_path, "User"), 0755) if not os.path.isdir(paths.netlogon): @@ -1081,12 +1082,11 @@ def provision(setup_dir, message, session_info, hostip6=hostip6, hostname=names.hostname, dnspass=dnspass, realm=names.realm, domainguid=domainguid, hostguid=hostguid) - message("Please install the zone located in %s into your DNS server" % paths.dns) create_named_conf(paths.namedconf, setup_path, realm=names.realm, dnsdomain=names.dnsdomain, private_dir=paths.private_dir, keytab_name=paths.dns_keytab) - message("See %s for example configuration statements for secure GSS-TSIG updates" % paths.namedconf) + message("See %s for an example configuration include file for BIND" % paths.namedconf) create_krb5_conf(paths.krb5conf, setup_path, dnsdomain=names.dnsdomain, hostname=names.hostname, realm=names.realm) @@ -1394,6 +1394,7 @@ def create_named_conf(path, setup_path, realm, dnsdomain, "REALM_WC": "*." + ".".join(realm.split(".")[1:]), "DNS_KEYTAB": keytab_name, "DNS_KEYTAB_ABS": os.path.join(private_dir, keytab_name), + "PRIVATE_DIR": private_dir, }) def create_krb5_conf(path, setup_path, dnsdomain, hostname, realm): -- cgit From c9c296b6bbe178502e8aded8fa5e38a0f338ee18 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 22 Jul 2008 11:09:18 +1000 Subject: Install'named.txt' to private/ as documentation. This document is much more use when subbed with all the right things. Andrew Bartlett (This used to be commit 136a85599815670c807f212d7d4003ec53a13729) --- source4/scripting/python/samba/provision.py | 28 ++++++++++++++++++++++++++-- 1 file changed, 26 insertions(+), 2 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 40b61a0ac4..4b310381ef 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -244,6 +244,7 @@ def provision_paths_from_lp(lp, dnsdomain): paths.templates = os.path.join(paths.private_dir, "templates.ldb") paths.dns = os.path.join(paths.private_dir, dnsdomain + ".zone") paths.namedconf = os.path.join(paths.private_dir, "named.conf") + paths.namedtxt = os.path.join(paths.private_dir, "named.txt") paths.krb5conf = os.path.join(paths.private_dir, "krb5.conf") paths.winsdb = os.path.join(paths.private_dir, "wins.ldb") paths.s4_ldapi_path = os.path.join(paths.private_dir, "ldapi") @@ -1084,9 +1085,13 @@ def provision(setup_dir, message, session_info, domainguid=domainguid, hostguid=hostguid) create_named_conf(paths.namedconf, setup_path, realm=names.realm, + dnsdomain=names.dnsdomain, private_dir=paths.private_dir) + + create_named_txt(paths.namedtxt, setup_path, realm=names.realm, dnsdomain=names.dnsdomain, private_dir=paths.private_dir, keytab_name=paths.dns_keytab) message("See %s for an example configuration include file for BIND" % paths.namedconf) + message("and %s for further documentation required for secure DNS updates" % paths.namedtxt) create_krb5_conf(paths.krb5conf, setup_path, dnsdomain=names.dnsdomain, hostname=names.hostname, realm=names.realm) @@ -1376,7 +1381,7 @@ def create_zone_file(path, setup_path, dnsdomain, domaindn, def create_named_conf(path, setup_path, realm, dnsdomain, - private_dir, keytab_name): + private_dir): """Write out a file containing zone statements suitable for inclusion in a named.conf file (including GSS-TSIG configuration). @@ -1392,9 +1397,28 @@ def create_named_conf(path, setup_path, realm, dnsdomain, "DNSDOMAIN": dnsdomain, "REALM": realm, "REALM_WC": "*." + ".".join(realm.split(".")[1:]), + "PRIVATE_DIR": private_dir + }) + +def create_named_txt(path, setup_path, realm, dnsdomain, + private_dir, keytab_name): + """Write out a file containing zone statements suitable for inclusion in a + named.conf file (including GSS-TSIG configuration). + + :param path: Path of the new named.conf file. + :param setup_path: Setup path function. + :param realm: Realm name + :param dnsdomain: DNS Domain name + :param private_dir: Path to private directory + :param keytab_name: File name of DNS keytab file + """ + + setup_file(setup_path("named.txt"), path, { + "DNSDOMAIN": dnsdomain, + "REALM": realm, "DNS_KEYTAB": keytab_name, "DNS_KEYTAB_ABS": os.path.join(private_dir, keytab_name), - "PRIVATE_DIR": private_dir, + "PRIVATE_DIR": private_dir }) def create_krb5_conf(path, setup_path, dnsdomain, hostname, realm): -- cgit From 11798902dc51cd9eea3b7e8a0c94d0c0c08ed828 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 25 Jul 2008 08:45:16 +1000 Subject: Complain if we are told to use an ldap backend, without the type (This used to be commit e9c3c9ad8289ee48efa998ab6b486250dcd40b52) --- source4/scripting/python/samba/provision.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 6eb47c8595..67f8cf7cc2 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -503,6 +503,8 @@ def setup_samdb_partitions(samdb_path, setup_path, message, lp, session_info, backend_modules = ["normalise", "entryuuid", "paged_searches"] # OpenLDAP handles subtree renames, so we don't want to do any of these things tdb_modules_list = None + elif ldap_backend is not None: + raise "LDAP Backend specified, but LDAP Backend Type not specified" elif serverrole == "domain controller": backend_modules = ["repl_meta_data"] else: -- cgit From cff30c6da666abcb4ad8c587defa63883ce86c23 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 28 Jul 2008 08:04:15 +1000 Subject: Remove unused function and make sensitive directories private. (This used to be commit e23333d16397606d38e90684d2d916b5b967cde4) --- source4/scripting/python/samba/provision.py | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 0119f40c7f..068fe5ad9b 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -133,26 +133,6 @@ findnss_uid = lambda names: findnss(pwd.getpwnam, names)[2] findnss_gid = lambda names: findnss(grp.getgrnam, names)[2] -def open_ldb(session_info, credentials, lp, dbname): - """Open a LDB, thrashing it if it is corrupt. - - :param session_info: auth session information - :param credentials: credentials - :param lp: Loadparm context - :param dbname: Path of the database to open. - :return: a Ldb object - """ - assert session_info is not None - try: - return Ldb(dbname, session_info=session_info, credentials=credentials, - lp=lp) - except LdbError, e: - print e - os.unlink(dbname) - return Ldb(dbname, session_info=session_info, credentials=credentials, - lp=lp) - - def read_and_sub_file(file, subst_vars): """Read a file and sub in variables found in it @@ -1195,7 +1175,7 @@ def provision_backend(setup_dir=None, message=None, paths = provision_paths_from_lp(lp, names.dnsdomain) if not os.path.isdir(paths.ldapdir): - os.makedirs(paths.ldapdir) + os.makedirs(paths.ldapdir, 0700) schemadb_path = os.path.join(paths.ldapdir, "schema-tmp.ldb") try: os.unlink(schemadb_path) @@ -1290,7 +1270,7 @@ def provision_backend(setup_dir=None, message=None, setup_db_config(setup_path, os.path.join(paths.ldapdir, "db", "schema")) if not os.path.exists(os.path.join(paths.ldapdir, "db", "samba", "cn=samba")): - os.makedirs(os.path.join(paths.ldapdir, "db", "samba", "cn=samba")) + os.makedirs(os.path.join(paths.ldapdir, "db", "samba", "cn=samba"), 0700) setup_file(setup_path("cn=samba.ldif"), os.path.join(paths.ldapdir, "db", "samba", "cn=samba.ldif"), -- cgit From 45d60f5bd9be53ae4d4399664500709f1b2801a5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 28 Jul 2008 20:18:17 +1000 Subject: Always print the slapd startup command (This used to be commit b1d05e7d14c65133e8ab0ff9d41a26fa7e3d41d3) --- source4/scripting/python/samba/provision.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 068fe5ad9b..8437909da1 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1290,7 +1290,8 @@ def provision_backend(setup_dir=None, message=None, server_port_string = " -h ldap://0.0.0.0:%d" % ldap_backend_port else: server_port_string = "" - slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string + + slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema) -- cgit From 08795db6d6af69442dfbfa7d39532e898d4c0ea6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 28 Jul 2008 20:26:14 +1000 Subject: Make it even clearer what to do next in the LDAP backend setup (This used to be commit bace931ad674b5071d53bf9c99c383f1d8957e1b) --- source4/scripting/python/samba/provision.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 8437909da1..13329e8b10 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1232,6 +1232,8 @@ def provision_backend(setup_dir=None, message=None, slapdcommand="Initailise Fedora DS with: setup-ds.pl --file=%s" % paths.fedoradsinf + ldapuser = "--simple-bind-dn=" + names.ldapmanagerdn + elif ldap_backend_type == "openldap": attrs = ["linkID", "lDAPDisplayName"] res = schemadb.search(expression="(&(&(linkID=*)(!(linkID:1.2.840.113556.1.4.803:=1)))(objectclass=attributeSchema))", base=names.schemadn, scope=SCOPE_SUBTREE, attrs=attrs) @@ -1293,6 +1295,8 @@ def provision_backend(setup_dir=None, message=None, slapdcommand="Start slapd with: slapd -f " + paths.ldapdir + "/slapd.conf -h " + ldapi_uri + server_port_string + ldapuser = "--username=samba-admin" + schema_command = "bin/ad2oLschema --option=convert:target=" + ldap_backend_type + " -I " + setup_path(mapping) + " -H tdb://" + schemadb_path + " -O " + os.path.join(paths.ldapdir, backend_schema) @@ -1311,7 +1315,7 @@ def provision_backend(setup_dir=None, message=None, message("LDAP admin password: %s" % adminpass) message(slapdcommand) - + message("Run provision with: --ldap-backend=ldapi --ldap-backend-type=" + ldap_backend_type + " --password=" + adminpass + " " + ldapuser) def create_phpldapadmin_config(path, setup_path, ldapi_uri): """Create a PHP LDAP admin configuration file. -- cgit From e80115deb9f57d827f915b57b52961f1e2df682e Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 28 Jul 2008 20:51:02 +1000 Subject: We don't use EXTENSIBLEOBJECT any more. (This used to be commit 4b137085c8b89773d4639372bbffd516a41dfc8f) --- source4/scripting/python/samba/provision.py | 3 --- 1 file changed, 3 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 13329e8b10..441d662b23 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -779,7 +779,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, setup_add_ldif(samdb, setup_path("provision_configuration_basedn.ldif"), { "CONFIGDN": names.configdn, "ACI": aci, - "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb", }) message("Modifying configuration container") setup_modify_ldif(samdb, setup_path("provision_configuration_basedn_modify.ldif"), { @@ -791,7 +790,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, setup_add_ldif(samdb, setup_path("provision_schema_basedn.ldif"), { "SCHEMADN": names.schemadn, "ACI": aci, - "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" }) message("Modifying schema container") @@ -1189,7 +1187,6 @@ def provision_backend(setup_dir=None, message=None, setup_add_ldif(schemadb, setup_path("provision_schema_basedn.ldif"), {"SCHEMADN": names.schemadn, "ACI": "#", - "EXTENSIBLEOBJECT": "# no objectClass: extensibleObject for local ldb" }) setup_modify_ldif(schemadb, setup_path("provision_schema_basedn_modify.ldif"), \ -- cgit From 3573420d7d108d796e0b424c131061dc74c23033 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 1 Aug 2008 20:17:29 +0200 Subject: Fix some forgotten substitute variables in provision, add check to prevent this sort of regression in the future. (This used to be commit a461118f3b668779f907c4d77cebe1e76fa4e39f) --- source4/scripting/python/samba/provision.py | 2 ++ 1 file changed, 2 insertions(+) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 0119f40c7f..33aeff2008 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1453,6 +1453,7 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): schema_data = open(setup_path("schema.ldif"), 'r').read() schema_data += open(setup_path("schema_samba4.ldif"), 'r').read() schema_data = substitute_var(schema_data, {"SCHEMADN": schemadn}) + check_all_substituted(schema_data) prefixmap = open(setup_path("prefixMap.txt"), 'r').read() prefixmap = b64encode(prefixmap) @@ -1464,5 +1465,6 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): "DEFAULTSITE":sitename, "PREFIXMAP_B64":prefixmap }) + check_all_substituted(head_data) samdb.attach_schema_from_ldif(head_data, schema_data) -- cgit From 3b4ff07ded89703b2a58ae2c9ca6f0ea82bb5a52 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 1 Aug 2008 20:47:03 +0200 Subject: Actually fix missing substitution variables. (This used to be commit 783412ecb27d646b171993da0ac2f11a821901d3) --- source4/scripting/python/samba/provision.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 6b1fd33b9f..6dd9f3b8bd 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -739,7 +739,8 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, samdb.set_invocation_id(invocationid) load_schema(setup_path, samdb, names.schemadn, names.netbiosname, - names.configdn, names.sitename) + names.configdn, names.sitename, names.serverdn, + names.hostname) samdb.transaction_start() @@ -1423,7 +1424,8 @@ def create_krb5_conf(path, setup_path, dnsdomain, hostname, realm): }) -def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): +def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename, + serverdn, servername): """Load schema for the SamDB. :param samdb: Load a schema into a SamDB. @@ -1431,6 +1433,8 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): :param schemadn: DN of the schema :param netbiosname: NetBIOS name of the host. :param configdn: DN of the configuration + :param serverdn: DN of the server + :param servername: Host name of the server """ schema_data = open(setup_path("schema.ldif"), 'r').read() schema_data += open(setup_path("schema_samba4.ldif"), 'r').read() @@ -1444,8 +1448,10 @@ def load_schema(setup_path, samdb, schemadn, netbiosname, configdn, sitename): "SCHEMADN": schemadn, "NETBIOSNAME": netbiosname, "CONFIGDN": configdn, - "DEFAULTSITE":sitename, - "PREFIXMAP_B64":prefixmap + "DEFAULTSITE": sitename, + "PREFIXMAP_B64": prefixmap, + "SERVERDN": serverdn, + "SERVERNAME": servername, }) check_all_substituted(head_data) samdb.attach_schema_from_ldif(head_data, schema_data) -- cgit From 1c94f3e95da5b520ee631670a30f96e487f12ac8 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Fri, 1 Aug 2008 21:00:09 +0200 Subject: Use new style python classes. (This used to be commit 2a39aae0cef310a79427feb1b85f6794ea36849a) --- source4/scripting/python/samba/provision.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 6dd9f3b8bd..4f7fbfc6e6 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -53,7 +53,7 @@ class InvalidNetbiosName(Exception): super(InvalidNetbiosName, self).__init__("The name '%r' is not a valid NetBIOS name" % name) -class ProvisionPaths: +class ProvisionPaths(object): def __init__(self): self.shareconf = None self.hklm = None @@ -77,7 +77,8 @@ class ProvisionPaths: self.fedoradsinf = None self.fedoradspartitions = None -class ProvisionNames: + +class ProvisionNames(object): def __init__(self): self.rootdn = None self.domaindn = None @@ -92,7 +93,8 @@ class ProvisionNames: self.sitename = None self.smbconf = None -class ProvisionResult: + +class ProvisionResult(object): def __init__(self): self.paths = None self.domaindn = None -- cgit From 47d80366bef5e62b6727a574b2300cc94a2e18f7 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 19 Aug 2008 11:43:41 +1000 Subject: Fix templates.ldb reprovision handling. This sets the attributes in a seperate transaction, and allows a forced delete of the whole file. Andrew Bartlett (This used to be commit 423db2468ba3dac89cebc59c8498c0b08c5f3d7b) --- source4/scripting/python/samba/provision.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 4f7fbfc6e6..836509a620 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -617,7 +617,17 @@ def setup_templatesdb(path, setup_path, session_info, credentials, lp): """ templates_ldb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) - templates_ldb.erase() + # Wipes the database + try: + templates_ldb.erase() + except: + os.unlink(path) + + templates_ldb.load_ldif_file_add(setup_path("provision_templates_init.ldif")) + + templates_ldb = SamDB(path, session_info=session_info, + credentials=credentials, lp=lp) + templates_ldb.load_ldif_file_add(setup_path("provision_templates.ldif")) -- cgit From 805dd85291fa55695ee7ae2b8f6d3c168d9186e8 Mon Sep 17 00:00:00 2001 From: Oliver Liebel Date: Tue, 19 Aug 2008 12:03:04 +1000 Subject: Generate Multi-Master Replication configuration for OpenLDAP This patches provision-backend and the related scripts to generate the correct configuration blobs for N-way multi-master replication using OpenLDAP. Signed-off-by: Andrew Bartlett (This used to be commit 6ed0b3f2475022288f636605492ca27fde97cd52) --- source4/scripting/python/samba/provision.py | 86 ++++++++++++++++++++++++++--- 1 file changed, 79 insertions(+), 7 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 4f7fbfc6e6..8abcc2f2e3 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -76,7 +76,9 @@ class ProvisionPaths(object): self.memberofconf = None self.fedoradsinf = None self.fedoradspartitions = None - + self.olmmron = None + self.olmmrserveridsconf = None + self.olmmrsyncreplconf = None class ProvisionNames(object): def __init__(self): @@ -242,8 +244,12 @@ def provision_paths_from_lp(lp, dnsdomain): "memberof.conf") paths.fedoradsinf = os.path.join(paths.ldapdir, "fedorads.inf") - paths.fedoradspartitions = os.path.join(paths.ldapdir, - "fedorads-partitions.ldif") + paths.olmmrserveridsconf = os.path.join(paths.ldapdir, + "mmr_serverids.conf") + paths.olmmrsyncreplconf = os.path.join(paths.ldapdir, + "mmr_syncrepl.conf") + paths.olmmron = os.path.join(paths.ldapdir, + "mmr_on.conf") paths.hklm = "hklm.ldb" paths.hkcr = "hkcr.ldb" paths.hkcu = "hkcu.ldb" @@ -331,7 +337,7 @@ def guess_names(lp=None, hostname=None, domain=None, dnsdomain=None, serverrole= names.hostname = hostname names.sitename = sitename names.serverdn = "CN=%s,CN=Servers,CN=%s,CN=Sites,%s" % (netbiosname, sitename, configdn) - + return names @@ -1141,7 +1147,11 @@ def provision_backend(setup_dir=None, message=None, smbconf=None, targetdir=None, realm=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, domain=None, hostname=None, adminpass=None, root=None, serverrole=None, - ldap_backend_type=None, ldap_backend_port=None): + ldap_backend_type=None, ldap_backend_port=None, + ol_mmr_urls=None, mmr_serverids_config=None, mmr_on_config=None, + mmr_syncrepl_schema_config=None, + mmr_syncrepl_config_config=None, + mmr_syncrepl_user_config=None ): def setup_path(file): return os.path.join(setup_dir, file) @@ -1255,7 +1265,64 @@ def provision_backend(setup_dir=None, message=None, refint_config = read_and_sub_file(setup_path("refint.conf"), { "LINK_ATTRS" : refint_attributes}) - + +######################################################## +### generate serverids and ldap-urls for mmr hosts ### +######################################################## + + mmr_on_config = " " + mmr_serverids_config = " " + + if ol_mmr_urls is not None: + mmr_hosts=ol_mmr_urls + mmr_hosts=filter(None,mmr_hosts.split(' ')) + + mmr_serverids_config = "# Generated from template mmr_serverids.conf\n" + z=0 + for i in mmr_hosts: + z=z+1 + mmr_serverids_config += read_and_sub_file(setup_path("mmr_serverids.conf"), + { "SERVERID" : str(z), + "LDAPSERVER" : i }) + mmr_on_config = "MirrorMode On" + +######################################################## +### generate syncrepl-blocks for mmr hosts ### +######################################################## + + mmr_syncrepl_schema_config = " " + mmr_syncrepl_config_config = " " + mmr_syncrepl_user_config = " " + + if ol_mmr_urls is not None: + mmr_hosts=ol_mmr_urls + mmr_hosts=filter(None,mmr_hosts.split(' ')) + mmr_syncrepl_schema_config = "# Generated from template mmr_syncrepl.conf\n" + mmr_syncrepl_config_config = "# Generated from template mmr_syncrepl.conf\n" + mmr_syncrepl_user_config = "# Generated from template mmr_syncrepl.conf\n" + z=0 + for i in mmr_hosts: + z=z+1 + mmr_syncrepl_schema_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(z), + "MMRDN": names.schemadn, + "LDAPSERVER" : i }) + + for i in mmr_hosts: + z=z+1 + mmr_syncrepl_config_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(z), + "MMRDN": names.configdn, + "LDAPSERVER" : i }) + + for i in mmr_hosts: + z=z+1 + mmr_syncrepl_user_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), + { "RID" : str(z), + "MMRDN": names.domaindn, + "LDAPSERVER" : i }) + + setup_file(setup_path("slapd.conf"), paths.slapdconf, {"DNSDOMAIN": names.dnsdomain, "LDAPDIR": paths.ldapdir, @@ -1263,8 +1330,13 @@ def provision_backend(setup_dir=None, message=None, "CONFIGDN": names.configdn, "SCHEMADN": names.schemadn, "MEMBEROF_CONFIG": memberof_config, + "MIRRORMODE": mmr_on_config, + "MMR_SERVERIDS_CONFIG": mmr_serverids_config, + "MMR_SYNCREPL_SCHEMA_CONFIG": mmr_syncrepl_schema_config, + "MMR_SYNCREPL_CONFIG_CONFIG": mmr_syncrepl_config_config, + "MMR_SYNCREPL_USER_CONFIG": mmr_syncrepl_user_config, "REFINT_CONFIG": refint_config}) - setup_file(setup_path("modules.conf"), paths.modulesconf, + setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) setup_db_config(setup_path, os.path.join(paths.ldapdir, "db", "user")) -- cgit From 7ef21658fbb519859aa7d23a614e1fdbcae95693 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 19 Aug 2008 14:10:14 +1000 Subject: Fix up new OpenLDAP MMR code. This changes the MMR password from hard-coded value of 'linux', adds tests and fixes the Fedora DS backend. Currently the MMR password matches the admin password, but we can change this to be another random value if required. Also require the port to be specified on the command line, so we don't hard-code a port of 9000. Andrew Bartlett (This used to be commit 08257c6d6ce809fcd53f9b2b4d558fef616b74ce) --- source4/scripting/python/samba/provision.py | 67 +++++++++++------------------ 1 file changed, 26 insertions(+), 41 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 8abcc2f2e3..f48a49dcfa 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -243,13 +243,13 @@ def provision_paths_from_lp(lp, dnsdomain): paths.memberofconf = os.path.join(paths.ldapdir, "memberof.conf") paths.fedoradsinf = os.path.join(paths.ldapdir, - "fedorads.inf") + "fedorads.inf") + paths.fedoradspartitions = os.path.join(paths.ldapdir, + "fedorads-partitions.ldif") paths.olmmrserveridsconf = os.path.join(paths.ldapdir, - "mmr_serverids.conf") + "mmr_serverids.conf") paths.olmmrsyncreplconf = os.path.join(paths.ldapdir, - "mmr_syncrepl.conf") - paths.olmmron = os.path.join(paths.ldapdir, - "mmr_on.conf") + "mmr_syncrepl.conf") paths.hklm = "hklm.ldb" paths.hkcr = "hkcr.ldb" paths.hkcu = "hkcu.ldb" @@ -1148,10 +1148,7 @@ def provision_backend(setup_dir=None, message=None, rootdn=None, domaindn=None, schemadn=None, configdn=None, domain=None, hostname=None, adminpass=None, root=None, serverrole=None, ldap_backend_type=None, ldap_backend_port=None, - ol_mmr_urls=None, mmr_serverids_config=None, mmr_on_config=None, - mmr_syncrepl_schema_config=None, - mmr_syncrepl_config_config=None, - mmr_syncrepl_user_config=None ): + ol_mmr_urls=None): def setup_path(file): return os.path.join(setup_dir, file) @@ -1266,61 +1263,48 @@ def provision_backend(setup_dir=None, message=None, refint_config = read_and_sub_file(setup_path("refint.conf"), { "LINK_ATTRS" : refint_attributes}) -######################################################## -### generate serverids and ldap-urls for mmr hosts ### -######################################################## - - mmr_on_config = " " - mmr_serverids_config = " " - +# generate serverids, ldap-urls and syncrepl-blocks for mmr hosts + mmr_on_config = "" + mmr_serverids_config = "" + mmr_syncrepl_schema_config = "" + mmr_syncrepl_config_config = "" + mmr_syncrepl_user_config = "" + if ol_mmr_urls is not None: - mmr_hosts=ol_mmr_urls - mmr_hosts=filter(None,mmr_hosts.split(' ')) + mmr_hosts=filter(None,ol_mmr_urls.split(' ')) + if (len(mmr_hosts) == 1): + mmr_hosts=filter(None,ol_mmr_urls.split(',')) + + + mmr_on_config = "MirrorMode On" - mmr_serverids_config = "# Generated from template mmr_serverids.conf\n" z=0 for i in mmr_hosts: z=z+1 mmr_serverids_config += read_and_sub_file(setup_path("mmr_serverids.conf"), { "SERVERID" : str(z), "LDAPSERVER" : i }) - mmr_on_config = "MirrorMode On" - -######################################################## -### generate syncrepl-blocks for mmr hosts ### -######################################################## - mmr_syncrepl_schema_config = " " - mmr_syncrepl_config_config = " " - mmr_syncrepl_user_config = " " - - if ol_mmr_urls is not None: - mmr_hosts=ol_mmr_urls - mmr_hosts=filter(None,mmr_hosts.split(' ')) - mmr_syncrepl_schema_config = "# Generated from template mmr_syncrepl.conf\n" - mmr_syncrepl_config_config = "# Generated from template mmr_syncrepl.conf\n" - mmr_syncrepl_user_config = "# Generated from template mmr_syncrepl.conf\n" - z=0 - for i in mmr_hosts: z=z+1 mmr_syncrepl_schema_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), { "RID" : str(z), "MMRDN": names.schemadn, - "LDAPSERVER" : i }) + "LDAPSERVER" : i, + "MMR_PASSWORD": adminpass}) - for i in mmr_hosts: z=z+1 mmr_syncrepl_config_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), { "RID" : str(z), "MMRDN": names.configdn, - "LDAPSERVER" : i }) + "LDAPSERVER" : i, + "MMR_PASSWORD": adminpass}) - for i in mmr_hosts: z=z+1 mmr_syncrepl_user_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), { "RID" : str(z), "MMRDN": names.domaindn, - "LDAPSERVER" : i }) + "LDAPSERVER" : i, + "MMR_PASSWORD": adminpass }) setup_file(setup_path("slapd.conf"), paths.slapdconf, @@ -1335,6 +1319,7 @@ def provision_backend(setup_dir=None, message=None, "MMR_SYNCREPL_SCHEMA_CONFIG": mmr_syncrepl_schema_config, "MMR_SYNCREPL_CONFIG_CONFIG": mmr_syncrepl_config_config, "MMR_SYNCREPL_USER_CONFIG": mmr_syncrepl_user_config, + "MMR_PASSWORD": adminpass, "REFINT_CONFIG": refint_config}) setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) -- cgit From 41493cbe680e0b8dff3b84937b3005c72c39dec6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 20 Aug 2008 12:21:36 +1000 Subject: Update OpenLDAP MMR configuration per comments by Oliver Liebel This changes the RIDs to be , to ease later debugging. The need to specify the port on the MMR URLs is now included in the help. Andrew Bartlett (This used to be commit a5cbe8c09c6f14f95ff9ba9b8782e2100fc55695) --- source4/scripting/python/samba/provision.py | 37 ++++++++++++++--------------- 1 file changed, 18 insertions(+), 19 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 0855efe3bb..d14ce58f04 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1281,39 +1281,38 @@ def provision_backend(setup_dir=None, message=None, mmr_syncrepl_user_config = "" if ol_mmr_urls is not None: - mmr_hosts=filter(None,ol_mmr_urls.split(' ')) - if (len(mmr_hosts) == 1): - mmr_hosts=filter(None,ol_mmr_urls.split(',')) + url_list=filter(None,ol_mmr_urls.split(' ')) + if (len(url_list) == 1): + url_list=filter(None,ol_mmr_urls.split(',')) mmr_on_config = "MirrorMode On" - - z=0 - for i in mmr_hosts: - z=z+1 + serverid=0 + for url in url_list: + serverid=serverid+1 mmr_serverids_config += read_and_sub_file(setup_path("mmr_serverids.conf"), - { "SERVERID" : str(z), - "LDAPSERVER" : i }) - - z=z+1 + { "SERVERID" : str(serverid), + "LDAPSERVER" : url }) + rid=serverid*10 + rid=rid+1 mmr_syncrepl_schema_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(z), + { "RID" : str(rid), "MMRDN": names.schemadn, - "LDAPSERVER" : i, + "LDAPSERVER" : url, "MMR_PASSWORD": adminpass}) - z=z+1 + rid=rid+1 mmr_syncrepl_config_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(z), + { "RID" : str(rid), "MMRDN": names.configdn, - "LDAPSERVER" : i, + "LDAPSERVER" : url, "MMR_PASSWORD": adminpass}) - z=z+1 + rid=rid+1 mmr_syncrepl_user_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), - { "RID" : str(z), + { "RID" : str(rid), "MMRDN": names.domaindn, - "LDAPSERVER" : i, + "LDAPSERVER" : url, "MMR_PASSWORD": adminpass }) -- cgit From 8237c0ba83e2b47bb7879ba68d3a50da887397b6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 21 Aug 2008 12:59:16 +1000 Subject: The index handling is now configured from the schema load, not by a template. Andrew Bartlett (This used to be commit b36c6a21ad12fdc1b53efdc3f29cde7614b4fa9e) --- source4/scripting/python/samba/provision.py | 9 --------- 1 file changed, 9 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index d14ce58f04..9c2a208460 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -745,12 +745,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, samdb = SamDB(path, session_info=session_info, credentials=credentials, lp=lp) - if fill == FILL_DRS: - # We want to finish here, but setup the index before we do so - message("Setting up sam.ldb index") - samdb.load_ldif_file_add(setup_path("provision_index.ldif")) - return samdb - message("Pre-loading the Samba 4 and AD schema") samdb.set_domain_sid(domainsid) if serverrole == "domain controller": @@ -886,9 +880,6 @@ def setup_samdb(path, setup_path, session_info, credentials, lp, domainsid=domainsid, policyguid=policyguid, setup_path=setup_path) - #We want to setup the index last, as adds are faster unindexed - message("Setting up sam.ldb index") - samdb.load_ldif_file_add(setup_path("provision_index.ldif")) except: samdb.transaction_cancel() raise -- cgit From b76f383eefe961e8a2f42ac782031e3e09ff7192 Mon Sep 17 00:00:00 2001 From: Oliver Liebel Date: Mon, 8 Sep 2008 14:39:54 +1000 Subject: Use DIGEST-MD5 authentication for OpenLDAP replication This avoids passing rootdn passwords or replicated data in cleartext across the network. Signed-of-by: Andrew Bartlett (This used to be commit 67373c143a1d8a9f310fd116dbf81c1dd123b75f) --- source4/scripting/python/samba/provision.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 9c2a208460..f37d09d5e0 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1266,6 +1266,7 @@ def provision_backend(setup_dir=None, message=None, # generate serverids, ldap-urls and syncrepl-blocks for mmr hosts mmr_on_config = "" + mmr_replicator_acl = "" mmr_serverids_config = "" mmr_syncrepl_schema_config = "" mmr_syncrepl_config_config = "" @@ -1278,6 +1279,7 @@ def provision_backend(setup_dir=None, message=None, mmr_on_config = "MirrorMode On" + mmr_replicator_acl = " by dn=cn=replicator,cn=samba read" serverid=0 for url in url_list: serverid=serverid+1 @@ -1315,6 +1317,7 @@ def provision_backend(setup_dir=None, message=None, "SCHEMADN": names.schemadn, "MEMBEROF_CONFIG": memberof_config, "MIRRORMODE": mmr_on_config, + "REPLICATOR_ACL": mmr_replicator_acl, "MMR_SERVERIDS_CONFIG": mmr_serverids_config, "MMR_SYNCREPL_SCHEMA_CONFIG": mmr_syncrepl_schema_config, "MMR_SYNCREPL_CONFIG_CONFIG": mmr_syncrepl_config_config, @@ -1340,6 +1343,15 @@ def provision_backend(setup_dir=None, message=None, {"LDAPADMINPASS_B64": b64encode(adminpass), "UUID": str(uuid.uuid4()), "LDAPTIME": timestring(int(time.time()))} ) + + if ol_mmr_urls is not None: + setup_file(setup_path("cn=replicator.ldif"), + os.path.join(paths.ldapdir, "db", "samba", "cn=samba", "cn=replicator.ldif"), + {"LDAPADMINPASS_B64": b64encode(adminpass), + "UUID": str(uuid.uuid4()), + "LDAPTIME": timestring(int(time.time()))} ) + + mapping = "schema-map-openldap-2.3" backend_schema = "backend-schema.schema" -- cgit From ef9169bfa6fcaa682ff5baf729301dd63f6bb029 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 8 Sep 2008 15:09:06 +1000 Subject: Make it clear that the MMR password can differ from the admin passsword In the future, we might simply randomly generate this, or allow the admin to specify it seperate to the admin password. However, both are highly sensitive, as they imply read access to the krbtgt. Andrew Bartlett (This used to be commit 57d19ad002c523fb9a09694e6710ab7f588d44ec) --- source4/scripting/python/samba/provision.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'source4/scripting/python/samba/provision.py') diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index f37d09d5e0..68f61532ad 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -1273,7 +1273,10 @@ def provision_backend(setup_dir=None, message=None, mmr_syncrepl_user_config = "" if ol_mmr_urls is not None: - url_list=filter(None,ol_mmr_urls.split(' ')) + # For now, make these equal + mmr_pass = adminpass + + url_list=filter(None,ol_mmr_urls.split(' ')) if (len(url_list) == 1): url_list=filter(None,ol_mmr_urls.split(',')) @@ -1292,21 +1295,21 @@ def provision_backend(setup_dir=None, message=None, { "RID" : str(rid), "MMRDN": names.schemadn, "LDAPSERVER" : url, - "MMR_PASSWORD": adminpass}) + "MMR_PASSWORD": mmr_pass}) rid=rid+1 mmr_syncrepl_config_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), { "RID" : str(rid), "MMRDN": names.configdn, "LDAPSERVER" : url, - "MMR_PASSWORD": adminpass}) + "MMR_PASSWORD": mmr_pass}) rid=rid+1 mmr_syncrepl_user_config += read_and_sub_file(setup_path("mmr_syncrepl.conf"), { "RID" : str(rid), "MMRDN": names.domaindn, "LDAPSERVER" : url, - "MMR_PASSWORD": adminpass }) + "MMR_PASSWORD": mmr_pass }) setup_file(setup_path("slapd.conf"), paths.slapdconf, @@ -1322,7 +1325,6 @@ def provision_backend(setup_dir=None, message=None, "MMR_SYNCREPL_SCHEMA_CONFIG": mmr_syncrepl_schema_config, "MMR_SYNCREPL_CONFIG_CONFIG": mmr_syncrepl_config_config, "MMR_SYNCREPL_USER_CONFIG": mmr_syncrepl_user_config, - "MMR_PASSWORD": adminpass, "REFINT_CONFIG": refint_config}) setup_file(setup_path("modules.conf"), paths.modulesconf, {"REALM": names.realm}) @@ -1347,7 +1349,7 @@ def provision_backend(setup_dir=None, message=None, if ol_mmr_urls is not None: setup_file(setup_path("cn=replicator.ldif"), os.path.join(paths.ldapdir, "db", "samba", "cn=samba", "cn=replicator.ldif"), - {"LDAPADMINPASS_B64": b64encode(adminpass), + {"MMR_PASSWORD_B64": b64encode(mmr_pass), "UUID": str(uuid.uuid4()), "LDAPTIME": timestring(int(time.time()))} ) -- cgit