示例#1
0
def update_machine_account_password(samdb, secrets_ldb, names):
    """Update (change) the password of the current DC both in the SAM db and in
       secret one

    :param samdb: An LDB object related to the sam.ldb file of a given provision
    :param secrets_ldb: An LDB object related to the secrets.ldb file of a given
                        provision
    :param names: List of key provision parameters"""

    expression = "samAccountName=%s$" % names.netbiosname
    secrets_msg = secrets_ldb.search(expression=expression,
                                     attrs=["secureChannelType"])
    if int(secrets_msg[0]["secureChannelType"][0]) == SEC_CHAN_BDC:
        res = samdb.search(expression=expression, attrs=[])
        assert (len(res) == 1)

        msg = ldb.Message(res[0].dn)
        machinepass = samba.generate_random_machine_password(128, 255)
        mputf16 = machinepass.encode('utf-16-le')
        msg["clearTextPassword"] = ldb.MessageElement(mputf16,
                                                      ldb.FLAG_MOD_REPLACE,
                                                      "clearTextPassword")
        samdb.modify(msg)

        res = samdb.search(expression=("samAccountName=%s$" %
                                       names.netbiosname),
                           attrs=["msDs-keyVersionNumber"])
        assert (len(res) == 1)
        kvno = int(str(res[0]["msDs-keyVersionNumber"]))
        secChanType = int(secrets_msg[0]["secureChannelType"][0])

        secretsdb_self_join(secrets_ldb,
                            domain=names.domain,
                            realm=names.realm,
                            domainsid=names.domainsid,
                            dnsdomain=names.dnsdomain,
                            netbiosname=names.netbiosname,
                            machinepass=machinepass,
                            key_version_number=kvno,
                            secure_channel_type=secChanType)
    else:
        raise ProvisioningError("Unable to find a Secure Channel"
                                "of type SEC_CHAN_BDC")
示例#2
0
def get_posix_attr_from_ldap_backend(logger, ldb_object, base_dn, user, attr):
    """Get posix attributes from a samba3 ldap backend
    :param ldbs: a list of ldb connection objects
    :param base_dn: the base_dn of the connection
    :param user: the user to get the attribute for
    :param attr: the attribute to be retrieved
    """
    try:
        msg = ldb_object.search(base_dn, scope=ldb.SCOPE_SUBTREE,
                        expression=("(&(objectClass=posixAccount)(uid=%s))"
                        % (user)), attrs=[attr])
    except ldb.LdbError as e:
        raise ProvisioningError("Failed to retrieve attribute %s for user %s, the error is: %s" % (attr, user, e))
    else:
        if msg.count <= 1:
            # This will raise KeyError (which is what we want) if there isn't a entry for this user
            return msg[0][attr][0]
        else:
            logger.warning("LDAP entry for user %s contains more than one %s", user, attr)
            raise KeyError
示例#3
0
def update_dns_account_password(samdb, secrets_ldb, names):
    """Update (change) the password of the dns both in the SAM db and in
       secret one

    :param samdb: An LDB object related to the sam.ldb file of a given provision
    :param secrets_ldb: An LDB object related to the secrets.ldb file of a given
                        provision
    :param names: List of key provision parameters"""

    expression = "samAccountName=dns-%s" % names.netbiosname
    secrets_msg = secrets_ldb.search(expression=expression)
    if len(secrets_msg) == 1:
        res = samdb.search(expression=expression, attrs=[])
        assert(len(res) == 1)

        msg = ldb.Message(res[0].dn)
        machinepass = samba.generate_random_password(128, 255)
        mputf16 = machinepass.encode('utf-16-le')
        msg["clearTextPassword"] = ldb.MessageElement(mputf16,
                                                ldb.FLAG_MOD_REPLACE,
                                                "clearTextPassword")

        samdb.modify(msg)

        res = samdb.search(expression=expression,
                     attrs=["msDs-keyVersionNumber"])
        assert(len(res) == 1)
        kvno = str(res[0]["msDs-keyVersionNumber"])

        msg = ldb.Message(secrets_msg[0].dn)
        msg["secret"] = ldb.MessageElement(machinepass,
                                                ldb.FLAG_MOD_REPLACE,
                                                "secret")
        msg["msDS-KeyVersionNumber"] = ldb.MessageElement(kvno,
                                                ldb.FLAG_MOD_REPLACE,
                                                "msDS-KeyVersionNumber")

        secrets_ldb.modify(msg)
    else:
        raise ProvisioningError("Unable to find an object"
                                " with %s" % expression )
示例#4
0
def get_paths(param, targetdir=None, smbconf=None):
    """Get paths to important provision objects (smb.conf, ldb files, ...)

    :param param: Param object
    :param targetdir: Directory where the provision is (or will be) stored
    :param smbconf: Path to the smb.conf file
    :return: A list with the path of important provision objects"""
    if targetdir is not None:
        etcdir = os.path.join(targetdir, "etc")
        if not os.path.exists(etcdir):
            os.makedirs(etcdir)
        smbconf = os.path.join(etcdir, "smb.conf")
    if smbconf is None:
        smbconf = param.default_path()

    if not os.path.exists(smbconf):
        raise ProvisioningError("Unable to find smb.conf")

    lp = param.LoadParm()
    lp.load(smbconf)
    paths = provision_paths_from_lp(lp, lp.get("realm"))
    return paths
示例#5
0
文件: upgrade.py 项目: nwns/samba
def upgrade_from_samba3(samba3, logger, targetdir, session_info=None,
        useeadb=False, dns_backend=None, use_ntvfs=False):
    """Upgrade from samba3 database to samba4 AD database

    :param samba3: samba3 object
    :param logger: Logger object
    :param targetdir: samba4 database directory
    :param session_info: Session information
    """
    serverrole = samba3.lp.server_role()

    domainname = samba3.lp.get("workgroup")
    realm = samba3.lp.get("realm")
    netbiosname = samba3.lp.get("netbios name")

    if samba3.lp.get("ldapsam:trusted") is None:
        samba3.lp.set("ldapsam:trusted", "yes")

    # secrets db
    try:
        secrets_db = samba3.get_secrets_db()
    except IOError, e:
        raise ProvisioningError("Could not open '%s', the Samba3 secrets database: %s.  Perhaps you specified the incorrect smb.conf, --testparm or --dbdir option?" % (samba3.privatedir_path("secrets.tdb"), str(e)))
示例#6
0
        secrets_db = samba3.get_secrets_db()
    except IOError, e:
        raise ProvisioningError(
            "Could not open '%s', the Samba3 secrets database: %s.  Perhaps you specified the incorrect smb.conf, --testparm or --dbdir option?"
            % (samba3.privatedir_path("secrets.tdb"), str(e)))

    if not domainname:
        domainname = secrets_db.domains()[0]
        logger.warning(
            "No workgroup specified in smb.conf file, assuming '%s'",
            domainname)

    if not realm:
        if serverrole == "ROLE_DOMAIN_BDC" or serverrole == "ROLE_DOMAIN_PDC":
            raise ProvisioningError(
                "No realm specified in smb.conf file and being a DC. That upgrade path doesn't work! Please add a 'realm' directive to your old smb.conf to let us know which one you want to use (it is the DNS name of the AD domain you wish to create."
            )
        else:
            realm = domainname.upper()
            logger.warning(
                "No realm specified in smb.conf file, assuming '%s'", realm)

    # Find machine account and password
    next_rid = 1000

    try:
        machinepass = secrets_db.get_machine_password(netbiosname)
    except KeyError:
        machinepass = None

    if samba3.lp.get("passdb backend").split(":")[0].strip() == "ldapsam":
示例#7
0
    def provision(self):
        from samba.provision import ProvisioningError, setup_path
        if self.ldap_backend_extra_port is not None:
            serverport = "ServerPort=%d" % self.ldap_backend_extra_port
        else:
            serverport = ""

        setup_file(
            setup_path("fedorads.inf"), self.fedoradsinf, {
                "ROOT": self.root,
                "HOSTNAME": self.hostname,
                "DNSDOMAIN": self.names.dnsdomain,
                "LDAPDIR": self.ldapdir,
                "DOMAINDN": self.names.domaindn,
                "LDAP_INSTANCE": self.ldap_instance,
                "LDAPMANAGERDN": self.names.ldapmanagerdn,
                "LDAPMANAGERPASS": self.ldapadminpass,
                "SERVERPORT": serverport
            })

        setup_file(
            setup_path("fedorads-partitions.ldif"), self.partitions_ldif, {
                "CONFIGDN": self.names.configdn,
                "SCHEMADN": self.names.schemadn,
                "SAMBADN": self.sambadn,
            })

        setup_file(setup_path("fedorads-sasl.ldif"), self.sasl_ldif, {
            "SAMBADN": self.sambadn,
        })

        setup_file(
            setup_path("fedorads-dna.ldif"), self.dna_ldif, {
                "DOMAINDN": self.names.domaindn,
                "SAMBADN": self.sambadn,
                "DOMAINSID": str(self.domainsid),
            })

        setup_file(setup_path("fedorads-pam.ldif"), self.pam_ldif)

        lnkattr = self.schema.linked_attributes()

        f = open(setup_path("fedorads-refint-delete.ldif"), 'r')
        try:
            refint_config = f.read()
        finally:
            f.close()
        memberof_config = ""
        index_config = ""
        argnum = 3

        for attr in lnkattr.keys():
            if lnkattr[attr] is not None:
                refint_config += read_and_sub_file(
                    setup_path("fedorads-refint-add.ldif"), {
                        "ARG_NUMBER": str(argnum),
                        "LINK_ATTR": attr
                    })
                memberof_config += read_and_sub_file(
                    setup_path("fedorads-linked-attributes.ldif"), {
                        "MEMBER_ATTR": attr,
                        "MEMBEROF_ATTR": lnkattr[attr]
                    })
                index_config += read_and_sub_file(
                    setup_path("fedorads-index.ldif"), {"ATTR": attr})
                argnum += 1

        f = open(self.refint_ldif, 'w')
        try:
            f.write(refint_config)
        finally:
            f.close()
        f = open(self.linked_attrs_ldif, 'w')
        try:
            f.write(memberof_config)
        finally:
            f.close()

        attrs = ["lDAPDisplayName"]
        res = self.schema.ldb.search(
            expression="(&(objectclass=attributeSchema)"
            "(searchFlags:1.2.840.113556.1.4.803:=1))",
            base=self.names.schemadn,
            scope=SCOPE_ONELEVEL,
            attrs=attrs)

        for i in range(0, len(res)):
            attr = res[i]["lDAPDisplayName"][0]

            if attr == "objectGUID":
                attr = "nsUniqueId"

            index_config += read_and_sub_file(
                setup_path("fedorads-index.ldif"), {"ATTR": attr})

        f = open(self.index_ldif, 'w')
        try:
            f.write(index_config)
        finally:
            f.close()

        setup_file(setup_path("fedorads-samba.ldif"), self.samba_ldif, {
            "SAMBADN": self.sambadn,
            "LDAPADMINPASS": self.ldapadminpass
        })

        mapping = "schema-map-fedora-ds-1.0"
        backend_schema = "99_ad.ldif"

        # Build a schema file in Fedora DS format
        f = open(setup_path(mapping), 'r')
        try:
            backend_schema_data = self.schema.convert_to_openldap(
                "fedora-ds", f.read())
        finally:
            f.close()
        assert backend_schema_data is not None
        f = open(os.path.join(self.ldapdir, backend_schema), 'w')
        try:
            f.write(backend_schema_data)
        finally:
            f.close()

        self.credentials.set_bind_dn(self.names.ldapmanagerdn)

        # Destory the target directory, or else setup-ds.pl will complain
        fedora_ds_dir = \
            os.path.join(self.ldapdir,
                         "slapd-" + self.ldap_instance)
        shutil.rmtree(fedora_ds_dir, True)

        self.slapd_provision_command = [
            self.slapd_path, "-D", fedora_ds_dir, "-i", self.slapd_pid
        ]
        # In the 'provision' command line, stay in the foreground so we can
        # easily kill it
        self.slapd_provision_command.append("-d0")

        # the command for the final run is the normal script
        self.slapd_command = \
            [os.path.join(self.ldapdir,
                          "slapd-" + self.ldap_instance, "start-slapd")]

        # If we were just looking for crashes up to this point, it's a
        # good time to exit before we realise we don't have Fedora DS on
        if self.ldap_dryrun_mode:
            sys.exit(0)

        # Try to print helpful messages when the user has not specified the
        # path to the setup-ds tool
        if self.setup_ds_path is None:
            raise ProvisioningError(
                "Fedora DS LDAP-Backend must be setup with path to setup-ds, e.g. --setup-ds-path=\"/usr/sbin/setup-ds.pl\"!"
            )
        if not os.path.exists(self.setup_ds_path):
            self.logger.warning("Path (%s) to slapd does not exist!",
                                self.setup_ds_path)

        # Run the Fedora DS setup utility
        retcode = subprocess.call(
            [self.setup_ds_path, "--silent", "--file", self.fedoradsinf],
            close_fds=True,
            shell=False)
        if retcode != 0:
            raise ProvisioningError("setup-ds failed")

        # Load samba-admin
        retcode = subprocess.call([
            os.path.join(self.ldapdir, "slapd-" + self.ldap_instance,
                         "ldif2db"), "-s", self.sambadn, "-i", self.samba_ldif
        ],
                                  close_fds=True,
                                  shell=False)
        if retcode != 0:
            raise ProvisioningError("ldif2db failed")
示例#8
0
    def provision(self):
        from samba.provision import ProvisioningError, setup_path
        # Wipe the directories so we can start
        shutil.rmtree(os.path.join(self.ldapdir, "db"), True)

        # Allow the test scripts to turn off fsync() for OpenLDAP as for TDB
        # and LDB
        nosync_config = ""
        if self.nosync:
            nosync_config = "dbnosync"

        lnkattr = self.schema.linked_attributes()
        refint_attributes = ""
        memberof_config = "# Generated from Samba4 schema\n"
        for att in lnkattr.keys():
            if lnkattr[att] is not None:
                refint_attributes = refint_attributes + " " + att

                memberof_config += read_and_sub_file(
                    setup_path("memberof.conf"), {
                        "MEMBER_ATTR": att,
                        "MEMBEROF_ATTR": lnkattr[att]
                    })

        refint_config = read_and_sub_file(setup_path("refint.conf"),
                                          {"LINK_ATTRS": refint_attributes})

        attrs = ["linkID", "lDAPDisplayName"]
        res = self.schema.ldb.search(
            expression="(&(objectclass=attributeSchema)"
            "(searchFlags:1.2.840.113556.1.4.803:=1))",
            base=self.names.schemadn,
            scope=SCOPE_ONELEVEL,
            attrs=attrs)
        index_config = ""
        for i in range(0, len(res)):
            index_attr = res[i]["lDAPDisplayName"][0]
            if index_attr == "objectGUID":
                index_attr = "entryUUID"

            index_config += "index " + index_attr + " eq\n"

        # 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 = ""
        mmr_syncrepl_domaindns_config = ""
        mmr_syncrepl_forestdns_config = ""
        mmr_syncrepl_user_config = ""
        mmr_pass = ""

        if self.ol_mmr_urls is not None:
            # For now, make these equal
            mmr_pass = self.ldapadminpass

            url_list = filter(None, self.ol_mmr_urls.split(','))
            for url in url_list:
                self.logger.info("Using LDAP-URL: " + url)
            if len(url_list) == 1:
                raise ProvisioningError("At least 2 LDAP-URLs needed for MMR!")

            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
                mmr_serverids_config += read_and_sub_file(
                    setup_path("mmr_serverids.conf"), {
                        "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(rid),
                        "MMRDN": self.names.schemadn,
                        "LDAPSERVER": url,
                        "MMR_PASSWORD": mmr_pass
                    })

                rid = rid + 1
                mmr_syncrepl_config_config += read_and_sub_file(
                    setup_path("mmr_syncrepl.conf"), {
                        "RID": str(rid),
                        "MMRDN": self.names.configdn,
                        "LDAPSERVER": url,
                        "MMR_PASSWORD": mmr_pass
                    })

                rid = rid + 1
                mmr_syncrepl_domaindns_config += read_and_sub_file(
                    setup_path("mmr_syncrepl.conf"), {
                        "RID": str(rid),
                        "MMRDN": "dc=DomainDNSZones," + self.names.domaindn,
                        "LDAPSERVER": url,
                        "MMR_PASSWORD": mmr_pass
                    })

                rid = rid + 1
                mmr_syncrepl_forestdns_config += read_and_sub_file(
                    setup_path("mmr_syncrepl.conf"), {
                        "RID": str(rid),
                        "MMRDN": "dc=ForestDNSZones," + self.names.domaindn,
                        "LDAPSERVER": url,
                        "MMR_PASSWORD": mmr_pass
                    })

                rid = rid + 1
                mmr_syncrepl_user_config += read_and_sub_file(
                    setup_path("mmr_syncrepl.conf"), {
                        "RID": str(rid),
                        "MMRDN": self.names.domaindn,
                        "LDAPSERVER": url,
                        "MMR_PASSWORD": mmr_pass
                    })
        # OpenLDAP cn=config initialisation
        olc_syncrepl_config = ""
        olc_mmr_config = ""
        # if mmr = yes, generate cn=config-replication directives
        # and olc_seed.lif for the other mmr-servers
        if self.ol_mmr_urls is not None:
            serverid = 0
            olc_serverids_config = ""
            olc_syncrepl_seed_config = ""
            olc_mmr_config += read_and_sub_file(setup_path("olc_mmr.conf"), {})
            rid = 500
            for url in url_list:
                serverid = serverid + 1
                olc_serverids_config += read_and_sub_file(
                    setup_path("olc_serverid.conf"), {
                        "SERVERID": str(serverid),
                        "LDAPSERVER": url
                    })

                rid = rid + 1
                olc_syncrepl_config += read_and_sub_file(
                    setup_path("olc_syncrepl.conf"), {
                        "RID": str(rid),
                        "LDAPSERVER": url,
                        "MMR_PASSWORD": mmr_pass
                    })

                olc_syncrepl_seed_config += read_and_sub_file(
                    setup_path("olc_syncrepl_seed.conf"), {
                        "RID": str(rid),
                        "LDAPSERVER": url
                    })

            setup_file(
                setup_path("olc_seed.ldif"), self.olcseedldif, {
                    "OLC_SERVER_ID_CONF": olc_serverids_config,
                    "OLC_PW": self.ldapadminpass,
                    "OLC_SYNCREPL_CONF": olc_syncrepl_seed_config
                })
        # end olc

        setup_file(
            setup_path("slapd.conf"), self.slapdconf, {
                "DNSDOMAIN": self.names.dnsdomain,
                "LDAPDIR": self.ldapdir,
                "DOMAINDN": self.names.domaindn,
                "CONFIGDN": self.names.configdn,
                "SCHEMADN": self.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,
                "MMR_SYNCREPL_DOMAINDNS_CONFIG": mmr_syncrepl_domaindns_config,
                "MMR_SYNCREPL_FORESTDNS_CONFIG": mmr_syncrepl_forestdns_config,
                "MMR_SYNCREPL_USER_CONFIG": mmr_syncrepl_user_config,
                "OLC_SYNCREPL_CONFIG": olc_syncrepl_config,
                "OLC_MMR_CONFIG": olc_mmr_config,
                "REFINT_CONFIG": refint_config,
                "INDEX_CONFIG": index_config,
                "ADMIN_UID": str(os.getuid()),
                "NOSYNC": nosync_config,
            })

        self.setup_db_dir(os.path.join(self.ldapdir, "db", "forestdns"))
        self.setup_db_dir(os.path.join(self.ldapdir, "db", "domaindns"))
        self.setup_db_dir(os.path.join(self.ldapdir, "db", "user"))
        self.setup_db_dir(os.path.join(self.ldapdir, "db", "config"))
        self.setup_db_dir(os.path.join(self.ldapdir, "db", "schema"))
        self.setup_db_dir(os.path.join(self.ldapdir, "db", "samba"))

        if self.ol_mmr_urls is not None:
            mmr = ""
        else:
            mmr = "#"

        cn_samba = read_and_sub_file(
            setup_path("cn=samba.ldif"), {
                "LDAPADMINPASS": self.ldapadminpass,
                "MMR_PASSWORD": mmr_pass,
                "MMR": mmr
            })

        mapping = "schema-map-openldap-2.3"
        backend_schema = "backend-schema.schema"

        f = open(setup_path(mapping), 'r')
        try:
            backend_schema_data = self.schema.convert_to_openldap(
                "openldap", f.read())
        finally:
            f.close()
        assert backend_schema_data is not None
        f = open(os.path.join(self.ldapdir, backend_schema), 'w')
        try:
            f.write(backend_schema_data)
        finally:
            f.close()

        # now we generate the needed strings to start slapd automatically,
        if self.ldap_backend_extra_port is not None:
            # When we use MMR, we can't use 0.0.0.0 as it uses the name
            # specified there as part of it's clue as to it's own name,
            # and not to replicate to itself
            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://%s.%s:%d" (
                    self.names.hostname, self.names.dnsdomain,
                    self.ldap_backend_extra_port)
        else:
            server_port_string = ""

        # Prepare the 'result' information - the commands to return in
        # particular
        self.slapd_provision_command = [
            self.slapd_path, "-F" + self.olcdir, "-h"
        ]

        # copy this command so we have two version, one with -d0 and only
        # ldapi (or the forced ldap_uri), and one with all the listen commands
        self.slapd_command = list(self.slapd_provision_command)

        self.slapd_provision_command.extend([self.ldap_uri, "-d0"])
        uris = self.ldap_uri
        if server_port_string is not "":
            uris = uris + " " + server_port_string

        self.slapd_command.append(uris)

        # Wipe the old sam.ldb databases away
        shutil.rmtree(self.olcdir, True)
        os.makedirs(self.olcdir, 0o770)

        # If we were just looking for crashes up to this point, it's a
        # good time to exit before we realise we don't have OpenLDAP on
        # this system
        if self.ldap_dryrun_mode:
            sys.exit(0)

        slapd_cmd = [
            self.slapd_path, "-Ttest", "-n", "0", "-f", self.slapdconf, "-F",
            self.olcdir
        ]
        retcode = subprocess.call(slapd_cmd, close_fds=True, shell=False)

        if retcode != 0:
            self.logger.error(
                "conversion from slapd.conf to cn=config failed slapd started with: %s"
                % "\'" + "\' \'".join(slapd_cmd) + "\'")
            raise ProvisioningError(
                "conversion from slapd.conf to cn=config failed")

        if not os.path.exists(os.path.join(self.olcdir, "cn=config.ldif")):
            raise ProvisioningError(
                "conversion from slapd.conf to cn=config failed")

        # Don't confuse the admin by leaving the slapd.conf around
        os.remove(self.slapdconf)

        cn_samba_cmd = [
            self.slapd_path, "-Tadd", "-b", "cn=samba", "-F", self.olcdir
        ]
        p = subprocess.Popen(cn_samba_cmd, stdin=subprocess.PIPE, shell=False)
        p.stdin.write(cn_samba)
        p.communicate()
示例#9
0
    def init(self):
        from samba.provision import ProvisioningError
        # we will shortly start slapd with ldapi for final provisioning. first
        # check with ldapsearch -> rootDSE via self.ldap_uri if another
        # instance of slapd is already running
        try:
            ldapi_db = Ldb(self.ldap_uri)
            ldapi_db.search(base="",
                            scope=SCOPE_BASE,
                            expression="(objectClass=OpenLDAProotDSE)")
            try:
                f = open(self.slapd_pid, "r")
            except IOError as err:
                if err != errno.ENOENT:
                    raise
            else:
                try:
                    p = f.read()
                finally:
                    f.close()
                self.logger.info(
                    "Check for slapd process with PID: %s and terminate it manually."
                    % p)
            raise SlapdAlreadyRunning(self.ldap_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
        if self.slapd_path is None:
            raise ProvisioningError(
                "Warning: LDAP-Backend must be setup with path to slapd, e.g. --slapd-path=\"/usr/local/libexec/slapd\"!"
            )
        if not os.path.exists(self.slapd_path):
            self.logger.warning("Path (%s) to slapd does not exist!",
                                self.slapd_path)

        if not os.path.isdir(self.ldapdir):
            os.makedirs(self.ldapdir, 0o700)

        # Put the LDIF of the schema into a database so we can search on
        # it to generate schema-dependent configurations in Fedora DS and
        # OpenLDAP
        schemadb_path = os.path.join(self.ldapdir, "schema-tmp.ldb")
        try:
            os.unlink(schemadb_path)
        except OSError:
            pass

        self.schema.write_to_tmp_ldb(schemadb_path)

        self.credentials = Credentials()
        self.credentials.guess(self.lp)
        # Kerberos to an ldapi:// backend makes no sense (we also force EXTERNAL)
        self.credentials.set_kerberos_state(DONT_USE_KERBEROS)
        self.credentials.set_username("samba-admin")
        self.credentials.set_password(self.ldapadminpass)
        self.credentials.set_forced_sasl_mech("EXTERNAL")

        self.provision()
示例#10
0
文件: sambadns.py 项目: auralic/Samba
def create_named_conf(paths, realm, dnsdomain, dns_backend, logger):
    """Write out a file containing zone statements suitable for inclusion in a
    named.conf file (including GSS-TSIG configuration).

    :param paths: all paths
    :param realm: Realm name
    :param dnsdomain: DNS Domain name
    :param dns_backend: DNS backend type
    :param keytab_name: File name of DNS keytab file
    :param logger: Logger object
    """

    # TODO: This really should have been done as a top level import.
    # It is done here to avoid a depencency loop.  That is, we move
    # ProvisioningError to another file, and have all the provision
    # scripts import it from there.

    from samba.provision import ProvisioningError

    if dns_backend == "BIND9_FLATFILE":
        setup_file(
            setup_path("named.conf"), paths.namedconf, {
                "DNSDOMAIN": dnsdomain,
                "REALM": realm,
                "ZONE_FILE": paths.dns,
                "REALM_WC": "*." + ".".join(realm.split(".")[1:]),
                "NAMED_CONF": paths.namedconf,
                "NAMED_CONF_UPDATE": paths.namedconf_update
            })

        setup_file(setup_path("named.conf.update"), paths.namedconf_update)

    elif dns_backend == "BIND9_DLZ":
        bind_info = subprocess.Popen(['named -V'],
                                     shell=True,
                                     stdout=subprocess.PIPE,
                                     stderr=subprocess.STDOUT,
                                     cwd='.').communicate()[0]
        bind9_8 = '#'
        bind9_9 = '#'
        bind9_10 = '#'
        bind9_11 = '#'
        if bind_info.upper().find('BIND 9.8') != -1:
            bind9_8 = ''
        elif bind_info.upper().find('BIND 9.9') != -1:
            bind9_9 = ''
        elif bind_info.upper().find('BIND 9.10') != -1:
            bind9_10 = ''
        elif bind_info.upper().find('BIND 9.11') != -1:
            bind9_11 = ''
        elif bind_info.upper().find('BIND 9.7') != -1:
            raise ProvisioningError("DLZ option incompatible with BIND 9.7.")
        else:
            logger.warning("BIND version unknown, please modify %s manually." %
                           paths.namedconf)
        setup_file(
            setup_path("named.conf.dlz"), paths.namedconf, {
                "NAMED_CONF": paths.namedconf,
                "MODULESDIR": samba.param.modules_dir(),
                "BIND9_8": bind9_8,
                "BIND9_9": bind9_9,
                "BIND9_10": bind9_10,
                "BIND9_11": bind9_11
            })
示例#11
0
def upgrade_from_samba3(samba3,
                        logger,
                        targetdir,
                        session_info=None,
                        useeadb=False,
                        dns_backend=None,
                        use_ntvfs=False):
    """Upgrade from samba3 database to samba4 AD database

    :param samba3: samba3 object
    :param logger: Logger object
    :param targetdir: samba4 database directory
    :param session_info: Session information
    """
    serverrole = samba3.lp.server_role()

    domainname = samba3.lp.get("workgroup")
    realm = samba3.lp.get("realm")
    netbiosname = samba3.lp.get("netbios name")

    if samba3.lp.get("ldapsam:trusted") is None:
        samba3.lp.set("ldapsam:trusted", "yes")

    # secrets db
    try:
        secrets_db = samba3.get_secrets_db()
    except IOError as e:
        raise ProvisioningError(
            "Could not open '%s', the Samba3 secrets database: %s.  Perhaps you specified the incorrect smb.conf, --testparm or --dbdir option?"
            % (samba3.privatedir_path("secrets.tdb"), str(e)))

    if not domainname:
        domainname = secrets_db.domains()[0]
        logger.warning(
            "No workgroup specified in smb.conf file, assuming '%s'",
            domainname)

    if not realm:
        if serverrole == "ROLE_DOMAIN_BDC" or serverrole == "ROLE_DOMAIN_PDC":
            raise ProvisioningError(
                "No realm specified in smb.conf file and being a DC. That upgrade path doesn't work! Please add a 'realm' directive to your old smb.conf to let us know which one you want to use (it is the DNS name of the AD domain you wish to create."
            )
        else:
            realm = domainname.upper()
            logger.warning(
                "No realm specified in smb.conf file, assuming '%s'", realm)

    # Find machine account and password
    next_rid = 1000

    try:
        machinepass = secrets_db.get_machine_password(netbiosname)
    except KeyError:
        machinepass = None

    if samba3.lp.get("passdb backend").split(":")[0].strip() == "ldapsam":
        base_dn = samba3.lp.get("ldap suffix")
        ldapuser = samba3.lp.get("ldap admin dn")
        ldappass = secrets_db.get_ldap_bind_pw(ldapuser)
        if ldappass is None:
            raise ProvisioningError(
                "ldapsam passdb backend detected but no LDAP Bind PW found in secrets.tdb for user %s.  Please point this tool at the secrets.tdb that was used by the previous installation."
            )
        ldappass = ldappass.decode('utf-8').strip('\x00')
        ldap = True
    else:
        ldapuser = None
        ldappass = None
        ldap = False

    # We must close the direct pytdb database before the C code loads it
    secrets_db.close()

    # Connect to old password backend
    passdb.set_secrets_dir(samba3.lp.get("private dir"))
    s3db = samba3.get_sam_db()

    # Get domain sid
    try:
        domainsid = passdb.get_global_sam_sid()
    except passdb.error:
        raise Exception("Can't find domain sid for '%s', Exiting." %
                        domainname)

    # Get machine account, sid, rid
    try:
        machineacct = s3db.getsampwnam('%s$' % netbiosname)
    except passdb.error:
        machinerid = None
        machinesid = None
    else:
        machinesid, machinerid = machineacct.user_sid.split()

    # Export account policy
    logger.info("Exporting account policy")
    policy = s3db.get_account_policy()

    # Export groups from old passdb backend
    logger.info("Exporting groups")
    grouplist = s3db.enum_group_mapping()
    groupmembers = {}
    for group in grouplist:
        sid, rid = group.sid.split()
        if sid == domainsid:
            if rid >= next_rid:
                next_rid = rid + 1

        # Get members for each group/alias
        if group.sid_name_use == lsa.SID_NAME_ALIAS:
            try:
                members = s3db.enum_aliasmem(group.sid)
                groupmembers[str(group.sid)] = members
            except passdb.error as e:
                logger.warn(
                    "Ignoring group '%s' %s listed but then not found: %s",
                    group.nt_name, group.sid, e)
                continue
        elif group.sid_name_use == lsa.SID_NAME_DOM_GRP:
            try:
                members = s3db.enum_group_members(group.sid)
                groupmembers[str(group.sid)] = members
            except passdb.error as e:
                logger.warn(
                    "Ignoring group '%s' %s listed but then not found: %s",
                    group.nt_name, group.sid, e)
                continue
        elif group.sid_name_use == lsa.SID_NAME_WKN_GRP:
            (group_dom_sid, rid) = group.sid.split()
            if (group_dom_sid != security.dom_sid(security.SID_BUILTIN)):
                logger.warn(
                    "Ignoring 'well known' group '%s' (should already be in AD, and have no members)",
                    group.nt_name)
                continue
            # A number of buggy databases mix up well known groups and aliases.
            try:
                members = s3db.enum_aliasmem(group.sid)
                groupmembers[str(group.sid)] = members
            except passdb.error as e:
                logger.warn(
                    "Ignoring group '%s' %s listed but then not found: %s",
                    group.nt_name, group.sid, e)
                continue
        else:
            logger.warn("Ignoring group '%s' %s with sid_name_use=%d",
                        group.nt_name, group.sid, group.sid_name_use)
            continue

    # Export users from old passdb backend
    logger.info("Exporting users")
    userlist = s3db.search_users(0)
    userdata = {}
    uids = {}
    admin_user = None
    for entry in userlist:
        if machinerid and machinerid == entry['rid']:
            continue
        username = entry['account_name']
        if entry['rid'] < 1000:
            logger.info("  Skipping wellknown rid=%d (for username=%s)",
                        entry['rid'], username)
            continue
        if entry['rid'] >= next_rid:
            next_rid = entry['rid'] + 1

        user = s3db.getsampwnam(username)
        acct_type = (user.acct_ctrl &
                     (samr.ACB_NORMAL | samr.ACB_WSTRUST | samr.ACB_SVRTRUST
                      | samr.ACB_DOMTRUST))
        if acct_type == samr.ACB_SVRTRUST:
            logger.warn(
                "  Demoting BDC account trust for %s, this DC must be elevated to an AD DC using 'samba-tool domain dcpromo'"
                % username[:-1])
            user.acct_ctrl = (user.acct_ctrl
                              & ~samr.ACB_SVRTRUST) | samr.ACB_WSTRUST

        elif acct_type == samr.ACB_DOMTRUST:
            logger.warn(
                "  Skipping inter-domain trust from domain %s, this trust must be re-created as an AD trust"
                % username[:-1])
            continue

        elif acct_type == (samr.ACB_WSTRUST) and username[-1] != '$':
            logger.warn(
                "  Skipping account %s that has ACB_WSTRUST (W) set but does not end in $.  This account can not have worked, and is probably left over from a misconfiguration."
                % username)
            continue

        elif acct_type == (samr.ACB_NORMAL
                           | samr.ACB_WSTRUST) and username[-1] == '$':
            logger.warn(
                "  Fixing account %s which had both ACB_NORMAL (U) and ACB_WSTRUST (W) set.  Account will be marked as ACB_WSTRUST (W), i.e. as a domain member"
                % username)
            user.acct_ctrl = (user.acct_ctrl & ~samr.ACB_NORMAL)

        elif acct_type == (samr.ACB_NORMAL
                           | samr.ACB_SVRTRUST) and username[-1] == '$':
            logger.warn(
                "  Fixing account %s which had both ACB_NORMAL (U) and ACB_SVRTRUST (S) set.  Account will be marked as ACB_WSTRUST (S), i.e. as a domain member"
                % username)
            user.acct_ctrl = (user.acct_ctrl & ~samr.ACB_NORMAL)

        elif acct_type == 0 and username[-1] != '$':
            user.acct_ctrl = (user.acct_ctrl | samr.ACB_NORMAL)

        elif (acct_type == samr.ACB_NORMAL or acct_type == samr.ACB_WSTRUST):
            pass

        else:
            raise ProvisioningError(
                """Failed to upgrade due to invalid account %s, account control flags 0x%08X must have exactly one of
ACB_NORMAL (N, 0x%08X), ACB_WSTRUST (W 0x%08X), ACB_SVRTRUST (S 0x%08X) or ACB_DOMTRUST (D 0x%08X).

Please fix this account before attempting to upgrade again
""" % (username, user.acct_ctrl, samr.ACB_NORMAL, samr.ACB_WSTRUST,
            samr.ACB_SVRTRUST, samr.ACB_DOMTRUST))

        userdata[username] = user
        try:
            uids[username] = s3db.sid_to_id(user.user_sid)[0]
        except passdb.error:
            try:
                uids[username] = pwd.getpwnam(username).pw_uid
            except KeyError:
                pass

        if not admin_user and username.lower() == 'root':
            admin_user = username
        if username.lower() == 'administrator':
            admin_user = username

        try:
            group_memberships = s3db.enum_group_memberships(user)
            for group in group_memberships:
                if str(group) in groupmembers:
                    if user.user_sid not in groupmembers[str(group)]:
                        groupmembers[str(group)].append(user.user_sid)
                else:
                    groupmembers[str(group)] = [user.user_sid]
        except passdb.error as e:
            logger.warn("Ignoring group memberships of '%s' %s: %s", username,
                        user.user_sid, e)

    logger.info("Next rid = %d", next_rid)

    # Check for same username/groupname
    group_names = set([g.nt_name for g in grouplist])
    user_names = set([u['account_name'] for u in userlist])
    common_names = group_names.intersection(user_names)
    if common_names:
        logger.error("Following names are both user names and group names:")
        for name in common_names:
            logger.error("   %s" % name)
        raise ProvisioningError(
            "Please remove common user/group names before upgrade.")

    # Check for same user sid/group sid
    group_sids = set([str(g.sid) for g in grouplist])
    if len(grouplist) != len(group_sids):
        raise ProvisioningError(
            "Please remove duplicate group sid entries before upgrade.")
    user_sids = set(["%s-%u" % (domainsid, u['rid']) for u in userlist])
    if len(userlist) != len(user_sids):
        raise ProvisioningError(
            "Please remove duplicate user sid entries before upgrade.")
    common_sids = group_sids.intersection(user_sids)
    if common_sids:
        logger.error("Following sids are both user and group sids:")
        for sid in common_sids:
            logger.error("   %s" % str(sid))
        raise ProvisioningError(
            "Please remove duplicate sid entries before upgrade.")

    # Get posix attributes from ldap or the os
    homes = {}
    shells = {}
    pgids = {}
    if ldap:
        creds = Credentials()
        creds.guess(samba3.lp)
        creds.set_bind_dn(ldapuser)
        creds.set_password(ldappass)
        urls = samba3.lp.get("passdb backend").split(":", 1)[1].strip('"')
        for url in urls.split():
            try:
                ldb_object = Ldb(url, credentials=creds)
            except ldb.LdbError as e:
                raise ProvisioningError(
                    "Could not open ldb connection to %s, the error message is: %s"
                    % (url, e))
            else:
                break
    logger.info("Exporting posix attributes")
    userlist = s3db.search_users(0)
    for entry in userlist:
        username = entry['account_name']
        if username in uids.keys():
            try:
                if ldap:
                    homes[username] = get_posix_attr_from_ldap_backend(
                        logger, ldb_object, base_dn, username, "homeDirectory")
                else:
                    homes[username] = pwd.getpwnam(username).pw_dir
            except KeyError:
                pass
            except IndexError:
                pass

            try:
                if ldap:
                    shells[username] = get_posix_attr_from_ldap_backend(
                        logger, ldb_object, base_dn, username, "loginShell")
                else:
                    shells[username] = pwd.getpwnam(username).pw_shell
            except KeyError:
                pass
            except IndexError:
                pass

            try:
                if ldap:
                    pgids[username] = get_posix_attr_from_ldap_backend(
                        logger, ldb_object, base_dn, username, "gidNumber")
                else:
                    pgids[username] = pwd.getpwnam(username).pw_gid
            except KeyError:
                pass
            except IndexError:
                pass

    logger.info("Reading WINS database")
    samba3_winsdb = None
    try:
        samba3_winsdb = samba3.get_wins_db()
    except IOError as e:
        logger.warn('Cannot open wins database, Ignoring: %s', str(e))

    if not (serverrole == "ROLE_DOMAIN_BDC"
            or serverrole == "ROLE_DOMAIN_PDC"):
        dns_backend = "NONE"

    # If we found an admin user, set a fake pw that we will override.
    # This avoids us printing out an admin password that we won't actually
    # set.
    if admin_user:
        adminpass = generate_random_password(12, 32)
    else:
        adminpass = None

    # Do full provision
    result = provision(logger,
                       session_info,
                       targetdir=targetdir,
                       realm=realm,
                       domain=domainname,
                       domainsid=domainsid,
                       next_rid=next_rid,
                       dc_rid=machinerid,
                       adminpass=adminpass,
                       dom_for_fun_level=dsdb.DS_DOMAIN_FUNCTION_2003,
                       hostname=netbiosname.lower(),
                       machinepass=machinepass,
                       serverrole=serverrole,
                       samdb_fill=FILL_FULL,
                       useeadb=useeadb,
                       dns_backend=dns_backend,
                       use_rfc2307=True,
                       use_ntvfs=use_ntvfs,
                       skip_sysvolacl=True)
    result.report_logger(logger)

    # Import WINS database
    logger.info("Importing WINS database")

    if samba3_winsdb:
        import_wins(Ldb(result.paths.winsdb), samba3_winsdb)

    # Set Account policy
    logger.info("Importing Account policy")
    import_sam_policy(result.samdb, policy, logger)

    # Migrate IDMAP database
    logger.info("Importing idmap database")
    import_idmap(result.idmap, samba3, logger)

    # Set the s3 context for samba4 configuration
    new_lp_ctx = s3param.get_context()
    new_lp_ctx.load(result.lp.configfile)
    new_lp_ctx.set("private dir", result.lp.get("private dir"))
    new_lp_ctx.set("state directory", result.lp.get("state directory"))
    new_lp_ctx.set("lock directory", result.lp.get("lock directory"))

    # Connect to samba4 backend
    s4_passdb = passdb.PDB(new_lp_ctx.get("passdb backend"))

    # Start a new transaction (should speed this up a little, due to index churn)
    result.samdb.transaction_start()

    logger.info("Adding groups")
    try:
        # Export groups to samba4 backend
        logger.info("Importing groups")
        for g in grouplist:
            # Ignore uninitialized groups (gid = -1)
            if g.gid != -1:
                add_group_from_mapping_entry(result.samdb, g, logger)
                add_ad_posix_idmap_entry(result.samdb, g.sid, g.gid,
                                         "ID_TYPE_GID", logger)
                add_posix_attrs(samdb=result.samdb,
                                sid=g.sid,
                                name=g.nt_name,
                                nisdomain=domainname.lower(),
                                xid_type="ID_TYPE_GID",
                                logger=logger)

    except:
        # We need this, so that we do not give even more errors due to not cancelling the transaction
        result.samdb.transaction_cancel()
        raise

    logger.info("Committing 'add groups' transaction to disk")
    result.samdb.transaction_commit()

    logger.info("Adding users")

    # Export users to samba4 backend
    logger.info("Importing users")
    for username in userdata:
        if username.lower() == 'administrator':
            if userdata[username].user_sid != dom_sid(str(domainsid) + "-500"):
                logger.error(
                    "User 'Administrator' in your existing directory has SID %s, expected it to be %s"
                    % (userdata[username].user_sid,
                       dom_sid(str(domainsid) + "-500")))
                raise ProvisioningError(
                    "User 'Administrator' in your existing directory does not have SID ending in -500"
                )
        if username.lower() == 'root':
            if userdata[username].user_sid == dom_sid(str(domainsid) + "-500"):
                logger.warn('User root has been replaced by Administrator')
            else:
                logger.warn(
                    'User root has been kept in the directory, it should be removed in favour of the Administrator user'
                )

        s4_passdb.add_sam_account(userdata[username])
        if username in uids:
            add_ad_posix_idmap_entry(result.samdb, userdata[username].user_sid,
                                     uids[username], "ID_TYPE_UID", logger)
            if (username in homes) and (homes[username] is not None) and \
               (username in shells) and (shells[username] is not None) and \
               (username in pgids) and (pgids[username] is not None):
                add_posix_attrs(samdb=result.samdb,
                                sid=userdata[username].user_sid,
                                name=username,
                                nisdomain=domainname.lower(),
                                xid_type="ID_TYPE_UID",
                                home=homes[username],
                                shell=shells[username],
                                pgid=pgids[username],
                                logger=logger)

    logger.info("Adding users to groups")
    # Start a new transaction (should speed this up a little, due to index churn)
    result.samdb.transaction_start()

    try:
        for g in grouplist:
            if str(g.sid) in groupmembers:
                add_users_to_group(result.samdb, g, groupmembers[str(g.sid)],
                                   logger)

    except:
        # We need this, so that we do not give even more errors due to not cancelling the transaction
        result.samdb.transaction_cancel()
        raise

    logger.info("Committing 'add users to groups' transaction to disk")
    result.samdb.transaction_commit()

    # Set password for administrator
    if admin_user:
        logger.info("Setting password for administrator")
        admin_userdata = s4_passdb.getsampwnam("administrator")
        admin_userdata.nt_passwd = userdata[admin_user].nt_passwd
        if userdata[admin_user].lanman_passwd:
            admin_userdata.lanman_passwd = userdata[admin_user].lanman_passwd
        admin_userdata.pass_last_set_time = userdata[
            admin_user].pass_last_set_time
        if userdata[admin_user].pw_history:
            admin_userdata.pw_history = userdata[admin_user].pw_history
        s4_passdb.update_sam_account(admin_userdata)
        logger.info(
            "Administrator password has been set to password of user '%s'",
            admin_user)

    if result.server_role == "active directory domain controller":
        setsysvolacl(result.samdb, result.paths.netlogon, result.paths.sysvol,
                     result.paths.root_uid, result.paths.root_gid,
                     security.dom_sid(result.domainsid),
                     result.names.dnsdomain, result.names.domaindn, result.lp,
                     use_ntvfs)
示例#12
0
        secrets_db = samba3.get_secrets_db()
    except IOError, e:
        raise ProvisioningError(
            "Could not open '%s', the Samba3 secrets database: %s.  Perhaps you specified the incorrect smb.conf, --testparm or --dbdir option?"
            % (samba3.privatedir_path("secrets.tdb"), str(e)))

    if not domainname:
        domainname = secrets_db.domains()[0]
        logger.warning(
            "No workgroup specified in smb.conf file, assuming '%s'",
            domainname)

    if not realm:
        if serverrole == "ROLE_DOMAIN_BDC" or serverrole == "ROLE_DOMAIN_PDC":
            raise ProvisioningError(
                "No realm specified in smb.conf file and being a DC. That upgrade path doesn't work! Please add a 'realm' directive to your old smb.conf to let us know which one you want to use (it is the DNS name of the AD domain you wish to create."
            )
        else:
            realm = domainname.upper()
            logger.warning(
                "No realm specified in smb.conf file, assuming '%s'", realm)

    # Find machine account and password
    next_rid = 1000

    try:
        machinepass = secrets_db.get_machine_password(netbiosname)
    except KeyError:
        machinepass = None

    # We must close the direct pytdb database before the C code loads it
示例#13
0
def find_provision_key_parameters(samdb, secretsdb, idmapdb, paths, smbconf, lp):
    """Get key provision parameters (realm, domain, ...) from a given provision

    :param samdb: An LDB object connected to the sam.ldb file
    :param secretsdb: An LDB object connected to the secrets.ldb file
    :param idmapdb: An LDB object connected to the idmap.ldb file
    :param paths: A list of path to provision object
    :param smbconf: Path to the smb.conf file
    :param lp: A LoadParm object
    :return: A list of key provision parameters
    """
    names = ProvisionNames()
    names.adminpass = None

    # NT domain, kerberos realm, root dn, domain dn, domain dns name
    names.domain = string.upper(lp.get("workgroup"))
    names.realm = lp.get("realm")
    basedn = "DC=" + names.realm.replace(".",",DC=")
    names.dnsdomain = names.realm.lower()
    names.realm = string.upper(names.realm)
    # netbiosname
    # Get the netbiosname first (could be obtained from smb.conf in theory)
    res = secretsdb.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

    # That's a bit simplistic but it's ok as long as we have only 3
    # partitions
    current = samdb.search(expression="(objectClass=*)", 
        base="", scope=SCOPE_BASE,
        attrs=["defaultNamingContext", "schemaNamingContext",
               "configurationNamingContext","rootDomainNamingContext"])

    names.configdn = current[0]["configurationNamingContext"]
    configdn = str(names.configdn)
    names.schemadn = current[0]["schemaNamingContext"]
    if not (ldb.Dn(samdb, basedn) == (ldb.Dn(samdb,
                                       current[0]["defaultNamingContext"][0]))):
        raise ProvisioningError(("basedn in %s (%s) and from %s (%s)"
                                 "is not the same ..." % (paths.samdb,
                                    str(current[0]["defaultNamingContext"][0]),
                                    paths.smbconf, basedn)))

    names.domaindn=current[0]["defaultNamingContext"]
    names.rootdn=current[0]["rootDomainNamingContext"]
    # default site name
    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
    res4 = samdb.search(expression="(CN=%s)" % names.netbiosname,
                            base="OU=Domain Controllers,%s" % basedn,
                            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]))

    # domain guid/sid
    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") is None or \
        int(res6[0]["msDS-Behavior-Version"][0]) < DS_DOMAIN_FUNCTION_2000:
        names.domainlevel = DS_DOMAIN_FUNCTION_2000
    else:
        names.domainlevel = int(res6[0]["msDS-Behavior-Version"][0])

    # policy guid
    res7 = samdb.search(expression="(displayName=Default Domain Policy)",
                        base="CN=Policies,CN=System," + basedn,
                        scope=SCOPE_ONELEVEL, attrs=["cn","displayName"])
    names.policyid = str(res7[0]["cn"]).replace("{","").replace("}","")
    # dc policy guid
    res8 = samdb.search(expression="(displayName=Default Domain Controllers"
                                   " Policy)",
                            base="CN=Policies,CN=System," + basedn,
                            scope=SCOPE_ONELEVEL, attrs=["cn","displayName"])
    if len(res8) == 1:
        names.policyid_dc = str(res8[0]["cn"]).replace("{","").replace("}","")
    else:
        names.policyid_dc = None
    res9 = idmapdb.search(expression="(cn=%s)" %
                            (security.SID_BUILTIN_ADMINISTRATORS),
                            attrs=["xidNumber"])
    if len(res9) == 1:
        names.wheel_gid = res9[0]["xidNumber"]
    else:
        raise ProvisioningError("Unable to find uid/gid for Domain Admins rid")
    return names