diff options
Diffstat (limited to 'source4/scripting/python')
| -rw-r--r-- | source4/scripting/python/samba/netcmd/domainlevel.py | 2 | ||||
| -rw-r--r-- | source4/scripting/python/samba/netcmd/dsacl.py | 21 | ||||
| -rw-r--r-- | source4/scripting/python/samba/provision.py | 89 | ||||
| -rw-r--r-- | source4/scripting/python/samba/provisionbackend.py | 190 | ||||
| -rw-r--r-- | source4/scripting/python/samba/provisionexceptions.py | 38 | ||||
| -rwxr-xr-x | source4/scripting/python/samba/upgradehelpers.py | 48 | 
6 files changed, 178 insertions, 210 deletions
diff --git a/source4/scripting/python/samba/netcmd/domainlevel.py b/source4/scripting/python/samba/netcmd/domainlevel.py index c97ed7bad6..1874191e1f 100644 --- a/source4/scripting/python/samba/netcmd/domainlevel.py +++ b/source4/scripting/python/samba/netcmd/domainlevel.py @@ -114,7 +114,7 @@ class cmd_domainlevel(Command):              raise CommandError("Could not retrieve the actual domain, forest level and/or lowest DC function level!")          if subcommand == "show": -            self.message("Domain and forest function level for domain '" + domain_dn + "'") +            self.message("Domain and forest function level for domain '%s'" % domain_dn)              if level_forest < DS_DOMAIN_FUNCTION_2003:                  self.message("\nATTENTION: You run SAMBA 4 on a forest function level lower than Windows 2003 (Native). This isn't supported! Please raise!")              if level_domain < DS_DOMAIN_FUNCTION_2003: diff --git a/source4/scripting/python/samba/netcmd/dsacl.py b/source4/scripting/python/samba/netcmd/dsacl.py index 58fb9c611a..17982b8119 100644 --- a/source4/scripting/python/samba/netcmd/dsacl.py +++ b/source4/scripting/python/samba/netcmd/dsacl.py @@ -57,7 +57,8 @@ class cmd_ds_acl_set(Command):          }      takes_options = [ -        Option("--host", help="LDB URL for database or target server", type=str), +        Option("--host", help="LDB URL for database or target server", +            type=str),          Option("--car", type="choice", choices=["change-rid",                                                  "change-pdc",                                                  "change-infrastructure", @@ -74,12 +75,15 @@ class cmd_ds_acl_set(Command):                 help=car_help),          Option("--action", type="choice", choices=["allow", "deny"],                  help="""Deny or allow access"""), -        Option("--objectdn", help="DN of the object whose SD to modify", type="string"), -        Option("--trusteedn", help="DN of the entity that gets access", type="string"), +        Option("--objectdn", help="DN of the object whose SD to modify", +            type="string"), +        Option("--trusteedn", help="DN of the entity that gets access", +            type="string"),          ]      def find_trustee_sid(self, samdb, trusteedn): -        res = samdb.search(base=trusteedn, expression="(objectClass=*)", scope=SCOPE_BASE) +        res = samdb.search(base=trusteedn, expression="(objectClass=*)", +            scope=SCOPE_BASE)          assert(len(res) == 1)          return ndr_unpack( security.dom_sid,res[0]["objectSid"][0]) @@ -93,18 +97,20 @@ class cmd_ds_acl_set(Command):          samdb.modify(m)      def read_descriptor(self, samdb, object_dn): -        res = samdb.search(base=object_dn, scope=SCOPE_BASE, attrs=["nTSecurityDescriptor"]) +        res = samdb.search(base=object_dn, scope=SCOPE_BASE, +                attrs=["nTSecurityDescriptor"])          # we should theoretically always have an SD          assert(len(res) == 1)          desc = res[0]["nTSecurityDescriptor"][0]          return ndr_unpack(security.descriptor, desc)      def get_domain_sid(self, samdb): -        res = samdb.search(base=SamDB.domain_dn(samdb), expression="(objectClass=*)", scope=SCOPE_BASE) +        res = samdb.search(base=SamDB.domain_dn(samdb), +                expression="(objectClass=*)", scope=SCOPE_BASE)          return ndr_unpack( security.dom_sid,res[0]["objectSid"][0]) -    #add new ace explicitly      def add_ace(self, samdb, object_dn, new_ace): +        """Add new ace explicitly."""          desc = self.read_descriptor(samdb, object_dn)          desc_sddl = desc.as_sddl(self.get_domain_sid(samdb))          #TODO add bindings for descriptor manipulation and get rid of this @@ -164,6 +170,7 @@ class cmd_ds_acl_set(Command):          self.add_ace(samdb, objectdn, new_ace)          self.print_new_acl(samdb, objectdn) +  class cmd_ds_acl(SuperCommand):      """DS ACLs manipulation""" diff --git a/source4/scripting/python/samba/provision.py b/source4/scripting/python/samba/provision.py index 4bef0ed7d4..eb89ee9f3a 100644 --- a/source4/scripting/python/samba/provision.py +++ b/source4/scripting/python/samba/provision.py @@ -2,7 +2,7 @@  # Unix SMB/CIFS implementation.  # backend code for provisioning a Samba4 server -# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2008 +# Copyright (C) Jelmer Vernooij <jelmer@samba.org> 2007-2010  # Copyright (C) Andrew Bartlett <abartlet@samba.org> 2008-2009  # Copyright (C) Oliver Liebel <oliver@itc.li> 2008-2009  # @@ -53,7 +53,6 @@ from samba.schema import Schema  from samba.samdb import SamDB  from ms_display_specifiers import read_ms_ldif  from samba.provisionbackend import LDBBackend, ExistingBackend, FDSBackend, OpenLDAPBackend -from provisionexceptions import ProvisioningError, InvalidNetbiosName  __docformat__ = "restructuredText" @@ -150,9 +149,8 @@ def get_domain_descriptor(domain_sid):  DEFAULTSITE = "Default-First-Site-Name" -# Exception classes -  class ProvisionPaths(object): +      def __init__(self):          self.shareconf = None          self.hklm = None @@ -172,6 +170,7 @@ class ProvisionPaths(object):  class ProvisionNames(object): +      def __init__(self):          self.rootdn = None          self.domaindn = None @@ -188,12 +187,14 @@ class ProvisionNames(object):  class ProvisionResult(object): +      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. @@ -203,9 +204,9 @@ def check_install(lp, session_info, credentials):      """      if lp.get("realm") == "":          raise Exception("Realm empty") -    ldb = Ldb(lp.get("sam database"), session_info=session_info,  +    samdb = Ldb(lp.get("sam database"), session_info=session_info,               credentials=credentials, lp=lp) -    if len(ldb.search("(cn=Administrator)")) != 1: +    if len(samdb.search("(cn=Administrator)")) != 1:          raise ProvisioningError("No administrator account found") @@ -825,6 +826,7 @@ def create_gpo_struct(policy_path):      os.makedirs(os.path.join(policy_path, "MACHINE"), 0755)      os.makedirs(os.path.join(policy_path, "USER"), 0755) +  def setup_gpo(sysvolpath, dnsdomain, policyguid, policyguid_dc):      policy_path = getpolicypath(sysvolpath,dnsdomain,policyguid)      create_gpo_struct(policy_path) @@ -832,6 +834,7 @@ def setup_gpo(sysvolpath, dnsdomain, policyguid, policyguid_dc):      policy_path = getpolicypath(sysvolpath,dnsdomain,policyguid_dc)      create_gpo_struct(policy_path) +  def setup_samdb(path, setup_path, session_info, provision_backend, lp,                   names, message,                   domainsid, domainguid, policyguid, policyguid_dc, @@ -851,7 +854,8 @@ def setup_samdb(path, setup_path, session_info, provision_backend, lp,      if dom_for_fun_level is None:          dom_for_fun_level = DS_DOMAIN_FUNCTION_2003      if dom_for_fun_level < DS_DOMAIN_FUNCTION_2003: -        message("You want to run SAMBA 4 on a domain and forest function level lower than Windows 2003 (Native). This is not recommended") +        message("You want to run SAMBA 4 on a domain and forest function level" +                " lower than Windows 2003 (Native). This is not recommended")      if dom_for_fun_level > domainControllerFunctionality:          raise ProvisioningError("You want to run SAMBA 4 on a domain and forest function level which itself is higher than its actual DC function level (2008). This won't work!") @@ -864,7 +868,7 @@ def setup_samdb(path, setup_path, session_info, provision_backend, lp,          provision_backend=provision_backend, session_info=session_info,          names=names, serverrole=serverrole, schema=schema) -    if (schema == None): +    if schema is None:          schema = Schema(setup_path, domainsid, schemadn=names.schemadn, serverdn=names.serverdn)      # Load the database, but importantly, use Ldb not SamDB as we don't want to @@ -1033,7 +1037,6 @@ def setup_samdb(path, setup_path, session_info, provision_backend, lp,              names.ntdsguid = samdb.searchone(basedn=ntds_dn,                  attribute="objectGUID", expression="", scope=ldb.SCOPE_BASE)              assert isinstance(names.ntdsguid, str) -      except:          samdb.transaction_cancel()          raise @@ -1066,9 +1069,11 @@ def set_gpo_acl(sysvol, dnsdomain, domainsid, domaindn, samdb, lp):                          attrs=["cn","nTSecurityDescriptor"],                          expression="", scope=ldb.SCOPE_ONELEVEL)      for policy in res: -        acl = ndr_unpack(security.descriptor,str(policy["nTSecurityDescriptor"])).as_sddl() +        acl = ndr_unpack(security.descriptor,  +                         str(policy["nTSecurityDescriptor"])).as_sddl()          policy_path = getpolicypath(sysvol,dnsdomain,str(policy["cn"])) -        set_dir_acl(policy_path,dsacl2fsacl(acl,str(domainsid)),lp,str(domainsid)) +        set_dir_acl(policy_path, dsacl2fsacl(acl, str(domainsid)), lp,  +                    str(domainsid))  def setsysvolacl(samdb, netlogon, sysvol, gid, domainsid, dnsdomain, domaindn,      lp): @@ -1177,8 +1182,8 @@ def provision(setup_dir, message, session_info,          data = open(smbconf, 'r').read()          data = data.lstrip()          if data is None or data == "": -            make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole,  -                         targetdir, sid_generator, useeadb) +            make_smbconf(smbconf, setup_path, hostname, domain, realm, +                         serverrole, targetdir, sid_generator, useeadb)      else:           make_smbconf(smbconf, setup_path, hostname, domain, realm, serverrole,                        targetdir, sid_generator, useeadb) @@ -1229,7 +1234,8 @@ def provision(setup_dir, message, session_info,      ldapi_url = "ldapi://%s" % urllib.quote(paths.s4_ldapi_path, safe="") -    schema = Schema(setup_path, domainsid, schemadn=names.schemadn, serverdn=names.serverdn) +    schema = Schema(setup_path, domainsid, schemadn=names.schemadn, +                    serverdn=names.serverdn)      if backend_type == "ldb":          provision_backend = LDBBackend(backend_type, @@ -1275,7 +1281,7 @@ def provision(setup_dir, message, session_info,                                           ol_mmr_urls=ol_mmr_urls,                                            nosync=nosync)      else: -        raise ProvisioningError("Unknown LDAP backend type selected") +        raise ValueError("Unknown LDAP backend type selected")      provision_backend.init()      provision_backend.start() @@ -1290,8 +1296,8 @@ def provision(setup_dir, message, session_info,      message("Setting up secrets.ldb")      secrets_ldb = setup_secretsdb(paths.secrets, setup_path,  -                                  session_info=session_info,  -                                  backend_credentials=provision_backend.secrets_credentials, lp=lp) +        session_info=session_info, +        backend_credentials=provision_backend.secrets_credentials, lp=lp)      message("Setting up the registry")      setup_registry(paths.hklm, setup_path, session_info,  @@ -1322,15 +1328,15 @@ def provision(setup_dir, message, session_info,          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) +                    (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("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)             -             +            assert paths.sysvol is not None          if not os.path.isdir(paths.netlogon):              os.makedirs(paths.netlogon, 0755) @@ -1342,8 +1348,9 @@ def provision(setup_dir, message, session_info,          if serverrole == "domain controller":              # Set up group policies (domain policy and domain controller policy) -            setup_gpo(paths.sysvol,names.dnsdomain,policyguid,policyguid_dc) -            setsysvolacl(samdb,paths.netlogon,paths.sysvol,wheel_gid,domainsid,names.dnsdomain,names.domaindn,lp) +            setup_gpo(paths.sysvol, names.dnsdomain, policyguid, policyguid_dc) +            setsysvolacl(samdb, paths.netlogon, paths.sysvol, wheel_gid,  +                         domainsid, names.dnsdomain, names.domaindn, lp)          message("Setting up sam.ldb rootDSE marking as synchronized")          setup_modify_ldif(samdb, setup_path("provision_rootdse_modify.ldif")) @@ -1368,11 +1375,10 @@ def provision(setup_dir, message, session_info,              # Only make a zone file on the first DC, it should be replicated              # with DNS replication -            create_zone_file(lp, message, paths, targetdir, setup_path, dnsdomain=names.dnsdomain, -                             hostip=hostip, -                             hostip6=hostip6, hostname=names.hostname, -                             realm=names.realm, -                             domainguid=domainguid, ntdsguid=names.ntdsguid) +            create_zone_file(lp, message, paths, targetdir, setup_path, +                dnsdomain=names.dnsdomain, hostip=hostip, hostip6=hostip6, +                hostname=names.hostname, realm=names.realm,  +                domainguid=domainguid, ntdsguid=names.ntdsguid)              create_named_conf(paths, setup_path, realm=names.realm,                                dnsdomain=names.dnsdomain, private_dir=paths.private_dir) @@ -1381,12 +1387,14 @@ def provision(setup_dir, message, session_info,                                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) +            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) -            message("A Kerberos configuration suitable for Samba 4 has been generated at %s" % paths.krb5conf) +            message("A Kerberos configuration suitable for Samba 4 has been " +                    "generated at %s" % paths.krb5conf)      if serverrole == "domain controller":          create_dns_update_list(lp, message, paths, setup_path) @@ -1407,7 +1415,8 @@ def provision(setup_dir, message, session_info,              os.chmod(dns_keytab_path, 0640)              os.chown(dns_keytab_path, -1, paths.bind_gid)          except OSError: -            message("Failed to chown %s to bind gid %u" % (dns_keytab_path, paths.bind_gid)) +            message("Failed to chown %s to bind gid %u" % (dns_keytab_path, +                paths.bind_gid))      message("Please install the phpLDAPadmin configuration located at %s into /etc/phpldapadmin/config.php" % paths.phpldapadminconfig) @@ -1443,7 +1452,6 @@ def provision(setup_dir, message, session_info,      return result -  def provision_become_dc(setup_dir=None,                          smbconf=None, targetdir=None, realm=None,                           rootdn=None, domaindn=None, schemadn=None, @@ -1622,7 +1630,6 @@ def create_krb5_conf(path, setup_path, dnsdomain, hostname, realm):      :param hostname: Local hostname      :param realm: Realm name      """ -      setup_file(setup_path("krb5.conf"), path, {              "DNSDOMAIN": dnsdomain,              "HOSTNAME": hostname, @@ -1630,3 +1637,17 @@ def create_krb5_conf(path, setup_path, dnsdomain, hostname, realm):          }) +class ProvisioningError(Exception): +    """A generic provision error.""" + +    def __init__(self, value): +        self.value = value + +    def __str__(self): +        return "ProvisioningError: " + self.value + + +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) diff --git a/source4/scripting/python/samba/provisionbackend.py b/source4/scripting/python/samba/provisionbackend.py index 479d965f27..e5d4d8e1b1 100644 --- a/source4/scripting/python/samba/provisionbackend.py +++ b/source4/scripting/python/samba/provisionbackend.py @@ -26,6 +26,7 @@  """Functions for setting up a Samba configuration (LDB and LDAP backends)."""  from base64 import b64encode +import errno  import ldb  import os  import sys @@ -40,11 +41,21 @@ from ldb import SCOPE_BASE, SCOPE_ONELEVEL, LdbError, timestring  from samba import Ldb, read_and_sub_file, setup_file  from samba.credentials import Credentials, DONT_USE_KERBEROS  from samba.schema import Schema -from samba.provisionexceptions import ProvisioningError + + +class SlapdAlreadyRunning(Exception): + +    def __init__(self, uri): +        self.ldapi_uri = uri +        super(SlapdAlreadyRunning, self).__init__("Another slapd Instance " +            "seems already running on this host, listening to %s." % +            self.ldapi_uri) +  class ProvisionBackend(object): -    def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None,  -                 names=None, message=None): + +    def __init__(self, backend_type, paths=None, setup_path=None, lp=None, +            credentials=None, names=None, message=None):          """Provision a backend for samba4"""          self.paths = paths          self.setup_path = setup_path @@ -72,15 +83,6 @@ class ProvisionBackend(object):  class LDBBackend(ProvisionBackend): -    def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None,  -                 names=None, message=None): - -        super(LDBBackend, self).__init__( -                backend_type=backend_type, -                paths=paths, setup_path=setup_path, -                lp=lp, credentials=credentials, -                names=names, -                message=message)      def init(self):          self.credentials = None @@ -91,49 +93,40 @@ class LDBBackend(ProvisionBackend):  class ExistingBackend(ProvisionBackend): -    def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None,  -                 names=None, message=None, -                 ldapi_uri=None): -        super(ExistingBackend, self).__init__( -                backend_type=backend_type, -                paths=paths, setup_path=setup_path, -                lp=lp, credentials=credentials, -                names=names, -                message=message) +    def __init__(self, backend_type, paths=None, setup_path=None, lp=None, +            credentials=None, names=None, message=None, ldapi_uri=None): + +        super(ExistingBackend, self).__init__(backend_type=backend_type, +                paths=paths, setup_path=setup_path, lp=lp, +                credentials=credentials, names=names, message=message)          self.ldapi_uri = ldapi_uri      def init(self): -        #Check to see that this 'existing' LDAP backend in fact exists +        # Check to see that this 'existing' LDAP backend in fact exists          ldapi_db = Ldb(self.ldapi_uri, credentials=self.credentials)          ldapi_db.search(base="", scope=SCOPE_BASE, -                                            expression="(objectClass=OpenLDAProotDSE)") +            expression="(objectClass=OpenLDAProotDSE)") -        # If we have got here, then we must have a valid connection to the LDAP server, with valid credentials supplied -        # This caused them to be set into the long-term database later in the script. +        # If we have got here, then we must have a valid connection to the LDAP +        # server, with valid credentials supplied This caused them to be set +        # into the long-term database later in the script.          self.secrets_credentials = self.credentials -        self.ldap_backend_type = "openldap" #For now, assume existing backends at least emulate OpenLDAP +        self.ldap_backend_type = "openldap" # For now, assume existing backends at least emulate OpenLDAP  class LDAPBackend(ProvisionBackend): -    def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None, -                 names=None, message=None, -                 domainsid=None, -                 schema=None, -                 hostname=None, -                 ldapadminpass=None, -                 slapd_path=None, -                 ldap_backend_extra_port=None, -                 ldap_dryrun_mode=False): - -        super(LDAPBackend, self).__init__( -                backend_type=backend_type, -                paths=paths, setup_path=setup_path, -                lp=lp, credentials=credentials, -                names=names, -                message=message) + +    def __init__(self, backend_type, paths=None, setup_path=None, lp=None, +            credentials=None, names=None, message=None, domainsid=None, +            schema=None, hostname=None, ldapadminpass=None, slapd_path=None, +            ldap_backend_extra_port=None, ldap_dryrun_mode=False): + +        super(LDAPBackend, self).__init__(backend_type=backend_type, +                paths=paths, setup_path=setup_path, lp=lp, +                credentials=credentials, names=names, message=message)          self.domainsid = domainsid          self.schema = schema @@ -156,23 +149,26 @@ class LDAPBackend(ProvisionBackend):              os.mkdir(self.ldapdir)      def init(self): -        # we will shortly start slapd with ldapi for final provisioning. first check with ldapsearch -> rootDSE via self.ldapi_uri -        # if another instance of slapd is already running  +        from samba.provision import ProvisioningError +        # we will shortly start slapd with ldapi for final provisioning. first +        # check with ldapsearch -> rootDSE via self.ldapi_uri if another +        # instance of slapd is already running           try:              ldapi_db = Ldb(self.ldapi_uri)              ldapi_db.search(base="", scope=SCOPE_BASE,                  expression="(objectClass=OpenLDAProotDSE)")              try:                  f = open(self.slapd_pid, "r") +            except IOError, err: +                if err != errno.ENOENT: +                    raise +            else:                  p = f.read()                  f.close()                  self.message("Check for slapd Process with PID: " + str(p) + " and terminate it manually.") -            except: -                pass -             -            raise ProvisioningError("Warning: Another slapd Instance seems already running on this host, listening to " + self.ldapi_uri + ". Please shut it down before you continue. ") -         +            raise SlapdAlreadyRunning(self.ldapi_uri)          except LdbError: +            # XXX: We should never be catching all Ldb errors              pass          # Try to print helpful messages when the user has not specified the path to slapd @@ -216,13 +212,15 @@ class LDAPBackend(ProvisionBackend):          pass      def start(self): +        from samba.provision import ProvisioningError          self.slapd_command_escaped = "\'" + "\' \'".join(self.slapd_command) + "\'" -        open(self.ldapdir + "/ldap_backend_startup.sh", 'w').write("#!/bin/sh\n" + self.slapd_command_escaped + "\n") +        open(os.path.join(self.ldapdir, "ldap_backend_startup.sh"), 'w').write("#!/bin/sh\n" + self.slapd_command_escaped + "\n")          # Now start the slapd, so we can provision onto it.  We keep the          # subprocess context around, to kill this off at the successful          # end of the script -        self.slapd = subprocess.Popen(self.slapd_provision_command, close_fds=True, shell=False) +        self.slapd = subprocess.Popen(self.slapd_provision_command, +            close_fds=True, shell=False)          while self.slapd.poll() is None:              # Wait until the socket appears @@ -253,29 +251,18 @@ class LDAPBackend(ProvisionBackend):  class OpenLDAPBackend(LDAPBackend): -    def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None, -                 names=None, message=None, -                 domainsid=None, -                 schema=None, -                 hostname=None, -                 ldapadminpass=None, -                 slapd_path=None, -                 ldap_backend_extra_port=None, -                 ldap_dryrun_mode=False, -                 ol_mmr_urls=None, -                 nosync=False): - -        super(OpenLDAPBackend, self).__init__( -                backend_type=backend_type, -                paths=paths, setup_path=setup_path, -                lp=lp, credentials=credentials, -                names=names, -                message=message, -                domainsid=domainsid, -                schema=schema, -                hostname=hostname, -                ldapadminpass=ldapadminpass, -                slapd_path=slapd_path, + +    def __init__(self, backend_type, paths=None, setup_path=None, lp=None, +            credentials=None, names=None, message=None, domainsid=None, +            schema=None, hostname=None, ldapadminpass=None, slapd_path=None, +            ldap_backend_extra_port=None, ldap_dryrun_mode=False, +            ol_mmr_urls=None, nosync=False): + +        super(OpenLDAPBackend, self).__init__( backend_type=backend_type, +                paths=paths, setup_path=setup_path, lp=lp, +                credentials=credentials, names=names, message=message, +                domainsid=domainsid, schema=schema, hostname=hostname, +                ldapadminpass=ldapadminpass, slapd_path=slapd_path,                  ldap_backend_extra_port=ldap_backend_extra_port,                  ldap_dryrun_mode=ldap_dryrun_mode) @@ -290,11 +277,8 @@ class OpenLDAPBackend(LDAPBackend):          self.olcdir             = os.path.join(self.ldapdir, "slapd.d")          self.olcseedldif        = os.path.join(self.ldapdir, "olc_seed.ldif") -        self.schema = Schema( -                self.setup_path, -                self.domainsid, -                schemadn=self.names.schemadn, -                serverdn=self.names.serverdn, +        self.schema = Schema(self.setup_path, self.domainsid, +                schemadn=self.names.schemadn, serverdn=self.names.serverdn,                  files=[setup_path("schema_samba4.ldif")])      def setup_db_config(self, dbdir): @@ -307,10 +291,11 @@ class OpenLDAPBackend(LDAPBackend):              if not os.path.isdir(os.path.join(dbdir, "tmp")):                  os.makedirs(os.path.join(dbdir, "tmp"), 0700) -        setup_file(self.setup_path("DB_CONFIG"), os.path.join(dbdir, "DB_CONFIG"), -                   {"LDAPDBDIR": dbdir}) +        setup_file(self.setup_path("DB_CONFIG"), +            os.path.join(dbdir, "DB_CONFIG"), {"LDAPDBDIR": dbdir})      def provision(self): +        from samba.provision import ProvisioningError          # Wipe the directories so we can start          shutil.rmtree(os.path.join(self.ldapdir, "db"), True) @@ -350,7 +335,6 @@ class OpenLDAPBackend(LDAPBackend):          mmr_syncrepl_schema_config = ""           mmr_syncrepl_config_config = ""           mmr_syncrepl_user_config = ""  -                 if self.ol_mmr_urls is not None:              # For now, make these equal @@ -485,7 +469,8 @@ class OpenLDAPBackend(LDAPBackend):              if self.ol_mmr_urls is None:                  server_port_string = "ldap://0.0.0.0:%d" % self.ldap_backend_extra_port              else: -                server_port_string = "ldap://" + self.names.hostname + "." + self.names.dnsdomain +":%d" % self.ldap_backend_extra_port +                server_port_string = "ldap://%s.%s:%d" (self.names.hostname, +                    self.names.dnsdomain, self.ldap_backend_extra_port)          else:              server_port_string = "" @@ -537,29 +522,18 @@ class OpenLDAPBackend(LDAPBackend):  class FDSBackend(LDAPBackend): -    def __init__(self, backend_type, paths=None, setup_path=None, lp=None, credentials=None, -                 names=None, message=None, -                 domainsid=None, -                 schema=None, -                 hostname=None, -                 ldapadminpass=None, -                 slapd_path=None, -                 ldap_backend_extra_port=None, -                 ldap_dryrun_mode=False, -                 root=None, -                 setup_ds_path=None): - -        super(FDSBackend, self).__init__( -                backend_type=backend_type, -                paths=paths, setup_path=setup_path, -                lp=lp, credentials=credentials, -                names=names, -                message=message, -                domainsid=domainsid, -                schema=schema, -                hostname=hostname, -                ldapadminpass=ldapadminpass, -                slapd_path=slapd_path, + +    def __init__(self, backend_type, paths=None, setup_path=None, lp=None, +            credentials=None, names=None, message=None, domainsid=None, +            schema=None, hostname=None, ldapadminpass=None, slapd_path=None, +            ldap_backend_extra_port=None, ldap_dryrun_mode=False, root=None, +            setup_ds_path=None): + +        super(FDSBackend, self).__init__(backend_type=backend_type, +                paths=paths, setup_path=setup_path, lp=lp, +                credentials=credentials, names=names, message=message, +                domainsid=domainsid, schema=schema, hostname=hostname, +                ldapadminpass=ldapadminpass, slapd_path=slapd_path,                  ldap_backend_extra_port=ldap_backend_extra_port,                  ldap_dryrun_mode=ldap_dryrun_mode) @@ -600,6 +574,7 @@ class FDSBackend(LDAPBackend):                  prefixmap=["1000:1.3.6.1.4.1.7165.2.1", "1001:1.3.6.1.4.1.7165.2.2"])      def provision(self): +        from samba.provision import ProvisioningError          if self.ldap_backend_extra_port is not None:              serverport = "ServerPort=%d" % self.ldap_backend_extra_port          else: @@ -616,7 +591,8 @@ class FDSBackend(LDAPBackend):                      "LDAPMANAGERPASS": self.ldapadminpass,                       "SERVERPORT": serverport}) -        setup_file(self.setup_path("fedorads-partitions.ldif"), self.partitions_ldif,  +        setup_file(self.setup_path("fedorads-partitions.ldif"), +            self.partitions_ldif,                      {"CONFIGDN": self.names.configdn,                      "SCHEMADN": self.names.schemadn,                      "SAMBADN": self.sambadn, diff --git a/source4/scripting/python/samba/provisionexceptions.py b/source4/scripting/python/samba/provisionexceptions.py deleted file mode 100644 index 6159a02e95..0000000000 --- a/source4/scripting/python/samba/provisionexceptions.py +++ /dev/null @@ -1,38 +0,0 @@ -# -# 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-2009 -# Copyright (C) Oliver Liebel <oliver@itc.li> 2008-2009 -# -# 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/>. -# - -class ProvisioningError(Exception): -    """A generic provision error.""" -    def __init__(self, value): -        self.value = value -    def __str__(self): -        return "ProvisioningError: " + self.value - -class InvalidNetbiosName(ProvisioningError): -    """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) - - diff --git a/source4/scripting/python/samba/upgradehelpers.py b/source4/scripting/python/samba/upgradehelpers.py index 25d1d7fe29..3da739b139 100755 --- a/source4/scripting/python/samba/upgradehelpers.py +++ b/source4/scripting/python/samba/upgradehelpers.py @@ -31,8 +31,8 @@ from samba import Ldb  from samba.dsdb import DS_DOMAIN_FUNCTION_2000  from ldb import SCOPE_SUBTREE, SCOPE_ONELEVEL, SCOPE_BASE  import ldb -from samba.provision import ProvisionNames, provision_paths_from_lp, FILL_FULL, provision -from samba.provisionexceptions import ProvisioningError +from samba.provision import (ProvisionNames, provision_paths_from_lp, +    FILL_FULL, provision, ProvisioningError)  from samba.dcerpc import misc, security  from samba.ndr import ndr_unpack @@ -61,7 +61,8 @@ def get_paths(param, targetdir=None, smbconf=None):      return paths -def find_provision_key_parameters(param, credentials, session_info, paths, smbconf): +def find_provision_key_parameters(param, credentials, session_info, paths, +        smbconf):      """Get key provision parameters (realm, domain, ...) from a given provision      :param param: Param object @@ -82,10 +83,10 @@ def find_provision_key_parameters(param, credentials, session_info, paths, smbco      names.dnsdomain = names.realm      names.realm = string.upper(names.realm)      # netbiosname -    secrets_ldb = Ldb(paths.secrets, session_info=session_info, credentials=credentials,lp=lp, options=["modules:samba_secrets"]) +    secrets_ldb = Ldb(paths.secrets, session_info=session_info, +        credentials=credentials,lp=lp, options=["modules:samba_secrets"])      # Get the netbiosname first (could be obtained from smb.conf in theory) -    attrs = ["sAMAccountName"] -    res = secrets_ldb.search(expression="(flatname=%s)"%names.domain,base="CN=Primary Domains", scope=SCOPE_SUBTREE, attrs=attrs) +    res = secrets_ldb.search(expression="(flatname=%s)"%names.domain,base="CN=Primary Domains", scope=SCOPE_SUBTREE, attrs=["sAMAccountName"])      names.netbiosname = str(res[0]["sAMAccountName"]).replace("$","")      names.smbconf = smbconf @@ -96,8 +97,7 @@ def find_provision_key_parameters(param, credentials, session_info, paths, smbco      # That's a bit simplistic but it's ok as long as we have only 3      # partitions -    attrs2 = ["defaultNamingContext", "schemaNamingContext","configurationNamingContext","rootDomainNamingContext"] -    current = samdb.search(expression="(objectClass=*)",base="", scope=SCOPE_BASE, attrs=attrs2) +    current = samdb.search(expression="(objectClass=*)",base="", scope=SCOPE_BASE, attrs=["defaultNamingContext", "schemaNamingContext","configurationNamingContext","rootDomainNamingContext"])      names.configdn = current[0]["configurationNamingContext"]      configdn = str(names.configdn) @@ -108,27 +108,28 @@ def find_provision_key_parameters(param, credentials, session_info, paths, smbco      names.domaindn=current[0]["defaultNamingContext"]      names.rootdn=current[0]["rootDomainNamingContext"]      # default site name -    attrs3 = ["cn"] -    res3= samdb.search(expression="(objectClass=*)",base="CN=Sites,"+configdn, scope=SCOPE_ONELEVEL, attrs=attrs3) +    res3= samdb.search(expression="(objectClass=*)",base="CN=Sites,"+configdn, scope=SCOPE_ONELEVEL, attrs=["cn"])      names.sitename = str(res3[0]["cn"])      # dns hostname and server dn -    attrs4 = ["dNSHostName"]      res4= samdb.search(expression="(CN=%s)"%names.netbiosname,base="OU=Domain Controllers,"+basedn, \ -                        scope=SCOPE_ONELEVEL, attrs=attrs4) +                        scope=SCOPE_ONELEVEL, attrs=["dNSHostName"])      names.hostname = str(res4[0]["dNSHostName"]).replace("."+names.dnsdomain,"")      server_res = samdb.search(expression="serverReference=%s"%res4[0].dn, attrs=[], base=configdn)      names.serverdn = server_res[0].dn      # invocation id/objectguid -    res5 = samdb.search(expression="(objectClass=*)",base="CN=NTDS Settings,%s" % str(names.serverdn), scope=SCOPE_BASE, attrs=["invocationID","objectGUID"]) -    names.invocation = str(ndr_unpack( misc.GUID,res5[0]["invocationId"][0])) -    names.ntdsguid = str(ndr_unpack( misc.GUID,res5[0]["objectGUID"][0])) +    res5 = samdb.search(expression="(objectClass=*)", +            base="CN=NTDS Settings,%s" % str(names.serverdn), scope=SCOPE_BASE, +            attrs=["invocationID", "objectGUID"]) +    names.invocation = str(ndr_unpack(misc.GUID, res5[0]["invocationId"][0])) +    names.ntdsguid = str(ndr_unpack(misc.GUID, res5[0]["objectGUID"][0]))      # domain guid/sid -    attrs6 = ["objectGUID", "objectSid","msDS-Behavior-Version" ] -    res6 = samdb.search(expression="(objectClass=*)",base=basedn, scope=SCOPE_BASE, attrs=attrs6) +    res6 = samdb.search(expression="(objectClass=*)",base=basedn, +            scope=SCOPE_BASE, attrs=["objectGUID", +                "objectSid","msDS-Behavior-Version" ])      names.domainguid = str(ndr_unpack( misc.GUID,res6[0]["objectGUID"][0]))      names.domainsid = ndr_unpack( security.dom_sid,res6[0]["objectSid"][0])      if res6[0].get("msDS-Behavior-Version") == None or int(res6[0]["msDS-Behavior-Version"][0]) < DS_DOMAIN_FUNCTION_2000: @@ -137,14 +138,12 @@ def find_provision_key_parameters(param, credentials, session_info, paths, smbco          names.domainlevel = int(res6[0]["msDS-Behavior-Version"][0])      # policy guid -    attrs7 = ["cn","displayName"]      res7 = samdb.search(expression="(displayName=Default Domain Policy)",base="CN=Policies,CN=System,"+basedn, \ -                            scope=SCOPE_ONELEVEL, attrs=attrs7) +                            scope=SCOPE_ONELEVEL, attrs=["cn","displayName"])      names.policyid = str(res7[0]["cn"]).replace("{","").replace("}","")      # dc policy guid -    attrs8 = ["cn","displayName"]      res8 = samdb.search(expression="(displayName=Default Domain Controllers Policy)",base="CN=Policies,CN=System,"+basedn, \ -                            scope=SCOPE_ONELEVEL, attrs=attrs8) +                            scope=SCOPE_ONELEVEL, attrs=["cn","displayName"])      if len(res8) == 1:          names.policyid_dc = str(res8[0]["cn"]).replace("{","").replace("}","")      else: @@ -194,9 +193,12 @@ def newprovision(names,setup_dir,creds,session,smbconf,provdir,messagefunc):  def dn_sort(x,y): -    """Sorts two DNs in the lexicographical order it and put higher level DN before. +    """Sorts two DNs in the lexicographical order it and put higher level DN +    before. + +    So given the dns cn=bar,cn=foo and cn=foo the later will be return as +    smaller -    So given the dns cn=bar,cn=foo and cn=foo the later will be return as smaller      :param x: First object to compare      :param y: Second object to compare      """  | 
