Example #1
0
def get_ldbs(paths, creds, session, lp):
    """Return LDB object mapped on most important databases

    :param paths: An object holding the different importants paths for provision object
    :param creds: Credential used for openning LDB files
    :param session: Session to use for openning LDB files
    :param lp: A loadparam object
    :return: A ProvisionLDB object that contains LDB object for the different LDB files of the provision"""

    ldbs = ProvisionLDB()

    ldbs.sam = SamDB(paths.samdb,
                     session_info=session,
                     credentials=creds,
                     lp=lp,
                     options=["modules:samba_dsdb"],
                     flags=0)
    ldbs.secrets = Ldb(paths.secrets,
                       session_info=session,
                       credentials=creds,
                       lp=lp)
    ldbs.idmap = Ldb(paths.idmapdb,
                     session_info=session,
                     credentials=creds,
                     lp=lp)
    ldbs.privilege = Ldb(paths.privilege,
                         session_info=session,
                         credentials=creds,
                         lp=lp)
    #    ldbs.hkcr = Ldb(paths.hkcr, session_info=session, credentials=creds, lp=lp)
    #    ldbs.hkcu = Ldb(paths.hkcu, session_info=session, credentials=creds, lp=lp)
    #    ldbs.hku = Ldb(paths.hku, session_info=session, credentials=creds, lp=lp)
    #    ldbs.hklm = Ldb(paths.hklm, session_info=session, credentials=creds, lp=lp)

    return ldbs
Example #2
0
 def setUp(self):
     super(MapTestCase, self).setUp()
     ldb = Ldb(self.ldburl, lp=cmdline_loadparm)
     ldif = read_datafile("provision_samba3sam.ldif")
     ldb.add_ldif(self.samba4.subst(ldif))
     self.setup_modules(ldb, self.samba3, self.samba4)
     del ldb
     self.ldb = Ldb(self.ldburl, lp=cmdline_loadparm)
Example #3
0
 def setUp(self):
     super(MapTestCase, self).setUp()
     ldb = Ldb(self.ldburl, lp=self.lp, session_info=system_session())
     ldb.set_opaque("skip_allocate_sids", "true")
     ldif = read_datafile("provision_samba3sam.ldif")
     ldb.add_ldif(self.samba4.subst(ldif))
     self.setup_modules(ldb, self.samba3, self.samba4)
     del ldb
     self.ldb = Ldb(self.ldburl, lp=self.lp, session_info=system_session())
     self.ldb.set_opaque("skip_allocate_sids", "true")
Example #4
0
def delta_update_basesamdb(refsampath, sampath, creds, session, lp, message):
    """Update the provision container db: sam.ldb
    This function is aimed for alpha9 and newer;

    :param refsampath: Path to the samdb in the reference provision
    :param sampath: Path to the samdb in the upgraded provision
    :param creds: Credential used for openning LDB files
    :param session: Session to use for openning LDB files
    :param lp: A loadparam object
    :return: A msg_diff object with the difference between the @ATTRIBUTES
             of the current provision and the reference provision
    """

    message(SIMPLE,
            "Update base samdb by searching difference with reference one")
    refsam = Ldb(refsampath,
                 session_info=session,
                 credentials=creds,
                 lp=lp,
                 options=["modules:"])
    sam = Ldb(sampath,
              session_info=session,
              credentials=creds,
              lp=lp,
              options=["modules:"])

    empty = ldb.Message()
    deltaattr = None
    reference = refsam.search(expression="")

    for refentry in reference:
        entry = sam.search(expression="distinguishedName=%s" % refentry["dn"],
                           scope=SCOPE_SUBTREE)
        if not len(entry):
            delta = sam.msg_diff(empty, refentry)
            message(CHANGE, "Adding %s to sam db" % str(refentry.dn))
            if str(refentry.dn) == "@PROVISION" and\
                    delta.get(samba.provision.LAST_PROVISION_USN_ATTRIBUTE):
                delta.remove(samba.provision.LAST_PROVISION_USN_ATTRIBUTE)
            delta.dn = refentry.dn
            sam.add(delta)
        else:
            delta = sam.msg_diff(entry[0], refentry)
            if str(refentry.dn) == "@ATTRIBUTES":
                deltaattr = sam.msg_diff(refentry, entry[0])
            if str(refentry.dn) == "@PROVISION" and\
                    delta.get(samba.provision.LAST_PROVISION_USN_ATTRIBUTE):
                delta.remove(samba.provision.LAST_PROVISION_USN_ATTRIBUTE)
            if len(delta.items()) > 1:
                delta.dn = refentry.dn
                sam.modify(delta)

    return deltaattr
Example #5
0
    def join_finalise(ctx):
        '''finalise the join, mark us synchronised and setup secrets db'''

        print "Sending DsReplicateUpdateRefs for all the partitions"
        ctx.send_DsReplicaUpdateRefs(ctx.schema_dn)
        ctx.send_DsReplicaUpdateRefs(ctx.config_dn)
        ctx.send_DsReplicaUpdateRefs(ctx.base_dn)

        print "Setting isSynchronized and dsServiceName"
        m = ldb.Message()
        m.dn = ldb.Dn(ctx.local_samdb, '@ROOTDSE')
        m["isSynchronized"] = ldb.MessageElement("TRUE", ldb.FLAG_MOD_REPLACE,
                                                 "isSynchronized")
        m["dsServiceName"] = ldb.MessageElement(
            "<GUID=%s>" % str(ctx.ntds_guid), ldb.FLAG_MOD_REPLACE,
            "dsServiceName")
        ctx.local_samdb.modify(m)

        if ctx.subdomain:
            return

        secrets_ldb = Ldb(ctx.paths.secrets,
                          session_info=system_session(),
                          lp=ctx.lp)

        print "Setting up secrets database"
        secretsdb_self_join(secrets_ldb,
                            domain=ctx.domain_name,
                            realm=ctx.realm,
                            dnsdomain=ctx.dnsdomain,
                            netbiosname=ctx.myname,
                            domainsid=security.dom_sid(ctx.domsid),
                            machinepass=ctx.acct_pass,
                            secure_channel_type=ctx.secure_channel_type,
                            key_version_number=ctx.key_version_number)
Example #6
0
def get_prim_dom(secrets_path, lp):
    secrets_ldb = Ldb(secrets_path, session_info=system_session(), lp=lp)
    return secrets_ldb.search(base="CN=Primary Domains",
                              attrs=['objectClass', 'samAccountName',
                                     'secret', 'msDS-KeyVersionNumber'],
                              scope=ldb.SCOPE_SUBTREE,
                              expression="(objectClass=kerberosSecret)")
 def __init__(self, file, basedn, dn):
     self.file = os.path.join(tempdir, file)
     self.url = "tdb://" + self.file
     self.basedn = basedn
     self.substvars = {"BASEDN": self.basedn}
     self.db = Ldb(lp=cmdline_loadparm)
     self._dn = dn
Example #8
0
    def join_provision_own_domain(ctx):
        """Provision the local SAM."""

        # we now operate exclusively on the local database, which
        # we need to reopen in order to get the newly created schema
        print("Reconnecting to local samdb")
        ctx.samdb = SamDB(url=ctx.local_samdb.url,
                          session_info=system_session(),
                          lp=ctx.local_samdb.lp,
                          global_schema=False)
        ctx.samdb.set_invocation_id(str(ctx.invocation_id))
        ctx.local_samdb = ctx.samdb

        print("Finding domain GUID from ncName")
        res = ctx.local_samdb.search(base=ctx.partition_dn, scope=ldb.SCOPE_BASE, attrs=['ncName'],
                                     controls=["extended_dn:1:1"])
        domguid = str(misc.GUID(ldb.Dn(ctx.samdb, res[0]['ncName'][0]).get_extended_component('GUID')))
        print("Got domain GUID %s" % domguid)

        print("Calling own domain provision")

        logger = logging.getLogger("provision")
        logger.addHandler(logging.StreamHandler(sys.stdout))

        secrets_ldb = Ldb(ctx.paths.secrets, session_info=system_session(), lp=ctx.lp)

        presult = provision_fill(ctx.local_samdb, secrets_ldb,
                                 logger, ctx.names, ctx.paths, domainsid=security.dom_sid(ctx.domsid),
                                 domainguid=domguid,
                                 targetdir=ctx.targetdir, samdb_fill=FILL_SUBDOMAIN,
                                 machinepass=ctx.acct_pass, serverrole="domain controller",
                                 lp=ctx.lp, hostip=ctx.names.hostip, hostip6=ctx.names.hostip6,
                                 dns_backend=ctx.dns_backend)
        print("Provision OK for domain %s" % ctx.names.dnsdomain)
Example #9
0
def accountcontrol(lp, creds, username=None, value=0):
    """enable/disable an OpenChange user account.

    :param lp: Loadparm context
    :param creds: Credentials context
    :param username: Name of user to disable
    :param value: the control value
    """

    names = guess_names_from_smbconf(lp, None, None)
    db = Ldb(url=get_ldb_url(lp, creds, names),
             session_info=system_session(),
             credentials=creds,
             lp=lp)
    user_dn = get_user_dn(db, names.domaindn, username)
    extended_user = """
dn: %s
changetype: modify
replace: msExchUserAccountControl
msExchUserAccountControl: %d
""" % (user_dn, value)
    db.modify_ldif(extended_user)
    if value == 2:
        print "[+] Account %s disabled" % username
    else:
        print "[+] Account %s enabled" % username
Example #10
0
 def rsop(self, gpo):
     output = {}
     pol_file = 'MACHINE/Registry.pol'
     section = 'Software\Policies\Microsoft\Cryptography\AutoEnrollment'
     if gpo.file_sys_path:
         path = os.path.join(gpo.file_sys_path, pol_file)
         pol_conf = self.parse(path)
         if not pol_conf:
             return output
         for e in pol_conf.entries:
             if e.keyname == section and e.valuename == 'AEPolicy':
                 enroll = e.data & 0x1 == 1
                 if e.data == 0x8000 or not enroll:
                     continue
                 output['Auto Enrollment Policy'] = {}
                 url = 'ldap://%s' % get_dc_hostname(self.creds, self.lp)
                 ldb = Ldb(url=url, session_info=system_session(),
                           lp=self.lp, credentials=self.creds)
                 cas = fetch_certification_authorities(ldb)
                 for ca in cas:
                     policy = 'Auto Enrollment Policy'
                     cn = ca['cn'][0]
                     output[policy][cn] = {}
                     output[policy][cn]['CA Certificate'] = \
                         format_root_cert(ca['cACertificate'][0]).decode()
                     output[policy][cn]['Auto Enrollment Server'] = \
                         ca['dNSHostName'][0]
                     supported_templates = \
                         get_supported_templates(ca['dNSHostName'][0],
                                                 self.logger)
                     output[policy][cn]['Templates'] = \
                         [t.decode() for t in supported_templates]
     return output
Example #11
0
    def backup_smb_dbs(self, private_dir, samdb, lp, logger):
        # First, determine if DB backend is MDB.  Assume not unless there is a
        # 'backendStore' attribute on @PARTITION containing the text 'mdb'
        store_label = "backendStore"
        res = samdb.search(base="@PARTITION",
                           scope=ldb.SCOPE_BASE,
                           attrs=[store_label])
        mdb_backend = store_label in res[0] and res[0][store_label][0] == 'mdb'

        sam_ldb_path = os.path.join(private_dir, 'sam.ldb')
        copy_function = None
        if mdb_backend:
            logger.info('MDB backend detected.  Using mdb backup function.')
            copy_function = self.offline_mdb_copy
        else:
            logger.info('Starting transaction on ' + sam_ldb_path)
            copy_function = self.offline_tdb_copy
            sam_obj = Ldb(sam_ldb_path, lp=lp)
            sam_obj.transaction_start()

        logger.info('   backing up ' + sam_ldb_path)
        self.offline_tdb_copy(sam_ldb_path)
        sam_ldb_d = sam_ldb_path + '.d'
        for sam_file in os.listdir(sam_ldb_d):
            sam_file = os.path.join(sam_ldb_d, sam_file)
            if sam_file.endswith('.ldb'):
                logger.info('   backing up locked/related file ' + sam_file)
                copy_function(sam_file)
            else:
                logger.info('   copying locked/related file ' + sam_file)
                shutil.copyfile(sam_file, sam_file + self.backup_ext)

        if not mdb_backend:
            sam_obj.transaction_cancel()
Example #12
0
    def process_group_policy(self, deleted_gpo_list, changed_gpo_list,
                             trust_dir=None, private_dir=None):
        if trust_dir is None:
            trust_dir = self.lp.cache_path('certs')
        if private_dir is None:
            private_dir = self.lp.private_path('certs')
        if not os.path.exists(trust_dir):
            os.mkdir(trust_dir, mode=0o755)
        if not os.path.exists(private_dir):
            os.mkdir(private_dir, mode=0o700)

        for guid, settings in deleted_gpo_list:
            self.gp_db.set_guid(guid)
            if str(self) in settings:
                for ca_cn_enc, data in settings[str(self)].items():
                    ca_cn = base64.b64decode(ca_cn_enc)
                    data = json.loads(data)
                    getcert = which('getcert')
                    if getcert is not None:
                        Popen([getcert, 'remove-ca', '-c', ca_cn]).wait()
                        for nickname in data['templates']:
                            Popen([getcert, 'stop-tracking',
                                   '-i', nickname]).wait()
                    for f in data['files']:
                        if os.path.exists(f):
                            os.unlink(f)
                    self.gp_db.delete(str(self), ca_cn_enc)
            self.gp_db.commit()

        for gpo in changed_gpo_list:
            if gpo.file_sys_path:
                section = 'Software\Policies\Microsoft\Cryptography\AutoEnrollment'
                self.gp_db.set_guid(gpo.name)
                pol_file = 'MACHINE/Registry.pol'
                path = os.path.join(gpo.file_sys_path, pol_file)
                pol_conf = self.parse(path)
                if not pol_conf:
                    continue
                for e in pol_conf.entries:
                    if e.keyname == section and e.valuename == 'AEPolicy':
                        # This policy applies as specified in [MS-CAESO] 4.4.5.1
                        if e.data == 0x8000:
                            continue # The policy is disabled
                        enroll = e.data & 0x1 == 1
                        manage = e.data & 0x2 == 1
                        retrive_pending = e.data & 0x4 == 1
                        if enroll:
                            url = 'ldap://%s' % get_dc_hostname(self.creds,
                                                                self.lp)
                            ldb = Ldb(url=url, session_info=system_session(),
                                      lp=self.lp, credentials=self.creds)
                            cas = fetch_certification_authorities(ldb)
                            for ca in cas:
                                data = cert_enroll(ca, trust_dir,
                                                   private_dir, self.logger)
                                self.gp_db.store(str(self),
                                     base64.b64encode(ca['cn'][0]).decode(),
                                     data)
                        self.gp_db.commit()
Example #13
0
def newuser(names, lp, creds, username=None):
    """extend user record with OpenChange settings.

    :param lp: Loadparm context
    :param creds: Credentials context
    :param names: provision names object.
    :param username: Name of user to extend
    """

    db = Ldb(url=get_ldb_url(lp, creds, names), session_info=system_session(),
             credentials=creds, lp=lp)
    user_dn = get_user_dn(db, "CN=Users,%s" % names.domaindn, username)
    if user_dn:
        extended_user = """
dn: %(user_dn)s
changetype: modify
add: mailNickName
mailNickname: %(username)s
add: homeMDB
homeMDB: CN=Mailbox Store (%(netbiosname)s),CN=First Storage Group,CN=InformationStore,CN=%(netbiosname)s,CN=Servers,CN=%(firstou)s,CN=Administrative Groups,CN=%(firstorg)s,CN=Microsoft Exchange,CN=Services,CN=Configuration,%(domaindn)s
add: homeMTA
homeMTA: CN=Mailbox Store (%(netbiosname)s),CN=First Storage Group,CN=InformationStore,CN=%(netbiosname)s,CN=Servers,CN=%(firstou)s,CN=Administrative Groups,CN=%(firstorg)s,CN=Microsoft Exchange,CN=Services,CN=Configuration,%(domaindn)s
add: legacyExchangeDN
legacyExchangeDN: /o=%(firstorg)s/ou=%(firstou)s/cn=Recipients/cn=%(username)s
add: proxyAddresses
proxyAddresses: =EX:/o=%(firstorg)s/ou=%(firstou)s/cn=Recipients/cn=%(username)s
proxyAddresses: smtp:postmaster@%(dnsdomain)s
proxyAddresses: X400:c=US;a= ;p=First Organizati;o=Exchange;s=%(username)s
proxyAddresses: SMTP:%(username)s@%(dnsdomain)s
replace: msExchUserAccountControl
msExchUserAccountControl: 0
"""
        ldif_value = extended_user % {"user_dn": user_dn,
                                      "username": username,
                                      "netbiosname": names.netbiosname,
                                      "firstorg": names.firstorg,
                                      "firstou": names.firstou,
                                      "domaindn": names.domaindn,
                                      "dnsdomain": names.dnsdomain}
        db.modify_ldif(ldif_value)

        res = db.search(base=user_dn, scope=SCOPE_BASE, attrs=["*"])
        if len(res) == 1:
            record = res[0]
        else:
            raise Exception("this should never happen as we just modified the record...")
        record_keys = map(lambda x: x.lower(), record.keys())

        if "displayname" not in record_keys:
            extended_user = "******" % (user_dn, username)
            db.modify_ldif(extended_user)

        if "mail" not in record_keys:
            extended_user = "******" % (user_dn, username, names.dnsdomain)
            db.modify_ldif(extended_user)

        print "[+] User %s extended and enabled" % username
    else:
        print "[!] User '%s' not found" % username
Example #14
0
 def __init__(self,
              host,
              creds,
              lp,
              two=False,
              quiet=False,
              descriptor=False,
              sort_aces=False,
              verbose=False,
              view="section",
              base="",
              scope="SUB"):
     ldb_options = []
     samdb_url = host
     if not "://" in host:
         if os.path.isfile(host):
             samdb_url = "tdb://%s" % host
         else:
             samdb_url = "ldap://%s" % host
     # use 'paged_search' module when connecting remotely
     if samdb_url.lower().startswith("ldap://"):
         ldb_options = ["modules:paged_searches"]
     self.ldb = Ldb(url=samdb_url,
                    credentials=creds,
                    lp=lp,
                    options=ldb_options)
     self.search_base = base
     self.search_scope = scope
     self.two_domains = two
     self.quiet = quiet
     self.descriptor = descriptor
     self.sort_aces = sort_aces
     self.view = view
     self.verbose = verbose
     self.host = host
     self.base_dn = str(self.ldb.get_default_basedn())
     self.root_dn = str(self.ldb.get_root_basedn())
     self.config_dn = str(self.ldb.get_config_basedn())
     self.schema_dn = str(self.ldb.get_schema_basedn())
     self.domain_netbios = self.find_netbios()
     self.server_names = self.find_servers()
     self.domain_name = re.sub("[Dd][Cc]=", "",
                               self.base_dn).replace(",", ".")
     self.domain_sid = self.find_domain_sid()
     self.get_guid_map()
     self.get_sid_map()
     #
     # Log some domain controller specific place-holers that are being used
     # when compare content of two DCs. Uncomment for DEBUG purposes.
     if self.two_domains and not self.quiet:
         self.outf.write("\n* Place-holders for %s:\n" % self.host)
         self.outf.write(4 * " " +
                         "${DOMAIN_DN}      => %s\n" % self.base_dn)
         self.outf.write(4 * " " +
                         "${DOMAIN_NETBIOS} => %s\n" % self.domain_netbios)
         self.outf.write(4 * " " +
                         "${SERVER_NAME}     => %s\n" % self.server_names)
         self.outf.write(4 * " " +
                         "${DOMAIN_NAME}    => %s\n" % self.domain_name)
Example #15
0
 def backup_secrets(self, private_dir, lp, logger):
     secrets_path = os.path.join(private_dir, 'secrets')
     secrets_obj = Ldb(secrets_path + '.ldb', lp=lp)
     logger.info('Starting transaction on ' + secrets_path)
     secrets_obj.transaction_start()
     self.offline_tdb_copy(secrets_path + '.ldb')
     self.offline_tdb_copy(secrets_path + '.tdb')
     secrets_obj.transaction_cancel()
Example #16
0
    def init(self):
        # Check to see that this 'existing' LDAP backend in fact exists
        ldapi_db = Ldb(self.ldapi_uri)
        ldapi_db.search(base="", scope=SCOPE_BASE,
            expression="(objectClass=OpenLDAProotDSE)")

        # For now, assume existing backends at least emulate OpenLDAP
        self.ldap_backend_type = "openldap"
Example #17
0
 def __init__(self, basedn, dn, lp):
     self.db = Ldb(lp=lp, session_info=system_session())
     self.db.set_opaque("skip_allocate_sids", "true")
     self.basedn = basedn
     self.basedn_casefold = ldb.Dn(self.db, basedn).get_casefold()
     self.substvars = {"BASEDN": self.basedn}
     self.file = os.path.join(tempdir, "%s.ldb" % self.basedn_casefold)
     self.url = "tdb://" + self.file
     self._dn = dn
Example #18
0
 def __init__(self, basedn, dn):
     self.db = Ldb(lp=cmdline_loadparm)
     self.basedn = basedn
     self.basedn_casefold = ldb.Dn(self.db, basedn).get_casefold()
     self.substvars = {"BASEDN": self.basedn}
     self.file = os.path.join(tempdir,
                              "%s.ldb" % self.basedn_casefold)
     self.url = "tdb://" + self.file
     self._dn = dn
Example #19
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()
Example #20
0
    def __init__(self,
                 setup_path,
                 domain_sid,
                 schemadn=None,
                 serverdn=None,
                 files=None,
                 prefixmap=None):
        """Load schema for the SamDB from the AD schema files and samba4_schema.ldif
        
        :param samdb: Load a schema into a SamDB.
        :param setup_path: Setup path function.
        :param schemadn: DN of the schema
        :param serverdn: DN of the server
        
        Returns the schema data loaded, to avoid double-parsing when then needing to add it to the db
        """

        self.schemadn = schemadn
        self.ldb = Ldb()
        self.schema_data = read_ms_schema(
            setup_path('ad-schema/MS-AD_Schema_2K8_Attributes.txt'),
            setup_path('ad-schema/MS-AD_Schema_2K8_Classes.txt'))

        if files is not None:
            for file in files:
                self.schema_data += open(file, 'r').read()

        self.schema_data = substitute_var(self.schema_data,
                                          {"SCHEMADN": schemadn})
        check_all_substituted(self.schema_data)

        self.schema_dn_modify = read_and_sub_file(
            setup_path("provision_schema_basedn_modify.ldif"), {
                "SCHEMADN": schemadn,
                "SERVERDN": serverdn,
            })

        descr = b64encode(get_schema_descriptor(domain_sid))
        self.schema_dn_add = read_and_sub_file(
            setup_path("provision_schema_basedn.ldif"), {
                "SCHEMADN": schemadn,
                "DESCRIPTOR": descr
            })

        self.prefixmap_data = open(setup_path("prefixMap.txt"), 'r').read()

        if prefixmap is not None:
            for map in prefixmap:
                self.prefixmap_data += "%s\n" % map

        self.prefixmap_data = b64encode(self.prefixmap_data)

        # We don't actually add this ldif, just parse it
        prefixmap_ldif = "dn: cn=schema\nprefixMap:: %s\n\n" % self.prefixmap_data
        self.ldb.set_schema_from_ldif(prefixmap_ldif, self.schema_data)
Example #21
0
    def init(self):
        #Check to see that this 'existing' LDAP backend in fact exists
        ldapi_db = Ldb(self.ldapi_uri, credentials=self.credentials)
        search_ol_rootdse = ldapi_db.search(base="", scope=SCOPE_BASE,
                                            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.
        self.secrets_credentials = self.credentials

        self.ldap_backend_type = "openldap" #For now, assume existing backends at least emulate OpenLDAP
Example #22
0
 def run(self, acl, file, quiet=False,xattr_backend=None,eadb_file=None,
         credopts=None, sambaopts=None, versionopts=None):
     lp = sambaopts.get_loadparm()
     creds = credopts.get_credentials(lp)
     path = os.path.join(lp.get("private dir"), lp.get("secrets database") or "secrets.ldb")
     creds = credopts.get_credentials(lp)
     creds.set_kerberos_state(DONT_USE_KERBEROS)
     try:
         ldb = Ldb(path, session_info=system_session(), credentials=creds,
                   lp=lp)
     except Exception, e:
         raise CommandError("Unable to read domain SID from configuration files", e)
Example #23
0
def ldif_to_samdb(dburl, lp, ldif_file, forced_local_dsa=None):
    """Routine to import all objects and attributes that are relevent
    to the KCC algorithms from a previously exported LDIF file.

    The point of this function is to allow a programmer/debugger to
    import an LDIF file with non-security relevent information that
    was previously extracted from a DC database.  The LDIF file is used
    to create a temporary abbreviated database.  The KCC algorithm can
    then run against this abbreviated database for debug or test
    verification that the topology generated is computationally the
    same between different OSes and algorithms.

    :param dburl: path to the temporary abbreviated db to create
    :param ldif_file: path to the ldif file to import
    """
    if os.path.exists(dburl):
        raise LdifError("Specify a database (%s) that doesn't already exist." %
                        dburl)

    # Use ["modules:"] as we are attempting to build a sam
    # database as opposed to start it here.
    tmpdb = Ldb(url=dburl,
                session_info=system_session(),
                lp=lp,
                options=["modules:"])

    tmpdb.transaction_start()
    try:
        data = read_and_sub_file(ldif_file, None)
        tmpdb.add_ldif(data, None)
        if forced_local_dsa:
            tmpdb.modify_ldif("""dn: @ROOTDSE
changetype: modify
replace: dsServiceName
dsServiceName: CN=NTDS Settings,%s
            """ % forced_local_dsa)

        tmpdb.add_ldif("""dn: @MODULES
@LIST: rootdse,extended_dn_in,extended_dn_out_ldb,objectguid
-
""")

    except Exception as estr:
        tmpdb.transaction_cancel()
        raise LdifError("Failed to import %s: %s" % (ldif_file, estr))

    tmpdb.transaction_commit()

    # We have an abbreviated list of options here because we have built
    # an abbreviated database.  We use the rootdse and extended-dn
    # modules only during this re-open
    samdb = SamDB(url=dburl, session_info=system_session(), lp=lp)
    return samdb
Example #24
0
    def start(self):
        from samba.provision import ProvisioningError
        self.slapd_command_escaped = "\'" + "\' \'".join(
            self.slapd_command) + "\'"
        ldap_backend_script = os.path.join(self.ldapdir,
                                           "ldap_backend_startup.sh")
        f = open(ldap_backend_script, 'w')
        try:
            f.write("#!/bin/sh\n" + self.slapd_command_escaped + " $@\n")
        finally:
            f.close()

        os.chmod(ldap_backend_script, 0o755)

        # 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)

        count = 0
        while self.slapd.poll() is None:
            # Wait until the socket appears
            try:
                time.sleep(1)
                ldapi_db = Ldb(self.ldap_uri,
                               lp=self.lp,
                               credentials=self.credentials)
                ldapi_db.search(base="",
                                scope=SCOPE_BASE,
                                expression="(objectClass=OpenLDAProotDSE)")
                # If we have got here, then we must have a valid connection to
                # the LDAP server!
                return
            except LdbError:
                count = count + 1

                if count > 15:
                    self.logger.error(
                        "Could not connect to slapd started with: %s" % "\'" +
                        "\' \'".join(self.slapd_provision_command) + "\'")
                    raise ProvisioningError(
                        "slapd never accepted a connection within 15 seconds of starting"
                    )

        self.logger.error("Could not start slapd with: %s" % "\'" +
                          "\' \'".join(self.slapd_provision_command) + "\'")
        raise ProvisioningError(
            "slapd died before we could make a connection to it")
Example #25
0
    def run(self, secret, sambaopts=None, credopts=None, versionopts=None):
        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp, fallback_machine=True)
        url = lp.get("secrets database")
        secretsdb = Ldb(url=url, session_info=system_session(),
            credentials=creds, lp=lp)
        
        result = secretsdb.search(attrs=["secret"], 
            expression="(&(objectclass=primaryDomain)(samaccountname=%s))" % secret)

        if len(result) != 1:
            raise CommandError("search returned %d records, expected 1" % len(result))

        self.outf.write("%s\n" % result[0]["secret"])
Example #26
0
    def test_tdb_copy(self):
        src_ldb_file = os.path.join(self.tempdir, "source.ldb")
        dst_ldb_file = os.path.join(self.tempdir, "destination.ldb")

        # Create LDB source file with some content
        src_ldb = Ldb(src_ldb_file)
        src_ldb.add({"dn": "f=dc", "b": "bla"})

        # Copy source file to destination file and check return status
        self.assertIsNone(tdb_copy(src_ldb_file, dst_ldb_file))

        # Load copied file as LDB object
        dst_ldb = Ldb(dst_ldb_file)

        # Copmare contents of files
        self.assertEqual(
            src_ldb.searchone(basedn=ldb.Dn(src_ldb, "f=dc"), attribute="b"),
            dst_ldb.searchone(basedn=ldb.Dn(dst_ldb, "f=dc"), attribute="b"))

        # Clean up
        del src_ldb
        del dst_ldb
        os.unlink(src_ldb_file)
        os.unlink(dst_ldb_file)
Example #27
0
    def post_setup(self):
        ldapi_db = Ldb(self.ldap_uri, credentials=self.credentials)

        # configure in-directory access control on Fedora DS via the aci
        # attribute (over a direct ldapi:// socket)
        aci = """(targetattr = "*") (version 3.0;acl "full access to all by samba-admin";allow (all)(userdn = "ldap:///CN=samba-admin,%s");)""" % self.sambadn

        m = ldb.Message()
        m["aci"] = ldb.MessageElement([aci], ldb.FLAG_MOD_REPLACE, "aci")

        for dnstring in (self.names.domaindn, self.names.configdn,
                         self.names.schemadn):
            m.dn = ldb.Dn(ldapi_db, dnstring)
            ldapi_db.modify(m)
        return LDAPBackendResult(self.credentials, self.slapd_command_escaped,
                                 self.ldapdir)
Example #28
0
 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 
     try:
         ldapi_db = Ldb(self.ldapi_uri)
         search_ol_rootdse = ldapi_db.search(base="", scope=SCOPE_BASE,
                                             expression="(objectClass=OpenLDAProotDSE)");
         try:
             f = open(self.paths.slapdpid, "r")
             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. ")
     
     except LdbError, e:
         pass
Example #29
0
    def join_finalise(ctx):
        '''finalise the join, mark us synchronised and setup secrets db'''

        print "Setting isSynchronized"
        m = ldb.Message()
        m.dn = ldb.Dn(ctx.samdb, '@ROOTDSE')
        m["isSynchronized"] = ldb.MessageElement("TRUE", ldb.FLAG_MOD_REPLACE, "isSynchronized")
        ctx.samdb.modify(m)

        secrets_ldb = Ldb(ctx.paths.secrets, session_info=system_session(), lp=ctx.lp)

        print "Setting up secrets database"
        secretsdb_self_join(secrets_ldb, domain=ctx.domain_name,
                            realm=ctx.realm,
                            dnsdomain=ctx.dnsdomain,
                            netbiosname=ctx.myname,
                            domainsid=security.dom_sid(ctx.domsid),
                            machinepass=ctx.acct_pass,
                            secure_channel_type=ctx.secure_channel_type,
                            key_version_number=ctx.key_version_number)
Example #30
0
    def start(self):
        self.slapd_command_escaped = "\'" + "\' \'".join(self.slapd_command) + "\'"
        open(self.paths.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)
    
        while self.slapd.poll() is None:
            # Wait until the socket appears
            try:
                ldapi_db = Ldb(self.ldapi_uri, lp=self.lp, credentials=self.credentials)
                search_ol_rootdse = ldapi_db.search(base="", scope=SCOPE_BASE,
                                                    expression="(objectClass=OpenLDAProotDSE)")
                # If we have got here, then we must have a valid connection to the LDAP server!
                return
            except LdbError, e:
                time.sleep(1)
                pass