def create_samdb_copy(samdb, logger, paths, names, domainsid, domainguid): """Create a copy of samdb and give write permissions to named for dns partitions """ private_dir = paths.private_dir samldb_dir = os.path.join(private_dir, "sam.ldb.d") dns_dir = os.path.dirname(paths.dns) dns_samldb_dir = os.path.join(dns_dir, "sam.ldb.d") # Find the partitions and corresponding filenames partfile = {} res = samdb.search(base="@PARTITION", scope=ldb.SCOPE_BASE, attrs=["partition", "backendStore"]) for tmp in res[0]["partition"]: (nc, fname) = tmp.split(':') partfile[nc.upper()] = fname backend_store = get_default_backend_store() if "backendStore" in res[0]: backend_store = res[0]["backendStore"][0] # Create empty domain partition domaindn = names.domaindn.upper() domainpart_file = os.path.join(dns_dir, partfile[domaindn]) try: os.mkdir(dns_samldb_dir) open(domainpart_file, 'w').close() # Fill the basedn and @OPTION records in domain partition dom_url = "%s://%s" % (backend_store, domainpart_file) dom_ldb = samba.Ldb(dom_url) # We need the dummy main-domain DB to have the correct @INDEXLIST index_res = samdb.search(base="@INDEXLIST", scope=ldb.SCOPE_BASE) dom_ldb.add(index_res[0]) domainguid_line = "objectGUID: %s\n-" % domainguid descr = b64encode(get_domain_descriptor(domainsid)).decode('utf8') setup_add_ldif(dom_ldb, setup_path("provision_basedn.ldif"), { "DOMAINDN" : names.domaindn, "DOMAINGUID" : domainguid_line, "DOMAINSID" : str(domainsid), "DESCRIPTOR" : descr}) setup_add_ldif(dom_ldb, setup_path("provision_basedn_options.ldif"), None) except: logger.error( "Failed to setup database for BIND, AD based DNS cannot be used") raise # This line is critical to the security of the whole scheme. # We assume there is no secret data in the (to be left out of # date and essentially read-only) config, schema and metadata partitions. # # Only the stub of the domain partition is created above. # # That way, things like the krbtgt key do not leak. del partfile[domaindn] # Link dns partitions and metadata domainzonedn = "DC=DOMAINDNSZONES,%s" % names.domaindn.upper() forestzonedn = "DC=FORESTDNSZONES,%s" % names.rootdn.upper() domainzone_file = partfile[domainzonedn] forestzone_file = partfile.get(forestzonedn) metadata_file = "metadata.tdb" try: os.link(os.path.join(samldb_dir, metadata_file), os.path.join(dns_samldb_dir, metadata_file)) os.link(os.path.join(private_dir, domainzone_file), os.path.join(dns_dir, domainzone_file)) if forestzone_file: os.link(os.path.join(private_dir, forestzone_file), os.path.join(dns_dir, forestzone_file)) except OSError: logger.error( "Failed to setup database for BIND, AD based DNS cannot be used") raise del partfile[domainzonedn] if forestzone_file: del partfile[forestzonedn] # Copy root, config, schema partitions (and any other if any) # Since samdb is open in the current process, copy them in a child process try: tdb_copy(os.path.join(private_dir, "sam.ldb"), os.path.join(dns_dir, "sam.ldb")) for nc in partfile: pfile = partfile[nc] if backend_store == "mdb": mdb_copy(os.path.join(private_dir, pfile), os.path.join(dns_dir, pfile)) else: tdb_copy(os.path.join(private_dir, pfile), os.path.join(dns_dir, pfile)) except: logger.error( "Failed to setup database for BIND, AD based DNS cannot be used") raise # Give bind read/write permissions dns partitions if paths.bind_gid is not None: try: for dirname, dirs, files in os.walk(dns_dir): for d in dirs: dpath = os.path.join(dirname, d) os.chown(dpath, -1, paths.bind_gid) os.chmod(dpath, 0o770) for f in files: if f.endswith(('.ldb', '.tdb', 'ldb-lock')): fpath = os.path.join(dirname, f) os.chown(fpath, -1, paths.bind_gid) os.chmod(fpath, 0o660) except OSError: if not os.environ.has_key('SAMBA_SELFTEST'): logger.error( "Failed to set permissions to sam.ldb* files, fix manually") else: if not os.environ.has_key('SAMBA_SELFTEST'): logger.warning("""Unable to find group id for BIND, set permissions to sam.ldb* files manually""")
def offline_mdb_copy(self, path): mdb_copy(path, path + self.backup_ext)
def create_samdb_copy(samdb, logger, paths, names, domainsid, domainguid): """Create a copy of samdb and give write permissions to named for dns partitions """ private_dir = paths.private_dir samldb_dir = os.path.join(private_dir, "sam.ldb.d") dns_dir = os.path.dirname(paths.dns) dns_samldb_dir = os.path.join(dns_dir, "sam.ldb.d") # Find the partitions and corresponding filenames partfile = {} res = samdb.search(base="@PARTITION", scope=ldb.SCOPE_BASE, attrs=["partition", "backendStore"]) for tmp in res[0]["partition"]: (nc, fname) = str(tmp).split(':') partfile[nc.upper()] = fname backend_store = get_default_backend_store() if "backendStore" in res[0]: backend_store = str(res[0]["backendStore"][0]) # Create empty domain partition domaindn = names.domaindn.upper() domainpart_file = os.path.join(dns_dir, partfile[domaindn]) try: os.mkdir(dns_samldb_dir) open(domainpart_file, 'w').close() # Fill the basedn and @OPTION records in domain partition dom_url = "%s://%s" % (backend_store, domainpart_file) dom_ldb = samba.Ldb(dom_url) # We need the dummy main-domain DB to have the correct @INDEXLIST index_res = samdb.search(base="@INDEXLIST", scope=ldb.SCOPE_BASE) dom_ldb.add(index_res[0]) domainguid_line = "objectGUID: %s\n-" % domainguid descr = b64encode(get_domain_descriptor(domainsid)).decode('utf8') setup_add_ldif(dom_ldb, setup_path("provision_basedn.ldif"), { "DOMAINDN": names.domaindn, "DOMAINGUID": domainguid_line, "DOMAINSID": str(domainsid), "DESCRIPTOR": descr}) setup_add_ldif(dom_ldb, setup_path("provision_basedn_options.ldif"), None) except: logger.error( "Failed to setup database for BIND, AD based DNS cannot be used") raise # This line is critical to the security of the whole scheme. # We assume there is no secret data in the (to be left out of # date and essentially read-only) config, schema and metadata partitions. # # Only the stub of the domain partition is created above. # # That way, things like the krbtgt key do not leak. del partfile[domaindn] # Link dns partitions and metadata domainzonedn = "DC=DOMAINDNSZONES,%s" % names.domaindn.upper() forestzonedn = "DC=FORESTDNSZONES,%s" % names.rootdn.upper() domainzone_file = partfile[domainzonedn] forestzone_file = partfile.get(forestzonedn) metadata_file = "metadata.tdb" try: os.link(os.path.join(samldb_dir, metadata_file), os.path.join(dns_samldb_dir, metadata_file)) os.link(os.path.join(private_dir, domainzone_file), os.path.join(dns_dir, domainzone_file)) if backend_store == "mdb": # If the file is an lmdb data file need to link the # lock file as well os.link(os.path.join(private_dir, domainzone_file + "-lock"), os.path.join(dns_dir, domainzone_file + "-lock")) if forestzone_file: os.link(os.path.join(private_dir, forestzone_file), os.path.join(dns_dir, forestzone_file)) if backend_store == "mdb": # If the database file is an lmdb data file need to link the # lock file as well os.link(os.path.join(private_dir, forestzone_file + "-lock"), os.path.join(dns_dir, forestzone_file + "-lock")) except OSError: logger.error( "Failed to setup database for BIND, AD based DNS cannot be used") raise del partfile[domainzonedn] if forestzone_file: del partfile[forestzonedn] # Copy root, config, schema partitions (and any other if any) # Since samdb is open in the current process, copy them in a child process try: tdb_copy(os.path.join(private_dir, "sam.ldb"), os.path.join(dns_dir, "sam.ldb")) for nc in partfile: pfile = partfile[nc] if backend_store == "mdb": mdb_copy(os.path.join(private_dir, pfile), os.path.join(dns_dir, pfile)) else: tdb_copy(os.path.join(private_dir, pfile), os.path.join(dns_dir, pfile)) except: logger.error( "Failed to setup database for BIND, AD based DNS cannot be used") raise # Give bind read/write permissions dns partitions if paths.bind_gid is not None: try: for dirname, dirs, files in os.walk(dns_dir): for d in dirs: dpath = os.path.join(dirname, d) os.chown(dpath, -1, paths.bind_gid) os.chmod(dpath, 0o770) for f in files: if f.endswith(('.ldb', '.tdb', 'ldb-lock')): fpath = os.path.join(dirname, f) os.chown(fpath, -1, paths.bind_gid) os.chmod(fpath, 0o660) except OSError: if 'SAMBA_SELFTEST' not in os.environ: logger.error( "Failed to set permissions to sam.ldb* files, fix manually") else: if 'SAMBA_SELFTEST' not in os.environ: logger.warning("""Unable to find group id for BIND, set permissions to sam.ldb* files manually""")