Ejemplo n.º 1
0
    def smbInfoSave(self, options):
        """
        Set information in global section:
         @param options: dict with global options
        """
        current = self.getSmbInfo()

        # Don't write an empty value
        # Use the SAMBA default
        for option in ["logon home", "logon drive"]:
            if options[option] == "":
                self.remove("global", option)
                del options[option]

        # We update only what has changed from the current configuration
        for option in self.supportedGlobalOptions:
            try:
                if option in options:
                    options[option] = self.mapOptionValue(options[option])
                    if options[option] != current[option]:
                        self.setContent("global", option, options[option])
                    # else do nothing, the option is already set
                else:
                    self.remove("global", option)
            except KeyError:
                # Just ignore the option if it was not sent
                pass

        if current["pdc"] != options['pdc']:
            if options['pdc']:
                self.setContent('global', 'domain logons', 'yes')
                self.setContent('global', 'domain master', 'yes')
                self.setContent('global', 'os level', '255')
            else:
                self.setContent('global', 'domain logons', 'no')
                self.remove('global', 'domain master')
                self.remove('global', 'os level')

        if options['hashomes']:
            self.setContent('homes', 'comment', 'User shares')
            self.setContent('homes', 'browseable', 'no')
            self.setContent('homes', 'read only', 'no')
            self.setContent('homes', 'create mask', '0700')
            self.setContent('homes', 'directory mask', '0700')
            # Set the vscan-av plugin if available
            if os.path.exists(SambaConfig("samba").av_so):
                self.setContent("homes", "vfs objects", os.path.splitext(os.path.basename(SambaConfig("samba").av_so))[0])
        elif 'homes' in self.config:
            del self.config["homes"]
            self.setContent('global', 'logon home', '')

        # Disable global profiles
        if not options['hasprofiles']:
            self.setContent('global', 'logon path', '')

        # Save file
        self.save()
        return 0
Ejemplo n.º 2
0
def modShare(name,
             path,
             comment,
             perms,
             admingroups,
             recursive=True,
             browseable=True,
             av=0,
             customparameters=None):
    smbObj = SambaConf(SambaConfig("samba").samba_conf_file)
    smbObj.addShare(name, path, comment, perms, admingroups, recursive,
                    browseable, av, customparameters, True)
    smbObj.save()
Ejemplo n.º 3
0
def backupShare(share, media, login):
    """
    Launch as a background process the backup of a share
    """
    r = AF().log(PLUGIN_NAME, AA.SAMBA_BACKUP_SHARE, [(share, AT.SHARE),
                                                      (login, AT.USER)], media)
    config = BasePluginConfig("base")
    cmd = os.path.join(config.backuptools, "backup.sh")
    if share == "homes":
        # FIXME: Maybe we should have a configuration directive to tell that
        # all users home are stored into /home
        savedir = "/home/"
    else:
        smbObj = SambaConf(SambaConfig("samba").samba_conf_file)
        savedir = smbObj.getContent(share, "path")
    # Run backup process in background
    shlaunchBackground(
        cmd + " " + share + " " + savedir + " " + config.backupdir + " " +
        login + " " + media + " " + config.backuptools,
        "backup share " + share, progressBackup)
    r.commit()
    return os.path.join(config.backupdir,
                        "%s-%s-%s" % (login, share, strftime("%Y%m%d")))
Ejemplo n.º 4
0
    def __init__(self, smbconffile="/etc/samba/smb.conf", conffile=None, conffilebase=None):
        """
        Constructor for object that read/write samba conf file.

        We use the testparm command on the smb configuration file to sanitize it,
        and to replace all keyword synonyms with the preferred keywords:
         - 'write ok', 'writeable', 'writable' -> 'read only'
         - 'public' -> 'guest ok'
         ...

        In SAMBA source code, parameters are defined in param/loadparm.c
        """
        config = SambaConfig("samba", conffile)
        self.defaultSharesPath = config.defaultSharesPath
        self.authorizedSharePaths = config.authorizedSharePaths
        self.conffilebase = conffilebase
        self.smbConfFile = smbconffile
        # Parse SAMBA configuration file
        try:
            self.config = ConfigObj(self.smbConfFile, interpolation=False,
                                    list_values=False, write_empty_values=True,
                                    encoding='utf8')
        except ParseError, e:
            logger.error("Failed to parse %s : %s " % (self.smbConfFile, e))
Ejemplo n.º 5
0
def shareCustomParameters(name):
    """get an array of additionnal params about a share"""
    smbObj = SambaConf(SambaConfig("samba").samba_conf_file)
    return smbObj.shareCustomParameters(name)
Ejemplo n.º 6
0
def shareInfo(name):
    """get an array of information about a share"""
    smbObj = SambaConf(SambaConfig("samba").samba_conf_file)
    return smbObj.shareInfo(name)
Ejemplo n.º 7
0
def delShare(name, file):
    smbObj = SambaConf(SambaConfig("samba").samba_conf_file)
    smbObj.delShare(name, file)
    smbObj.save()
    return 0
Ejemplo n.º 8
0
                    for root, dirs, files in os.walk(path):
                        acls.applyto(root)
                        acls.applyto(root, posix1e.ACL_TYPE_DEFAULT)
                        for file in map(lambda f: os.path.join(root, f), files):
                            acls.applyto(file)
            else:
                logger.error("Cannot save ACL on folder " + path)

            tmpInsert['valid users'] = ', '.join(map(sanitize_name,
                reduce(operator.add, [j for p, j in perms.items()], [])))
            tmpInsert['write list'] = ', '.join(map(sanitize_name,
                reduce(operator.add, [j for p, j in perms.items() if 'w' in p], [])))

        # Set the anti-virus plugin if available
        if av:
            tmpInsert['vfs objects'] = os.path.splitext(os.path.basename(SambaConfig("samba").av_so))[0]

        # Set the admin groups for the share
        if admingroups:
            # need to add '@'
            admingroups = map(lambda g: '@' + g, admingroups)
            tmpInsert["admin users"] = ", ".join(map(sanitize_name, admingroups))
            # include admin users in valid users list and write list
            if tmpInsert['writeable'] == 'no':
                tmpInsert['valid users'] = ', '.join(filter(bool, [tmpInsert['valid users'], tmpInsert["admin users"]]))
                tmpInsert['write list'] = ', '.join(filter(bool, [tmpInsert['write list'], tmpInsert["admin users"]]))

        self.config[name] = tmpInsert

        info = self.shareInfo(name)
        if mod:
Ejemplo n.º 9
0
def reloadSamba():
    r = AF().log(PLUGIN_NAME, AA.SAMBA_RELOAD_SAMBA)
    shlaunchBackground(SambaConfig("samba").samba_init_script + ' reload')
    r.commit()
    return 0
Ejemplo n.º 10
0
def isPdc():
    try:
        smbObj = SambaConf(SambaConfig("samba").samba_conf_file)
    except:
        raise Exception("Can't open SAMBA configuration file")
    return smbObj.isPdc()
Ejemplo n.º 11
0
def getDetailedShares(filter="", start=0, end=None):
    """Get a complete array of information about all shares"""
    smbObj = SambaConf(SambaConfig("samba").samba_conf_file)
    resList = smbObj.getDetailedShares(filter, start, end)
    return resList
Ejemplo n.º 12
0
def getDefaultSharesPath():
    """
    @return: the default SAMBA share path
    @rtype: str
    """
    return SambaConfig("samba").defaultSharesPath
Ejemplo n.º 13
0
def isAuthorizedSharePath(path):
    return SambaConf(
        SambaConfig("samba").samba_conf_file).isAuthorizedSharePath(path)
Ejemplo n.º 14
0
def isSmbAntiVirus():
    return os.path.exists(SambaConfig("samba").av_so)
Ejemplo n.º 15
0
 def __init__(self, conffile = None, conffilebase = None):
     ldapUserGroupControl.__init__(self, conffilebase)
     self.configSamba = SambaConfig("samba")
     self.baseComputersDN = self.configSamba.baseComputersDN
     self.hooks.update(self.configSamba.hooks)
Ejemplo n.º 16
0
def getSmbInfo():
    """get main information of global section"""
    smbObj = SambaConf(SambaConfig("samba").samba_conf_file)
    return smbObj.getSmbInfo()
Ejemplo n.º 17
0
def smbInfoSave(options):
    """save information about global section"""
    smbObj = SambaConf(SambaConfig("samba").samba_conf_file)
    return smbObj.smbInfoSave(options)
Ejemplo n.º 18
0
def getACLOnShare(name):
    smbObj = SambaConf(SambaConfig("samba").samba_conf_file)
    return smbObj.getACLOnShare(name)
Ejemplo n.º 19
0
def isProfiles():
    """ check if global profiles are setup """
    smbObj = SambaConf(SambaConfig("samba").samba_conf_file)
    return smbObj.isProfiles()
Ejemplo n.º 20
0
def getAdminUsersOnShare(name):
    return SambaConf(
        SambaConfig("samba").samba_conf_file).getAdminUsersOnShare(name)
Ejemplo n.º 21
0
def restartSamba():
    r = AF().log(PLUGIN_NAME, AA.SAMBA_RESTART_SAMBA)
    shlaunchBackground(SambaConfig("samba").samba_init_script + ' restart')
    r.commit()
    return 0
Ejemplo n.º 22
0
def isBrowseable(name):
    return SambaConf(SambaConfig("samba").samba_conf_file).isBrowseable(name)
Ejemplo n.º 23
0
def activate():
    """
     this function define if the module "base" can be activated.
     @return: return True if this module can be activate
     @rtype: boolean
    """
    config = SambaConfig("samba")

    if config.disabled:
        logger.info("samba plugin disabled by configuration.")
        return False

    if config.defaultSharesPath:
        if config.defaultSharesPath.endswith("/"):
            logger.error("Trailing / is not allowed in defaultSharesPath")
            return False
        if not os.path.exists(config.defaultSharesPath):
            logger.error("The default shares path '%s' does not exist" %
                         config.defaultSharesPath)
            return False

    for cpath in config.authorizedSharePaths:
        if cpath.endswith("/"):
            logger.error("Trailing / is not allowed in authorizedSharePaths")
            return False
        if not os.path.exists(cpath):
            logger.error("The authorized share path '%s' does not exist" %
                         cpath)
            return False

    # Verify if samba conf file exist
    conf = config.samba_conf_file
    if not os.path.exists(conf):
        logger.error(conf + " does not exist")
        return False

    # validate smb.conf
    smbconf = SambaConf()
    if not smbconf.validate(conf):
        logger.error("SAMBA configuration file is not valid")
        return False

    # For each share, test if it sharePath exists
    for share in getDetailedShares():
        shareName = share[0]
        infos = shareInfo(shareName)
        if infos:
            sharePath = infos['sharePath']
            if sharePath and not '%' in sharePath and not os.path.exists(
                    sharePath):
                # only show error
                logger.error("The samba share path '%s' does not exist." %
                             sharePath)
        else:
            return False

    try:
        ldapObj = ldapUserGroupControl()
    except ldap.INVALID_CREDENTIALS:
        logger.error("Can't bind to LDAP: invalid credentials.")
        return False

    # Test if the Samba LDAP schema is available in the directory
    try:
        schema = ldapObj.getSchema("sambaSamAccount")
        if len(schema) <= 0:
            logger.error("Samba schema is not included in LDAP directory")
            return False
    except:
        logger.exception("invalid schema")
        return False

    # Verify if init script exist
    init = config.samba_init_script
    if not os.path.exists(init):
        logger.error(init + " does not exist")
        return False

    # If SAMBA is defined as a PDC, make extra checks
    if smbconf.isPdc():
        samba = SambaLDAP()
        # Create SAMBA computers account OU if it doesn't exist
        head, path = samba.baseComputersDN.split(",", 1)
        ouName = head.split("=")[1]
        samba.addOu(ouName, path)
        # Check that a sambaDomainName entry is in LDAP directory
        domainInfos = samba.getDomain()
        # Set domain policy
        samba.setDomainPolicy()
        if not domainInfos:
            logger.error(
                "Can't find sambaDomainName entry in LDAP for domain %s. Please check your SAMBA LDAP configuration."
                % smbconf.getContent("global", "workgroup"))
            return False
        smbconfbasesuffix = smbconf.getContent("global", "ldap suffix")
        if not smbconfbasesuffix:
            logger.error("SAMBA 'ldap suffix' option is not setted.")
            return False
        if ldap.explode_dn(samba.baseDN) != ldap.explode_dn(smbconfbasesuffix):
            logger.error(
                "SAMBA 'ldap suffix' option is not equal to MMC 'baseDN' option."
            )
            return False
        # Check that SAMBA and MMC given OU are in sync
        for option in [
            ("ldap user suffix", "baseUsersDN", samba.baseUsersDN),
            ("ldap group suffix", "baseGroupsDN", samba.baseGroupsDN),
            ("ldap machine suffix", "baseComputersDN", samba.baseComputersDN)
        ]:
            smbconfsuffix = smbconf.getContent("global", option[0])
            if not smbconfsuffix:
                logger.error("SAMBA '" + option[0] + "' option is not setted")
                return False
            # Do a case insensitive comparison of the corresponding MMC / SAMBA options
            if ldap.explode_rdn(smbconfsuffix)[0].lower() != ldap.explode_rdn(
                    option[2])[0].lower():
                logger.error("SAMBA option '" + option[0] +
                             "' is not equal to MMC '" + option[1] +
                             "' option.")
                return False
        # Check that "ldap delete dn" SAMBA option is set to "No"
        smbconfdeletedn = smbconf.isValueTrue(
            smbconf.getContent("global", "ldap delete dn"))
        if smbconfdeletedn == 1:
            logger.error("SAMBA option 'ldap delete dn' must be disabled.")
            return False
        # Check that Domain Computers group exists
        # We need it to put a machine account in the right group when joigning it to the domain
        if not samba.getDomainComputersGroup():
            logger.error(
                "Can't find sambaGroupMapping entry in LDAP corresponding to 'Domain Computers' group. Please check your SAMBA LDAP configuration."
            )
            return False
        # Check that Domain Admins group exists
        if not samba.getDomainAdminsGroup():
            logger.error(
                "Can't find sambaGroupMapping entry in LDAP corresponding to 'Domain Admins' group. Please check your SAMBA LDAP configuration."
            )
            return False
        # Check that Domain Guests group exists
        if not samba.getDomainGuestsGroup():
            logger.error(
                "Can't find sambaGroupMapping entry in LDAP corresponding to 'Domain Guests' group. Please check your SAMBA LDAP configuration."
            )
            return False
        # Check that Domain Users group exists
        if not samba.getDomainUsersGroup():
            logger.error(
                "Can't find sambaGroupMapping entry in LDAP corresponding to 'Domain Users' group. Please check your SAMBA LDAP configuration."
            )
            return False
        # Check that add machine script option is set, and that the given script exist
        addMachineScript = smbconf.getContent("global", "add machine script")
        if not addMachineScript:
            logger.error("SAMBA 'add machine script' option is not set.")
            return False
        else:
            script = addMachineScript.split(" ")[0]
            if not os.path.exists(script):
                logger.error(
                    "SAMBA 'add machine script' option is set to a non existing file: "
                    + script)
                return False
        # Issue a warning if NSCD is running
        if os.path.exists("/var/run/nscd.pid") or os.path.exists(
                "/var/run/.nscd_socket") or os.path.exists("/var/run/nscd"):
            logger.warning(
                "Looks like NSCD is installed on your system. You should not run NSCD on a SAMBA server."
            )
        # Check that os level is set to 255
        oslevel = smbconf.getContent("global", "os level")
        if int(oslevel) < 255:
            logger.debug("Set SAMBA os level to 255.")
            smbconf.setContent("global", "os level", "255")
            smbconf.save()
            reloadSamba()
    try:
        from mmc.plugins.dashboard.manager import DashboardManager
        from mmc.plugins.samba.panel import SambaPanel
        DM = DashboardManager()
        DM.register_panel(SambaPanel("samba"))
    except ImportError:
        pass

    return True
Ejemplo n.º 24
0
def getDetailedShares():
    """Get a complete array of information about all shares"""
    smbObj = SambaConf(SambaConfig("samba").samba_conf_file)
    resList = smbObj.getDetailedShares()
    return resList