示例#1
0
def check_refresh_gpo_list(dc_hostname, lp, creds, gpos):
    conn = smb.SMB(dc_hostname, 'sysvol', lp=lp, creds=creds, sign=True)
    cache_path = lp.cache_path('gpo_cache')
    for gpo in gpos:
        if not gpo.file_sys_path:
            continue
        cache_gpo_dir(conn, cache_path, check_safe_path(gpo.file_sys_path))
示例#2
0
    def fetch_dir(self, unc, dst, recursive=True):
        [dom_name, service, src] = parse_unc(unc)
        debug("UNC: %s" % ([dom_name, service, src]))
        conn = smb.SMB(self.finddc(realm=dom_name), service, lp=self.lp, creds=self.creds)

        if not os.path.isdir(dst):
            os.mkdir(dst)

        r_dirs = [ src ]
        l_dirs = [ dst ]
        attr_flags = smb.FILE_ATTRIBUTE_SYSTEM | \
                     smb.FILE_ATTRIBUTE_DIRECTORY | \
                     smb.FILE_ATTRIBUTE_ARCHIVE | \
                     smb.FILE_ATTRIBUTE_HIDDEN

        while r_dirs:
            r_dir = r_dirs.pop()
            l_dir = l_dirs.pop()
            dirlist = conn.list(r_dir, attribs=attr_flags)
            for e in dirlist:
                r_name = "%s\\%s" % (r_dir, e['name'])
                l_name = os.path.join(l_dir, e['name'])

                if e['attrib'] & smb.FILE_ATTRIBUTE_DIRECTORY:
                    r_dirs.append(r_name)
                    l_dirs.append(l_name)
                    os.mkdir(l_name)
                else:
                    data = conn.loadfile(r_name)
                    open(l_name, 'w').write(data)
示例#3
0
文件: gpo.py 项目: lausser/samba
    def run(self,
            gpo,
            H=None,
            sambaopts=None,
            credopts=None,
            versionopts=None):

        self.lp = sambaopts.get_loadparm()
        self.creds = credopts.get_credentials(self.lp, fallback_machine=True)

        # We need to know writable DC to setup SMB connection
        if H and H.startswith('ldap://'):
            dc_hostname = H[7:]
            self.url = H
        else:
            dc_hostname = netcmd_finddc(self.lp, self.creds)
            self.url = dc_url(self.lp, self.creds, dc=dc_hostname)

        samdb_connect(self)

        # Check if valid GPO
        try:
            msg = get_gpo_info(self.samdb, gpo=gpo)[0]
            unc_path = msg['gPCFileSysPath'][0]
        except Exception:
            raise CommandError("GPO '%s' does not exist" % gpo)

        # Connect to DC over SMB
        [dom_name, service, sharepath] = parse_unc(unc_path)
        try:
            conn = smb.SMB(dc_hostname, service, lp=self.lp, creds=self.creds)
        except Exception, e:
            raise CommandError(
                "Error connecting to '%s' using SMB" % dc_hostname, e)
示例#4
0
    def run(self, sambaopts=None, credopts=None, server=None, targetdir=None,
            no_secrets=False, backend_store=None):
        logger = self.get_logger()
        logger.setLevel(logging.DEBUG)

        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp)

        # Make sure we have all the required args.
        if server is None:
            raise CommandError('Server required')

        check_targetdir(logger, targetdir)

        tmpdir = tempfile.mkdtemp(dir=targetdir)

        # Run a clone join on the remote
        include_secrets = not no_secrets
        ctx = join_clone(logger=logger, creds=creds, lp=lp,
                         include_secrets=include_secrets, server=server,
                         dns_backend='SAMBA_INTERNAL', targetdir=tmpdir,
                         backend_store=backend_store)

        # get the paths used for the clone, then drop the old samdb connection
        paths = ctx.paths
        del ctx

        # Get a free RID to use as the new DC's SID (when it gets restored)
        remote_sam = SamDB(url='ldap://' + server, credentials=creds,
                           session_info=system_session(), lp=lp)
        new_sid = get_sid_for_restore(remote_sam)
        realm = remote_sam.domain_dns_name()

        # Grab the remote DC's sysvol files and bundle them into a tar file
        sysvol_tar = os.path.join(tmpdir, 'sysvol.tar.gz')
        smb_conn = smb.SMB(server, "sysvol", lp=lp, creds=creds, sign=True)
        backup_online(smb_conn, sysvol_tar, remote_sam.get_domain_sid())

        # remove the default sysvol files created by the clone (we want to
        # make sure we restore the sysvol.tar.gz files instead)
        shutil.rmtree(paths.sysvol)

        # Edit the downloaded sam.ldb to mark it as a backup
        samdb = SamDB(url=paths.samdb, session_info=system_session(), lp=lp)
        time_str = get_timestamp()
        add_backup_marker(samdb, "backupDate", time_str)
        add_backup_marker(samdb, "sidForRestore", new_sid)
        add_backup_marker(samdb, "backupType", "online")

        # ensure the admin user always has a password set (same as provision)
        if no_secrets:
            set_admin_password(logger, samdb)

        # Add everything in the tmpdir to the backup tar file
        backup_file = backup_filepath(targetdir, realm, time_str)
        create_log_file(tmpdir, lp, "online", server, include_secrets)
        create_backup_tar(logger, tmpdir, backup_file)

        shutil.rmtree(tmpdir)
示例#5
0
 def fetch(self, src, dst):
     [host, share, fname] = parse_unc(src)
     debug("UNC: %s" % ([host, share, fname]))
     conn = smb.SMB(str(host), share, lp=self.lp, creds=self.creds)
     dst_name = "%s/%s" % (dst, fname)
     debug("fetch %s from %s to %s" % (fname, host, dst_name))
     data = conn.loadfile(fname)
     open(dst_name, 'w').write(data)
示例#6
0
 def _get_smb_connection(self, service='SysVol'):
     # Connect to SMB using kerberos
     parm = param.LoadParm()
     creds = Credentials()
     creds.set_kerberos_state(MUST_USE_KERBEROS)
     creds.guess(parm)
     conn = smb.SMB(self._get_server_name(), service, lp=parm, creds=creds)
     return conn
示例#7
0
    def run(self, sambaopts=None, credopts=None, server=None, targetdir=None):
        logger = self.get_logger()
        logger.setLevel(logging.DEBUG)

        # Make sure we have all the required args.
        check_online_backup_args(logger, credopts, server, targetdir)

        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp)

        if not os.path.exists(targetdir):
            logger.info('Creating targetdir %s...' % targetdir)
            os.makedirs(targetdir)

        tmpdir = tempfile.mkdtemp(dir=targetdir)

        # Run a clone join on the remote
        ctx = join_clone(logger=logger,
                         creds=creds,
                         lp=lp,
                         include_secrets=True,
                         dns_backend='SAMBA_INTERNAL',
                         server=server,
                         targetdir=tmpdir)

        # get the paths used for the clone, then drop the old samdb connection
        paths = ctx.paths
        del ctx

        # Get a free RID to use as the new DC's SID (when it gets restored)
        remote_sam = SamDB(url='ldap://' + server,
                           credentials=creds,
                           session_info=system_session(),
                           lp=lp)
        new_sid = get_sid_for_restore(remote_sam)
        realm = remote_sam.domain_dns_name()

        # Grab the remote DC's sysvol files and bundle them into a tar file
        sysvol_tar = os.path.join(tmpdir, 'sysvol.tar.gz')
        smb_conn = smb.SMB(server, "sysvol", lp=lp, creds=creds)
        backup_online(smb_conn, sysvol_tar, remote_sam.get_domain_sid())

        # remove the default sysvol files created by the clone (we want to
        # make sure we restore the sysvol.tar.gz files instead)
        shutil.rmtree(paths.sysvol)

        # Edit the downloaded sam.ldb to mark it as a backup
        samdb = SamDB(url=paths.samdb, session_info=system_session(), lp=lp)
        time_str = get_timestamp()
        add_backup_marker(samdb, "backupDate", time_str)
        add_backup_marker(samdb, "sidForRestore", new_sid)

        # Add everything in the tmpdir to the backup tar file
        backup_file = backup_filepath(targetdir, realm, time_str)
        create_backup_tar(logger, tmpdir, backup_file)

        shutil.rmtree(tmpdir)
示例#8
0
文件: smb.py 项目: ulkuderner/samba
 def setUp(self):
     super(SMBTests, self).setUp()
     self.server = os.environ["SERVER"]
     creds = self.insta_creds(template=self.get_credentials())
     self.conn = smb.SMB(self.server,
                         "sysvol",
                         lp=self.get_loadparm(),
                         creds=creds)
     self.conn.mkdir(test_dir)
示例#9
0
    def setUp(self):
        super(NtaclsBackupRestoreTests, self).setUp()

        self.server = os.environ["SERVER"]  # addc
        samdb_url = 'ldap://' + self.server

        self.service = 'test1'  # service/share to test
        # root path for service
        self.service_root = os.path.join(os.environ["LOCAL_PATH"],
                                         self.service)

        self.smb_conf_path = os.environ['SMB_CONF_PATH']
        self.dom_sid = security.dom_sid(os.environ['DOMSID'])

        self.creds = self.insta_creds(template=self.get_credentials())

        # helper will load conf into lp, that's how smbd can find services.
        self.ntacls_helper = ntacls.NtaclsHelper(self.service,
                                                 self.smb_conf_path,
                                                 self.dom_sid)

        self.lp = self.ntacls_helper.lp

        self.samdb_conn = samdb.SamDB(url=samdb_url,
                                      session_info=system_session(),
                                      credentials=self.creds,
                                      lp=self.lp)

        self.smb_conn = smb.SMB(self.server,
                                self.service,
                                lp=self.lp,
                                creds=self.creds)

        self.smb_helper = ntacls.SMBHelper(self.smb_conn, self.dom_sid)

        self.tarfile_path = os.path.join(self.tempdir, 'ntacls-backup.tar.gz')

        # an example file tree
        self.tree = {
            'file0.txt': b'test file0',
            'dir1': {
                'file1.txt': b'test file1',
                'dir2': {}  # an empty dir in dir
            },
        }

        self._delete_tarfile()
        self.smb_helper.delete_tree()

        self.smb_helper.create_tree(self.tree)
        self._check_tree()
        # keep a copy of ntacls after tree just created
        self.original_ntacls = self.smb_helper.get_ntacls()
示例#10
0
文件: gpo.py 项目: cpatulea/samba
class cmd_fetch(Command):
    """Download a GPO"""

    synopsis = "%prog <gpo> [options]"

    takes_optiongroups = {
        "sambaopts": options.SambaOptions,
        "versionopts": options.VersionOptions,
        "credopts": options.CredentialsOptions,
    }

    takes_args = ['gpo']

    takes_options = [
        Option("-H", help="LDB URL for database or target server", type=str),
        Option("--tmpdir",
               help="Temporary directory for copying policy files",
               type=str)
    ]

    def run(self,
            gpo,
            H=None,
            tmpdir=None,
            sambaopts=None,
            credopts=None,
            versionopts=None):

        self.lp = sambaopts.get_loadparm()
        self.creds = credopts.get_credentials(self.lp, fallback_machine=True)

        dc_hostname = netcmd_finddc(self.lp, self.creds)
        self.url = dc_url(self.lp, self.creds, H, dc=dc_hostname)

        samdb_connect(self)
        try:
            msg = get_gpo_info(self.samdb, gpo)[0]
        except Exception, e:
            raise CommandError("GPO %s does not exist" % gpo)

        # verify UNC path
        unc = msg['gPCFileSysPath'][0]
        try:
            [dom_name, service, sharepath] = parse_unc(unc)
        except ValueError:
            raise CommandError("Invalid GPO path (%s)" % unc)

        # SMB connect to DC
        try:
            conn = smb.SMB(dc_hostname, service, lp=self.lp, creds=self.creds)
        except Exception, e:
            raise CommandError(
                "Error connecting to '%s' using SMB" % dc_hostname, e)
示例#11
0
文件: gpo.py 项目: lausser/samba
    def run(self, H=None, sambaopts=None, credopts=None, versionopts=None):

        self.lp = sambaopts.get_loadparm()
        self.creds = credopts.get_credentials(self.lp, fallback_machine=True)

        self.url = dc_url(self.lp, self.creds, H)

        # We need to know writable DC to setup SMB connection
        if H and H.startswith('ldap://'):
            dc_hostname = H[7:]
            self.url = H
        else:
            dc_hostname = netcmd_finddc(self.lp, self.creds)
            self.url = dc_url(self.lp, self.creds, dc=dc_hostname)

        samdb_connect(self)

        msg = get_gpo_info(self.samdb, None)

        for m in msg:
            # verify UNC path
            unc = m['gPCFileSysPath'][0]
            try:
                [dom_name, service, sharepath] = parse_unc(unc)
            except ValueError:
                raise CommandError("Invalid GPO path (%s)" % unc)

            # SMB connect to DC
            try:
                conn = smb.SMB(dc_hostname,
                               service,
                               lp=self.lp,
                               creds=self.creds)
            except Exception:
                raise CommandError("Error connecting to '%s' using SMB" %
                                   dc_hostname)

            fs_sd = conn.get_acl(
                sharepath, security.SECINFO_OWNER | security.SECINFO_GROUP
                | security.SECINFO_DACL, security.SEC_FLAG_MAXIMUM_ALLOWED)

            ds_sd_ndr = m['nTSecurityDescriptor'][0]
            ds_sd = ndr_unpack(security.descriptor, ds_sd_ndr).as_sddl()

            # Create a file system security descriptor
            domain_sid = security.dom_sid(self.samdb.get_domain_sid())
            expected_fs_sddl = dsacl2fsacl(ds_sd, domain_sid)

            if (fs_sd.as_sddl(domain_sid) != expected_fs_sddl):
                raise CommandError(
                    "Invalid GPO ACL %s on path (%s), should be %s" %
                    (fs_sd.as_sddl(domain_sid), sharepath, expected_fs_sddl))
示例#12
0
 def __init__(self, lp, creds, gpo_path):
     GPConnection.__init__(self, lp, creds)
     path_parts = [n for n in gpo_path.split('\\') if n]
     self.path_start = '\\\\' + '\\'.join(path_parts[:2])
     self.path = '\\'.join(path_parts[2:])
     self.name = path_parts[-1]
     self.realm_dn = self.realm_to_dn(self.realm)
     self.gpo_dn = 'CN=%s,CN=Policies,CN=System,%s' % (self.name,
                                                       self.realm_dn)
     try:
         self.conn = smb.SMB(path_parts[0],
                             path_parts[1],
                             lp=self.lp,
                             creds=self.creds)
     except:
         self.conn = None
示例#13
0
        else:
            # Download the file
            fname = os.path.join(local_path, f['name'])
            rname = win_path_join(remote_path, f['name'])
            open(fname, 'w').write(conn.loadfile(rname))
            os.utime(fname, (time(), f['mtime']))

if __name__ == '__main__':
    parse = argparse.ArgumentParser(description='Sysvol replication tool')
    parse.add_argument('server', help='FQDN of server to replicate sysvol from')
    args = parse.parse_args()

    parser = optparse.OptionParser()
    lp = getopt.SambaOptions(parser).get_loadparm()
    creds = getopt.CredentialsOptions(parser).get_credentials(lp, fallback_machine=True)
    conn = smb.SMB(args.server, 'sysvol', lp=lp, creds=creds)

    gpo_versions = '%s/%s' % (lp.get('path', 'sysvol'), 'versions.tdb')
    if os.path.isfile(gpo_versions):
        vers_f = tdb.open(gpo_versions)
    else:
        vers_f = tdb.Tdb(gpo_versions, 0, tdb.DEFAULT, os.O_CREAT|os.O_RDWR)

    gpo_path = win_path_join(lp.get('realm').lower(), 'Policies')
    gpos = [x['name'] for x in conn.list(gpo_path)]
    for gpo in gpos:
        s_gpo_path = win_path_join(gpo_path, gpo)
        # Check if the version has changed
        fname = win_path_join(s_gpo_path, 'GPT.INI')
        data = conn.loadfile(fname)
        gpt_ini = ConfigParser()
示例#14
0
    def run(self,
            new_domain_name,
            new_dns_realm,
            sambaopts=None,
            credopts=None,
            server=None,
            targetdir=None,
            keep_dns_realm=False,
            no_secrets=False):
        logger = self.get_logger()
        logger.setLevel(logging.INFO)

        # Make sure we have all the required args.
        check_online_backup_args(logger, credopts, server, targetdir)
        delete_old_dns = not keep_dns_realm

        new_dns_realm = new_dns_realm.lower()
        new_domain_name = new_domain_name.upper()

        new_base_dn = samba.dn_from_dns_name(new_dns_realm)
        logger.info("New realm for backed up domain: %s" % new_dns_realm)
        logger.info("New base DN for backed up domain: %s" % new_base_dn)
        logger.info("New domain NetBIOS name: %s" % new_domain_name)

        tmpdir = tempfile.mkdtemp(dir=targetdir)

        # setup a join-context for cloning the remote server
        lp = sambaopts.get_loadparm()
        creds = credopts.get_credentials(lp)
        include_secrets = not no_secrets
        ctx = DCCloneAndRenameContext(new_base_dn,
                                      new_domain_name,
                                      new_dns_realm,
                                      logger=logger,
                                      creds=creds,
                                      lp=lp,
                                      include_secrets=include_secrets,
                                      dns_backend='SAMBA_INTERNAL',
                                      server=server,
                                      targetdir=tmpdir)

        # sanity-check we're not "renaming" the domain to the same values
        old_domain = ctx.domain_name
        if old_domain == new_domain_name:
            shutil.rmtree(tmpdir)
            raise CommandError("Cannot use the current domain NetBIOS name.")

        old_realm = ctx.realm
        if old_realm == new_dns_realm:
            shutil.rmtree(tmpdir)
            raise CommandError("Cannot use the current domain DNS realm.")

        # do the clone/rename
        ctx.do_join()

        # get the paths used for the clone, then drop the old samdb connection
        del ctx.local_samdb
        paths = ctx.paths

        # get a free RID to use as the new DC's SID (when it gets restored)
        remote_sam = SamDB(url='ldap://' + server,
                           credentials=creds,
                           session_info=system_session(),
                           lp=lp)
        new_sid = get_sid_for_restore(remote_sam)

        # Grab the remote DC's sysvol files and bundle them into a tar file.
        # Note we end up with 2 sysvol dirs - the original domain's files (that
        # use the old realm) backed here, as well as default files generated
        # for the new realm as part of the clone/join.
        sysvol_tar = os.path.join(tmpdir, 'sysvol.tar.gz')
        smb_conn = smb.SMB(server, "sysvol", lp=lp, creds=creds)
        backup_online(smb_conn, sysvol_tar, remote_sam.get_domain_sid())

        # connect to the local DB (making sure we use the new/renamed config)
        lp.load(paths.smbconf)
        samdb = SamDB(url=paths.samdb, session_info=system_session(), lp=lp)

        # Edit the cloned sam.ldb to mark it as a backup
        time_str = get_timestamp()
        add_backup_marker(samdb, "backupDate", time_str)
        add_backup_marker(samdb, "sidForRestore", new_sid)
        add_backup_marker(samdb, "backupRename", old_realm)

        # fix up the DNS objects that are using the old dnsRoot value
        self.update_dns_root(logger, samdb, old_realm, delete_old_dns)

        # update the netBIOS name and the Partition object for the domain
        self.rename_domain_partition(logger, samdb, new_domain_name)

        if delete_old_dns:
            self.delete_old_dns_zones(logger, samdb, old_realm)

        logger.info("Fixing DN attributes after rename...")
        self.fix_old_dn_attributes(samdb)

        # ensure the admin user always has a password set (same as provision)
        if no_secrets:
            set_admin_password(logger, samdb, creds.get_username())

        # Add everything in the tmpdir to the backup tar file
        backup_file = backup_filepath(targetdir, new_dns_realm, time_str)
        create_log_file(
            tmpdir, lp, "rename", server, include_secrets,
            "Original domain %s (NetBIOS), %s (DNS realm)" %
            (old_domain, old_realm))
        create_backup_tar(logger, tmpdir, backup_file)

        shutil.rmtree(tmpdir)
示例#15
0
文件: gpo.py 项目: lausser/samba
class cmd_create(Command):
    """Create an empty GPO."""

    synopsis = "%prog <displayname> [options]"

    takes_optiongroups = {
        "sambaopts": options.SambaOptions,
        "versionopts": options.VersionOptions,
        "credopts": options.CredentialsOptions,
    }

    takes_args = ['displayname']

    takes_options = [
        Option("-H", help="LDB URL for database or target server", type=str),
        Option("--tmpdir",
               help="Temporary directory for copying policy files",
               type=str)
    ]

    def run(self,
            displayname,
            H=None,
            tmpdir=None,
            sambaopts=None,
            credopts=None,
            versionopts=None):

        self.lp = sambaopts.get_loadparm()
        self.creds = credopts.get_credentials(self.lp, fallback_machine=True)

        net = Net(creds=self.creds, lp=self.lp)

        # We need to know writable DC to setup SMB connection
        if H and H.startswith('ldap://'):
            dc_hostname = H[7:]
            self.url = H
            flags = (nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_DS
                     | nbt.NBT_SERVER_WRITABLE)
            cldap_ret = net.finddc(address=dc_hostname, flags=flags)
        else:
            flags = (nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_DS
                     | nbt.NBT_SERVER_WRITABLE)
            cldap_ret = net.finddc(domain=self.lp.get('realm'), flags=flags)
            dc_hostname = cldap_ret.pdc_dns_name
            self.url = dc_url(self.lp, self.creds, dc=dc_hostname)

        samdb_connect(self)

        msg = get_gpo_info(self.samdb, displayname=displayname)
        if msg.count > 0:
            raise CommandError("A GPO already existing with name '%s'" %
                               displayname)

        # Create new GUID
        guid = str(uuid.uuid4())
        gpo = "{%s}" % guid.upper()
        realm = cldap_ret.dns_domain
        unc_path = "\\\\%s\\sysvol\\%s\\Policies\\%s" % (realm, realm, gpo)

        # Create GPT
        if tmpdir is None:
            tmpdir = "/tmp"
        if not os.path.isdir(tmpdir):
            raise CommandError("Temporary directory '%s' does not exist" %
                               tmpdir)

        localdir = os.path.join(tmpdir, "policy")
        if not os.path.isdir(localdir):
            os.mkdir(localdir)

        gpodir = os.path.join(localdir, gpo)
        if os.path.isdir(gpodir):
            raise CommandError(
                "GPO directory '%s' already exists, refusing to overwrite" %
                gpodir)

        try:
            os.mkdir(gpodir)
            os.mkdir(os.path.join(gpodir, "Machine"))
            os.mkdir(os.path.join(gpodir, "User"))
            gpt_contents = "[General]\r\nVersion=0\r\n"
            file(os.path.join(gpodir, "GPT.INI"), "w").write(gpt_contents)
        except Exception, e:
            raise CommandError("Error Creating GPO files", e)

        # Connect to DC over SMB
        [dom_name, service, sharepath] = parse_unc(unc_path)
        try:
            conn = smb.SMB(dc_hostname, service, lp=self.lp, creds=self.creds)
        except Exception, e:
            raise CommandError(
                "Error connecting to '%s' using SMB" % dc_hostname, e)
示例#16
0
文件: gpo.py 项目: lausser/samba
    def run(self,
            gpo,
            H=None,
            tmpdir=None,
            sambaopts=None,
            credopts=None,
            versionopts=None):

        self.lp = sambaopts.get_loadparm()
        self.creds = credopts.get_credentials(self.lp, fallback_machine=True)

        # We need to know writable DC to setup SMB connection
        if H and H.startswith('ldap://'):
            dc_hostname = H[7:]
            self.url = H
        else:
            dc_hostname = netcmd_finddc(self.lp, self.creds)
            self.url = dc_url(self.lp, self.creds, dc=dc_hostname)

        samdb_connect(self)
        try:
            msg = get_gpo_info(self.samdb, gpo)[0]
        except Exception:
            raise CommandError("GPO '%s' does not exist" % gpo)

        # verify UNC path
        unc = msg['gPCFileSysPath'][0]
        try:
            [dom_name, service, sharepath] = parse_unc(unc)
        except ValueError:
            raise CommandError("Invalid GPO path (%s)" % unc)

        # SMB connect to DC
        try:
            conn = smb.SMB(dc_hostname, service, lp=self.lp, creds=self.creds)
        except Exception:
            raise CommandError("Error connecting to '%s' using SMB" %
                               dc_hostname)

        # Copy GPT
        if tmpdir is None:
            tmpdir = "/tmp"
        if not os.path.isdir(tmpdir):
            raise CommandError("Temoprary directory '%s' does not exist" %
                               tmpdir)

        localdir = os.path.join(tmpdir, "policy")
        if not os.path.isdir(localdir):
            os.mkdir(localdir)

        gpodir = os.path.join(localdir, gpo)
        if os.path.isdir(gpodir):
            raise CommandError(
                "GPO directory '%s' already exists, refusing to overwrite" %
                gpodir)

        try:
            os.mkdir(gpodir)
            copy_directory_remote_to_local(conn, sharepath, gpodir)
        except Exception, e:
            # FIXME: Catch more specific exception
            raise CommandError("Error copying GPO from DC", e)
示例#17
0
文件: gpo.py 项目: UUUUnotfound/samba
    def run(self,
            displayname,
            H=None,
            tmpdir=None,
            sambaopts=None,
            credopts=None,
            versionopts=None):

        self.lp = sambaopts.get_loadparm()
        self.creds = credopts.get_credentials(self.lp, fallback_machine=True)

        net = Net(creds=self.creds, lp=self.lp)

        # We need to know writable DC to setup SMB connection
        if H and H.startswith('ldap://'):
            dc_hostname = H[7:]
            self.url = H
            flags = (nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_DS
                     | nbt.NBT_SERVER_WRITABLE)
            cldap_ret = net.finddc(address=dc_hostname, flags=flags)
        else:
            flags = (nbt.NBT_SERVER_LDAP | nbt.NBT_SERVER_DS
                     | nbt.NBT_SERVER_WRITABLE)
            cldap_ret = net.finddc(domain=self.lp.get('realm'), flags=flags)
            dc_hostname = cldap_ret.pdc_dns_name
            self.url = dc_url(self.lp, self.creds, dc=dc_hostname)

        samdb_connect(self)

        msg = get_gpo_info(self.samdb, displayname=displayname)
        if msg.count > 0:
            raise CommandError("A GPO already existing with name '%s'" %
                               displayname)

        # Create new GUID
        guid = str(uuid.uuid4())
        gpo = "{%s}" % guid.upper()
        realm = cldap_ret.dns_domain
        unc_path = "\\\\%s\\sysvol\\%s\\Policies\\%s" % (realm, realm, gpo)

        # Create GPT
        if tmpdir is None:
            tmpdir = "/tmp"
        if not os.path.isdir(tmpdir):
            raise CommandError("Temporary directory '%s' does not exist" %
                               tmpdir)

        localdir = os.path.join(tmpdir, "policy")
        if not os.path.isdir(localdir):
            os.mkdir(localdir)

        gpodir = os.path.join(localdir, gpo)
        if os.path.isdir(gpodir):
            raise CommandError(
                "GPO directory '%s' already exists, refusing to overwrite" %
                gpodir)

        try:
            os.mkdir(gpodir)
            os.mkdir(os.path.join(gpodir, "Machine"))
            os.mkdir(os.path.join(gpodir, "User"))
            gpt_contents = "[General]\r\nVersion=0\r\n"
            open(os.path.join(gpodir, "GPT.INI"), "w").write(gpt_contents)
        except Exception as e:
            raise CommandError("Error Creating GPO files", e)

        # Connect to DC over SMB
        [dom_name, service, sharepath] = parse_unc(unc_path)
        try:
            conn = smb.SMB(dc_hostname, service, lp=self.lp, creds=self.creds)
        except Exception as e:
            raise CommandError(
                "Error connecting to '%s' using SMB" % dc_hostname, e)

        self.samdb.transaction_start()
        try:
            # Add cn=<guid>
            gpo_dn = get_gpo_dn(self.samdb, gpo)

            m = ldb.Message()
            m.dn = gpo_dn
            m['a01'] = ldb.MessageElement("groupPolicyContainer",
                                          ldb.FLAG_MOD_ADD, "objectClass")
            self.samdb.add(m)

            # Add cn=User,cn=<guid>
            m = ldb.Message()
            m.dn = ldb.Dn(self.samdb, "CN=User,%s" % str(gpo_dn))
            m['a01'] = ldb.MessageElement("container", ldb.FLAG_MOD_ADD,
                                          "objectClass")
            self.samdb.add(m)

            # Add cn=Machine,cn=<guid>
            m = ldb.Message()
            m.dn = ldb.Dn(self.samdb, "CN=Machine,%s" % str(gpo_dn))
            m['a01'] = ldb.MessageElement("container", ldb.FLAG_MOD_ADD,
                                          "objectClass")
            self.samdb.add(m)

            # Get new security descriptor
            ds_sd_flags = (security.SECINFO_OWNER | security.SECINFO_GROUP
                           | security.SECINFO_DACL)
            msg = get_gpo_info(self.samdb, gpo=gpo, sd_flags=ds_sd_flags)[0]
            ds_sd_ndr = msg['nTSecurityDescriptor'][0]
            ds_sd = ndr_unpack(security.descriptor, ds_sd_ndr).as_sddl()

            # Create a file system security descriptor
            domain_sid = security.dom_sid(self.samdb.get_domain_sid())
            sddl = dsacl2fsacl(ds_sd, domain_sid)
            fs_sd = security.descriptor.from_sddl(sddl, domain_sid)

            # Copy GPO directory
            create_directory_hier(conn, sharepath)

            # Set ACL
            sio = (security.SECINFO_OWNER | security.SECINFO_GROUP
                   | security.SECINFO_DACL | security.SECINFO_PROTECTED_DACL)
            conn.set_acl(sharepath, fs_sd, sio)

            # Copy GPO files over SMB
            copy_directory_local_to_remote(conn, gpodir, sharepath)

            m = ldb.Message()
            m.dn = gpo_dn
            m['a02'] = ldb.MessageElement(displayname, ldb.FLAG_MOD_REPLACE,
                                          "displayName")
            m['a03'] = ldb.MessageElement(unc_path, ldb.FLAG_MOD_REPLACE,
                                          "gPCFileSysPath")
            m['a05'] = ldb.MessageElement("0", ldb.FLAG_MOD_REPLACE,
                                          "versionNumber")
            m['a07'] = ldb.MessageElement("2", ldb.FLAG_MOD_REPLACE,
                                          "gpcFunctionalityVersion")
            m['a04'] = ldb.MessageElement("0", ldb.FLAG_MOD_REPLACE, "flags")
            controls = ["permissive_modify:0"]
            self.samdb.modify(m, controls=controls)
        except Exception:
            self.samdb.transaction_cancel()
            raise
        else:
            self.samdb.transaction_commit()

        self.outf.write("GPO '%s' created as %s\n" % (displayname, gpo))
示例#18
0
文件: gpo.py 项目: UUUUnotfound/samba
    def run(self,
            gpo,
            H=None,
            sambaopts=None,
            credopts=None,
            versionopts=None):

        self.lp = sambaopts.get_loadparm()
        self.creds = credopts.get_credentials(self.lp, fallback_machine=True)

        # We need to know writable DC to setup SMB connection
        if H and H.startswith('ldap://'):
            dc_hostname = H[7:]
            self.url = H
        else:
            dc_hostname = netcmd_finddc(self.lp, self.creds)
            self.url = dc_url(self.lp, self.creds, dc=dc_hostname)

        samdb_connect(self)

        # Check if valid GPO
        try:
            msg = get_gpo_info(self.samdb, gpo=gpo)[0]
            unc_path = msg['gPCFileSysPath'][0]
        except Exception:
            raise CommandError("GPO '%s' does not exist" % gpo)

        # Connect to DC over SMB
        [dom_name, service, sharepath] = parse_unc(unc_path)
        try:
            conn = smb.SMB(dc_hostname, service, lp=self.lp, creds=self.creds)
        except Exception as e:
            raise CommandError(
                "Error connecting to '%s' using SMB" % dc_hostname, e)

        self.samdb.transaction_start()
        try:
            # Check for existing links
            msg = get_gpo_containers(self.samdb, gpo)

            if len(msg):
                self.outf.write("GPO %s is linked to containers\n" % gpo)
                for m in msg:
                    del_gpo_link(self.samdb, m['dn'], gpo)
                    self.outf.write("    Removed link from %s.\n" % m['dn'])

            # Remove LDAP entries
            gpo_dn = get_gpo_dn(self.samdb, gpo)
            self.samdb.delete(ldb.Dn(self.samdb, "CN=User,%s" % str(gpo_dn)))
            self.samdb.delete(ldb.Dn(self.samdb,
                                     "CN=Machine,%s" % str(gpo_dn)))
            self.samdb.delete(gpo_dn)

            # Remove GPO files
            conn.deltree(sharepath)

        except Exception:
            self.samdb.transaction_cancel()
            raise
        else:
            self.samdb.transaction_commit()

        self.outf.write("GPO %s deleted.\n" % gpo)