Ejemplo n.º 1
0
def editShare(name, path, comment, browseable, permAll, usergroups, users):
    samba = SambaConf()
    samba.addShare(name,
                   path,
                   comment,
                   browseable,
                   permAll,
                   usergroups,
                   users,
                   mod=True)
    return samba.save()
Ejemplo n.º 2
0
def isSamba4Provisioned():
    """
    @return: check if Samba4 has been provisioned already
    @rtype: boolean
    """
    global_info = SambaConf().getGlobalInfo()
    if global_info["realm"] and global_info["server role"]:
        return True
    return False
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.SAMBA4_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:
        savedir = SambaConf().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
class SambaAD:
    """
    Handle sam.ldb: users and computers
    """
    def __init__(self):
        self.smb_conf = SambaConf()
        self.samdb_url = os.path.join(self.smb_conf.private_dir(), 'sam.ldb')
        self.samdb = SamDB(url=self.samdb_url,
                           session_info=system_session(),
                           lp=LoadParm())

# v Users ---------------------------------------------------------------------

    def isUserEnabled(self, username):
        search_filter = "(&(objectClass=user)(sAMAccountName=%s))" % ldb.binary_encode(
            to_str(username))
        userlist = self.samdb.search(base=self.samdb.domain_dn(),
                                     scope=ldb.SCOPE_SUBTREE,
                                     expression=search_filter,
                                     attrs=["userAccountControl"])
        if not userlist:
            return False

        uac_flags = int(userlist[0]["userAccountControl"][0])
        return 0 == (uac_flags & dsdb.UF_ACCOUNTDISABLE)

    def existsUser(self, username):
        return to_str(username) in self._samba_tool("user list")

    def updateUserPassword(self, username, password):
        self._samba_tool("user setpassword %s --newpassword='******'" %
                         (username, password))
        return True

    def createUser(self, username, password, given_name=None, surname=None):
        cmd = "user create %s '%s'" % (username, password)
        if given_name and surname:
            cmd += " --given-name='%s' --surname='%s'" % (to_str(given_name),
                                                          to_str(surname))
        self._samba_tool(cmd)
        return True

    def createGroup(self, name, description):
        cmd = 'group add ' + name
        if description:
            cmd += ' --description=' + description
        self._samba_tool(cmd)
        return True

    def enableUser(self, username):
        self._samba_tool("user enable %s" % username)
        return True

    def disableUser(self, username):
        self._samba_tool("user disable %s" % username)
        return True

    def deleteUser(self, username):
        self._samba_tool("user delete %s" % username)
        return True

    def _samba_tool(self, cmd):
        samba_tool = os.path.join(self.smb_conf.prefix, "bin/samba-tool")
        cmd = samba_tool + " " + cmd
        exit_code, std_out, std_err = shlaunch(cmd)
        if exit_code != 0:
            error_msg = "Error processing `%s`:\n" % cmd
            if std_err:
                error_msg += "\n".join(std_err)
            if std_out:
                error_msg += "\n".join(std_out)
            logger.error(error_msg)
            raise SambaToolException(error_msg)
        return std_out

# v Machines ------------------------------------------------------------------

    def _listComputersInContainer(self, container_dn, name_suffix=''):
        computers = self.samdb.search(
            base=container_dn,
            scope=ldb.SCOPE_ONELEVEL,
            expression="(objectClass=computer)",
            attrs=["name", "description", "operatingSystem"])
        res = []
        if computers:
            for computer in computers:
                description = computer.get("description",
                                           computer.get("operatingSystem", ""))
                res.append({
                    "name": str(computer["name"]) + name_suffix,
                    "description": str(description),
                    "enabled": 1  # TODO: get what the state actually is
                })
        return res

    def listDomainMembers(self):
        """
        Returns list of Computer objects description

        @return: list of dicts with Computer name and description
        @rtype: list
        """
        dcs = self._listComputersInContainer(
            "OU=Domain Controllers,%s" % self.samdb.domain_dn(), ' (dc)')
        computers = self._listComputersInContainer("CN=Computers,%s" %
                                                   self.samdb.domain_dn())
        return dcs + computers

    def deleteMachine(self, name):  # TODO
        return True

    def getMachine(self, name):
        container_dn = "CN=Computers,%s" % self.samdb.domain_dn()
        computers = self.samdb.search(
            base=container_dn,
            scope=ldb.SCOPE_ONELEVEL,
            expression="(&(objectClass=computer)(name=%s))" % name,
            attrs=["description", "operatingSystem"])
        if not computers or len(computers) < 1:
            return {'name': name, 'description': 'Unknown', 'enabled': False}

        c = computers[0]
        description = str(c.get('description', c.get('operatingSystem')))
        return {'name': name, 'description': description, 'enabled': True}

    def editMachine(self, name, description, enabled):  # TODO
        return True
Ejemplo n.º 5
0
def getSamba4GlobalInfo():
    """
    @return: values from [global] section in smb.conf
    @rtype: dict
    """
    return SambaConf().getGlobalInfo()
Ejemplo n.º 6
0
def saveOptions(options):
    return SambaConf().saveOptions(options)
Ejemplo n.º 7
0
def editShare(name, path, comment, browseable, permAll, usergroups, users):
    samba = SambaConf()
    samba.addShare(name, path, comment, browseable, permAll, usergroups, users,
                   mod=True)
    return samba.save()
Ejemplo n.º 8
0
 def __init__(self):
     self.smb_conf = SambaConf()
     self.samdb_url = os.path.join(self.smb_conf.private_dir(), 'sam.ldb')
     self.samdb = SamDB(url=self.samdb_url, session_info=system_session(),
                        lp=LoadParm())
Ejemplo n.º 9
0
def getShare(name):
    return SambaConf().getDetailedShare(name)
Ejemplo n.º 10
0
def addShare(name, path, comment, browseable, permAll, usergroups, users):
    samba = SambaConf()
    samba.addShare(name, path, comment, browseable, permAll, usergroups, users)
    samba.save()
    return name
Ejemplo n.º 11
0
def getShares():
    return SambaConf().getDetailedShares()
Ejemplo n.º 12
0
def getACLOnShare(name):
    if name:
        return SambaConf().getACLOnShare(name)
    else:
        return []
Ejemplo n.º 13
0
def deleteShare(name, file):
    samba = SambaConf()
    samba.delShare(name, file)
    return samba.save()
Ejemplo n.º 14
0
 def __init__(self):
     self.smb_conf = SambaConf()
     self.samdb_url = os.path.join(self.smb_conf.private_dir(), 'sam.ldb')
     self.samdb = SamDB(url=self.samdb_url,
                        session_info=system_session(),
                        lp=LoadParm())
Ejemplo n.º 15
0
def deleteShare(name, file):
    samba = SambaConf()
    samba.delShare(name, file)
    return samba.save()
Ejemplo n.º 16
0
class SambaAD:

    """
    Handle sam.ldb: users and computers
    """

    def __init__(self):
        self.smb_conf = SambaConf()
        self.samdb_url = os.path.join(self.smb_conf.private_dir(), 'sam.ldb')
        self.samdb = SamDB(url=self.samdb_url, session_info=system_session(),
                           lp=LoadParm())

# v Users ---------------------------------------------------------------------

    def isUserEnabled(self, username):
        if type(username) != type(''):
            raise TypeError("username is expected to be string")

        search_filter = "(&(objectClass=user)(sAMAccountName=%s))" % ldb.binary_encode(
            username)
        userlist = self.samdb.search(base=self.samdb.domain_dn(),
                                     scope=ldb.SCOPE_SUBTREE,
                                     expression=search_filter,
                                     attrs=["userAccountControl"])
        if not userlist:
            return False

        uac_flags = int(userlist[0]["userAccountControl"][0])
        return 0 == (uac_flags & dsdb.UF_ACCOUNTDISABLE)

    def existsUser(self, username):
        return username in self._samba_tool("user list")

    def updateUserPassword(self, username, password):
        self._samba_tool("user setpassword %s --newpassword='******'" %
                         (username, password))
        return True

    def createUser(self, username, password, given_name=None, surname=None):
        cmd = "user create %s '%s'" % (username, password)
        if given_name and surname:
            cmd += " --given-name='%s' --surname='%s'" % (given_name, surname)
        self._samba_tool(cmd)
        return True

    def createGroup(self, name, description):
        cmd = 'group add ' + name
        if description:
            cmd += ' --description=' + description
        self._samba_tool(cmd)
        return True

    def enableUser(self, username):
        self._samba_tool("user enable %s" % username)
        return True

    def disableUser(self, username):
        self._samba_tool("user disable %s" % username)
        return True

    def deleteUser(self, username):
        self._samba_tool("user delete %s" % username)
        return True

    def _samba_tool(self, cmd):
        samba_tool = os.path.join(self.smb_conf.prefix, "bin/samba-tool")
        cmd = samba_tool + " " + cmd
        exit_code, std_out, std_err = shlaunch(cmd)
        if exit_code != 0:
            error_msg = "Error processing `%s`:\n" % cmd
            if std_err:
                error_msg += "\n".join(std_err)
            if std_out:
                error_msg += "\n".join(std_out)
            logger.error(error_msg)
            raise SambaToolException(error_msg)
        return std_out

# v Machines ------------------------------------------------------------------

    def _listComputersInContainer(self, container_dn, name_suffix=''):
        computers = self.samdb.search(base=container_dn,
                                      scope=ldb.SCOPE_ONELEVEL,
                                      expression="(objectClass=computer)",
                                      attrs=["name", "description", "operatingSystem"])
        res = []
        if computers:
            for computer in computers:
                try:
                    description = computer["description"]
                except KeyError:
                    description = computer["operatingSystem"]
                res.append({
                    "name": str(computer["name"]) + name_suffix,
                    "description":  str(description),
                    "enabled": 1  # TODO: get what the state actually is
                })
        return res

    def listDomainMembers(self):
        """
        Returns list of Computer objects description

        @return: list of dicts with Computer name and description
        @rtype: list
        """
        dcs = self._listComputersInContainer(
            "OU=Domain Controllers,%s" % self.samdb.domain_dn(), ' (dc)')
        computers = self._listComputersInContainer(
            "CN=Computers,%s" % self.samdb.domain_dn())
        return dcs + computers

    def deleteMachine(self, name):  # TODO
        return True

    def getMachine(self, name):
        container_dn = "CN=Computers,%s" % self.samdb.domain_dn()
        computers = self.samdb.search(base=container_dn,
                                      scope=ldb.SCOPE_ONELEVEL,
                                      expression="(&(objectClass=computer)(name=%s))" % name,
                                      attrs=["description", "operatingSystem"])
        if not computers or len(computers) < 1:
            return {'name': name, 'description': 'Unknown', 'enabled': False}

        c = computers[0]
        description = str(c.get('description', c.get('operatingSystem')))
        return {'name': name, 'description': description, 'enabled': True}

    def editMachine(self, name, description, enabled):  # TODO
        return True
Ejemplo n.º 17
0
def isAuthorizedSharePath(path):
    return not path or SambaConf().isAuthorizedSharePath(path)
Ejemplo n.º 18
0
def provision_samba4(mode, realm, admin, admin_password, iface, dns_ip,
                     dns_forwarder):
    if mode not in ['dc', 'bdc', 'robdc']:
        fail_provisioning_samba4(
            "We can only provision samba4 as Domain Controller")

    print('Provisionning samba mode: %s, realm: %s, admin_password:%s' %
          (mode, realm, admin_password))

    bdc = False
    rodc = False
    if mode == 'bdc':
        mode = 'dc'
        bdc = True
    elif mode == 'robdc':
        mode = 'dc'
        bdc = True
        rodc = True

    samba = SambaConf()
    params = {'realm': realm, 'prefix': samba.prefix,
              'role': mode, 'adminpass': admin_password,
              'workgroup': samba.workgroupFromRealm(realm),
              'dns_forwarder': dns_forwarder}

    def provision_domain():
        print("Provisioning domain")
        cmd = ("%(prefix)s/bin/samba-tool domain provision"
               " --adminpass='******'"
               " --domain='%(workgroup)s'"
               " --workgroup='%(workgroup)s'"
               " --realm='%(realm)s'"
               " --use-xattr=yes"
               " --use-rfc2307"
               " --server-role='%(role)s'" % params)
        shlaunch(cmd)

    def join_domain():
        print('Joining domain')
        if bdc is True:
            if rodc is True:
                mode_bdc = 'RODC'
            else:
                mode_bdc = 'DC'
        else:
            fail_provisioning_samba4('Unsupported DC mode.')

        par = {'realm': realm,
               'mode_bdc': mode_bdc,
               'prefix': samba.prefix,
               'username': admin,
               'adminpass': admin_password}
        cmd = ("%(prefix)s/bin/samba-tool domain join %(realm)s %(mode_bdc)s"
               " --username='******'"
               " --realm='%(realm)s'"
               " --password='******'" % par)
        # shlaunch(cmd)
        run(cmd, shell=True)

    def write_config_files():
        print("provision: domain_provision_cb")
        netbios_domain_name = gethostname()

        samba.writeSambaConfig(mode, netbios_domain_name, realm, DESCRIPTION,
                               dns_forwarder=dns_forwarder)
        samba.writeKrb5Config(realm)

    def disable_password_complexity():
        print("provision: disable_password_complexity")
        cmd = ("%s/bin/samba-tool domain passwordsettings set"
               " --complexity=off"
               " --min-pwd-length=0"
               " --min-pwd-age=0"
               " --max-pwd-age=999" % samba.prefix)
        shlaunch(cmd)

    def check_ldap_is_running():
        # Number of times we will check whether ldap is running on 389 port
        max_checkings_ldap_running = 10
        tries = 1
        while tries < max_checkings_ldap_running:
            print("Checking ldap is running")
            sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            result = sock.connect_ex(('127.0.0.1', 389))
            if result == 0:
                return True
            sleep(SLEEP_TIME)
            tries += 1
        fail_provisioning_samba4("Ldap is not running after waiting long time")

    def openldap_smb5pwd_config():
        with open('/etc/openldap/slapd.conf', 'r') as h:
            for line in h:
                if line.lstrip().startswith('moduleload') and 'smbk5pwd' in line:
                    return
        state = 0
        conf_file = '/etc/openldap/slapd.conf'
        backup_file = backup(conf_file)
        with open(conf_file, 'w') as file_out, open(backup_file, 'r') as file_in:
            for line in file_in:
                file_out.write(line)
                if state == 0:
                    if line.lstrip().startswith('moduleload'):
                        file_out.write('moduleload smbk5pwd.so\n')
                        state = 1
                elif state == 1:
                    if line.lstrip().startswith('database'):
                        file_out.write('overlay smbk5pwd\n')
                        state = 2
        # TODO: fix this strange chmodS
        shlaunch("chown root:ldap /etc/openldap/slapd.conf")

    def reconfig_ldap_service():
        print("Reconfiguring ldap service")
        openldap_smb5pwd_config()
        should_reconfing = True
        f = None
        try:
            f = open('/etc/sysconfig/slapd', 'r')
            for line in f:
                if line.lstrip().startswith('SLAPDURLLIST='):
                    should_reconfing = False
            if should_reconfing:
                f.close()
                f = open('/etc/sysconfig/slapd', 'a')
                f.write(os.linesep)
                f.write('SLAPDURLLIST="ldap://127.0.0.1"')
                f.write(os.linesep)
                f.close()
            shlaunch("systemctl restart slapd")
        except Exception as e:
            print(">>>> %s" % e)
            fail_provisioning_samba4(e.message)
        sleep(SLEEP_TIME)
        check_ldap_is_running()

    def clean_etc_host():
        cmd = "sed -i -e 's/.*%s.*//' /etc/hosts" % gethostname()
        shlaunch(cmd)

    def configure_network():

        def configure_ntpd():
            shlaunch("systemctl stop ntpd")
            state = 0
            for line in fileinput.input('/etc/ntp.conf', inplace=1):
                # replace first server
                if line.startswith('fudge'):
                    print(line,)
                    state = 1
                if line.startswith('server') and state == 1:
                    print('server %s' % dns_ip)
                    state = 2
                else:
                    print line,
            shlaunch("ntpdate %s" % dns_ip, False, subprocess.PIPE)
            shlaunch("systemctl start ntpd")

        def update_resolvconf():
            with open('/etc/dhclient-enter-hooks', 'w') as f:
                fic = """make_resolv_conf() {
    echo "nameserver %s" > /etc/resolv.conf
    echo "nameserver 127.0.0.1" >> /etc/resolv.conf
    echo "search %s" >> /etc/resolv.conf
}""" % (dns_ip, realm)
                f.write(fic)

        def configure_shorewall():
            print("Configure shorewall")
            src = os.path.join(os.getcwd(), 'templates',
                               'shorewall_macro.Samba4AD')
            dst = os.path.join('/etc/shorewall/', 'macro.Samba4AD')
            shutil.copy(src, dst)
            os.chmod(dst, 0o600)

            zones = get_zones('lan')
            for zone in zones:
                add_rule('Samba4AD/ACCEPT', zone, "fw")

            shlaunch("systemctl restart shorewall")

        def configure_dhcp():
            subnet = getSubnet(network)
            if not subnet:
                addSubnet(network, netmask, realm)
                setSubnetDescription(network, 'AD network')
                setSubnetAuthoritative(network)
                setSubnetOption(network, 'domain-name', '\"' + realm + '\"')
                setSubnetOption(network, 'domain-name-servers', addr)
                start = IP(ip.net().int() + 100)
                end = IP(start.int() + 99)
                addPool(network, 'ADpool', str(start), str(end))
                shlaunch("systemctl restart dhcpd")
            print("### Done configure_dhcp")

        if_detail = netifaces.ifaddresses(iface)[netifaces.AF_INET][0]
        addr = if_detail['addr']
        netmask = if_detail['netmask']
        ip = IP(addr).make_net(netmask)
        network = str(ip.net())
        netmask = ip.prefixlen()

        if not bdc:
            configure_dhcp()
        else:
            configure_ntpd()

        configure_shorewall()
        print("### Done configure_shorewall")

    def start_samba4_service():
        print("Starting samba service")
        shlaunch("systemctl restart samba")
        sleep(SLEEP_TIME)

    def start_s4sync_service():
        print("Starting s4sync daemon")
        shlaunch("systemctl start s4sync")

    # Clean up previous provisions
    if os.path.exists(samba.smb_conf_path):
        os.unlink(samba.smb_conf_path)
    if os.path.exists(os.path.join(samba.db_dir, 'private/sam.ldb')):
        for root, dirs, files in os.walk(os.path.join(samba.db_dir, 'private/')):
            for f in files:
                os.unlink(os.path.join(root, f))
            for d in dirs:
                shutil.rmtree(os.path.join(root, d))

    write_config_files()
    print("### Done write_config_files")

    if not bdc:
        provision_domain()
        print("### Done provision_domain")
        disable_password_complexity()
        print("### Done disable_password_complexity")
    else:
        clean_etc_host()
        join_domain()

    reconfig_ldap_service()
    print("### Done reconfig_ldap_service")

    configure_network()

    start_samba4_service()
    print("### Done start_samba4_service")
    start_s4sync_service()
    print("### Done start_s4sync_service")
Ejemplo n.º 19
0
def addShare(name, path, comment, browseable, permAll, usergroups, users):
    samba = SambaConf()
    samba.addShare(name, path, comment, browseable, permAll, usergroups, users)
    samba.save()
    return name