📄 provision.py
字号:
## Unix SMB/CIFS implementation.# backend code for provisioning a Samba4 server# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008# Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008## Based on the original in EJS:# Copyright (C) Andrew Tridgell <tridge@samba.org> 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 <http://www.gnu.org/licenses/>.#"""Functions for setting up a Samba configuration."""from base64 import b64encodeimport osimport pwdimport grpimport timeimport uuid, miscimport socketimport paramimport registryimport sambafrom auth import system_sessionfrom samba import Ldb, substitute_var, valid_netbios_name, check_all_substitutedfrom samba.samdb import SamDBfrom samba.idmap import IDmapDBimport securityimport urllibfrom ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE, LdbError, \ LDB_ERR_NO_SUCH_OBJECT, timestring, CHANGETYPE_MODIFY, CHANGETYPE_NONE__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)class ProvisionPaths: def __init__(self): 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.idmapdb = None self.secrets = None self.keytab = None self.dns_keytab = None 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 self.smbconf = None class ProvisionResult: def __init__(self): self.paths = None self.domaindn = None self.lp = None self.samdb = Nonedef check_install(lp, session_info, credentials): """Check whether the current install seems ok. :param lp: Loadparm context :param session_info: Session information :param credentials: Credentials """ if lp.get("realm") == "": 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: raise "No administrator account found"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 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. :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 setup_add_ldif(ldb, ldif_path, subst_vars=None): """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() if subst_vars is not None: data = substitute_var(data, subst_vars) check_all_substituted(data) ldb.add_ldif(data)def setup_modify_ldif(ldb, ldif_path, substvars=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. """ data = open(ldif_path, 'r').read() if substvars is not None: data = substitute_var(data, substvars) check_all_substituted(data) ldb.modify_ldif(data)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: setup_add_ldif(ldb, ldif_path, subst_vars) except: ldb.transaction_cancel() raise ldb.transaction_commit()def setup_file(template, fname, substvars): """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): os.unlink(f) data = open(template, 'r').read() if substvars: data = substitute_var(data, substvars) check_all_substituted(data) open(f, 'w').write(data)def provision_paths_from_lp(lp, dnsdomain): """Set the default paths for provisioning. :param lp: Loadparm context. :param dnsdomain: DNS Domain name """ paths = ProvisionPaths() paths.private_dir = lp.get("private dir") paths.keytab = "secrets.keytab" paths.dns_keytab = "dns.keytab" 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.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, "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" paths.hku = "hku.ldb" paths.hkpd = "hkpd.ldb" paths.hkpt = "hkpt.ldb" paths.sysvol = lp.get("path", "sysvol") paths.netlogon = lp.get("path", "netlogon") paths.smbconf = lp.configfile() return pathsdef 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() 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"), lp.configfile(), 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 Exception("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 names.serverdn = "CN=%s,CN=Servers,CN=%s,CN=Sites,%s" % (netbiosname, sitename, configdn) return names
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -