Пример #1
0
def _adjustSssdConfiguration(domain):
    logging.info("Adjusting sssd.conf")

    sssdConfigFilePath = '/etc/sssd/sssd.conf'
    sssdConfig = configparser.ConfigParser(interpolation=None)

    sssdConfig.read(sssdConfigFilePath)
    # accept usernames without domain
    sssdConfig[f"domain/{domain}"]["use_fully_qualified_names"] = "False"

    # override homedir
    sssdConfig[f"domain/{domain}"]["override_homedir"] = "/home/%u"

    # Don't validate KVNO! Otherwise the Login will fail when the KVNO stored
    # in /etc/krb5.keytab does not match the one in the AD (msDS-KeyVersionNumber)
    sssdConfig[f"domain/{domain}"]["krb5_validate"] = "False"

    sssdConfig[f"domain/{domain}"]["ad_gpo_access_control"] = "permissive"
    sssdConfig[f"domain/{domain}"]["ad_gpo_ignore_unreadable"] = "True"

    # Don't renew the machine password, as this will break the domain join
    # See: https://github.com/linuxmuster/linuxmuster-linuxclient7/issues/27
    sssdConfig[f"domain/{domain}"][
        "ad_maximum_machine_account_password_age"] = "0"

    # Make sure usernames are not case sensitive
    sssdConfig[f"domain/{domain}"]["case_sensitive"] = "False"

    try:
        logging.info("Writing new Configuration")
        with open(sssdConfigFilePath, 'w') as sssdConfigFile:
            sssdConfig.write(sssdConfigFile)

    except Exception as e:
        logging.error("Failed!")
        logging.exception(e)
        return False

    logging.info("Restarting sssd")
    if subprocess.call(["service", "sssd", "restart"]) != 0:
        logging.error("Failed!")
        return False

    return True
Пример #2
0
def network():
    rc, rawNetworkConfig = _readNetworkConfig()
    if not rc:
        return False

    if not _checkNetworkConfigVersion(rawNetworkConfig)[0]:
        return False

    networkConfig = {}

    try:
        networkConfig["serverHostname"] = rawNetworkConfig["serverHostname"]
        networkConfig["domain"] = rawNetworkConfig["domain"]
        networkConfig["realm"] = rawNetworkConfig["realm"]
    except KeyError as e:
        logging.error("Error when reading network.conf (2)")
        logging.exception(e)
        return False, None

    return True, networkConfig
Пример #3
0
def removeLinesInFileContainingString(filePath, forbiddenStrings):
    """
    Remove all lines containing a given string form a file.

    :param filePath: The path to the file
    :type filePath: str
    :param forbiddenStrings: The string to search for
    :type forbiddenStrings: str
    :return: True on success, False otherwise
    :rtype: bool
    """
    if not isinstance(forbiddenStrings, list):
        forbiddenStrings = [forbiddenStrings]

    try:
        with open(filePath, "r") as originalFile:
            originalContents = originalFile.read()
    except Exception as e:
        logging.exception(e)
        logging.warning("Could not read contents of original file")
        return False

    newContents = ""
    for line in originalContents.split("\n"):
        lineIsClean = True
        for forbiddenString in forbiddenStrings:
            lineIsClean = lineIsClean and not forbiddenString in line

        if lineIsClean:
            newContents += line + "\n"

    try:
        with open(filePath, "w") as originalFile:
            originalFile.write(newContents)
    except Exception as e:
        logging.exception(e)
        logging.warning("Could not write new contents to original file")
        return False

    return True
Пример #4
0
def searchOne(filter):
    if conn() == None:
        logging.error("Cannot talk to LDAP")
        return False, None

    try:
        rawResult = conn().search_s(baseDn(), ldap.SCOPE_SUBTREE, filter)
    except Exception as e:
        logging.error("Error executing LDAP search!")
        logging.exception(e)
        return False, None

    try:
        result = {}

        if len(rawResult) <= 0 or rawResult[0][0] == None:
            logging.debug(
                "Search \"{}\" did not return any objects".format(filter))
            return False, None

        for k in rawResult[0][1]:
            if k != 'objectSid' and k != 'objectGUID' and rawResult[0][1][
                    k] != None:
                rawAttribute = rawResult[0][1][k]
                if len(rawAttribute) == 1:
                    result[k] = str(rawAttribute[0].decode())
                elif len(rawAttribute) > 0:
                    result[k] = []
                    for rawItem in rawAttribute:
                        result[k].append(str(rawItem.decode()))
                #print(k, str(rawResult[0][1][k]))

        #print(result)
        return True, result

    except Exception as e:
        logging.error("Error while reading ldap search results!")
        logging.exception(e)
        return False, None
Пример #5
0
def mountHomeShare():
    """
    Mounts the serverhome of the current user

    :return: True on success, False otherwise
    :rtype: bool
    """
    rc1, userAttributes = readAttributes()
    rc2, shareName = _getHomeShareName(userAttributes)
    if rc1 and rc2:
        try:
            homeShareServerPath = userAttributes["homeDirectory"]
            res = shares.mountShare(homeShareServerPath,
                                    shareName=shareName,
                                    hiddenShare=False,
                                    username=username())
            return res

        except Exception as e:
            logging.error("Could not mount home dir of user")
            logging.exception(e)

    return False, None
Пример #6
0
def _clearUserHomes(unattended=False):
    print("\nCAUTION! This will delete all userhomes of AD users!")
    if not unattended and not _askStep("clear all user homes now", False):
        return True

    if not _checkLoggedInUsers():
        return False

    if not _unmountAllCifsMounts():
        logging.info(
            "Aborting deletion of user homes to prevent deleting data on the server."
        )
        return False

    userHomes = os.listdir("/home")

    logging.info("Deleting all user homes now!")
    for userHome in userHomes:
        if not user.isUserInAD(userHome):
            logging.info("* {} [SKIPPED]".format(userHome))
            continue

        logging.info("* {}".format(userHome))
        try:
            shutil.rmtree("/home/{}".format(userHome))
        except Exception as e:
            logging.error("* FAILED!")
            logging.exception(e)

        try:
            shutil.rmtree(constants.hiddenShareMountBasepath.format(userHome))
        except:
            pass

    logging.info("Done.")
    return True
Пример #7
0
def _adjustSssdConfiguration(domain):
    logging.info("Adjusting sssd.conf")

    sssdConfigFilePath = '/etc/sssd/sssd.conf'
    sssdConfig = configparser.ConfigParser(interpolation=None)

    sssdConfig.read(sssdConfigFilePath)
    # accept usernames without domain
    sssdConfig[f"domain/{domain}"]["use_fully_qualified_names"] = "False"

    # override homedir
    sssdConfig[f"domain/{domain}"]["override_homedir"] = "/home/%u"

    # Don't validate KVNO! Otherwise the Login will fail when the KVNO stored
    # in /etc/krb5.keytab does not match the one in the AD (msDS-KeyVersionNumber)
    sssdConfig[f"domain/{domain}"]["krb5_validate"] = "False"

    sssdConfig[f"domain/{domain}"]["ad_gpo_access_control"] = "permissive"
    sssdConfig[f"domain/{domain}"]["ad_gpo_ignore_unreadable"] = "True"

    try:
        logging.info("Writing new Configuration")
        with open(sssdConfigFilePath, 'w') as sssdConfigFile:
            sssdConfig.write(sssdConfigFile)

    except Exception as e:
        logging.error("Failed!")
        logging.exception(e)
        return False

    logging.info("Restarting sssd")
    if subprocess.call(["service", "sssd", "restart"]) != 0:
        logging.error("Failed!")
        return False

    return True
Пример #8
0
def _processPrintersPolicy(policyBasepath):
    logging.info("== Parsing a printer policy! ==")
    policyFile = "{}/User/Preferences/Printers/Printers.xml".format(
        policyBasepath)
    printerList = []
    # test
    rc, tree = _parseXmlPolicy(policyFile)

    if not rc:
        logging.error(
            "==> Error while reading Printer policy file, skipping! ==")
        return

    xmlPrinters = tree.getroot()

    if not xmlPrinters.tag == "Printers":
        logging.warning(
            "==> Printer policy xml File is of invalid format, skipping! ==")
        return

    for xmlPrinter in xmlPrinters:

        if xmlPrinter.tag != "SharedPrinter" or (
                "disabled" in xmlPrinter.attrib
                and xmlPrinter.attrib["disabled"] == "1"):
            continue

        printer = {}
        printer["filters"] = []

        try:
            printer["name"] = xmlPrinter.attrib["name"]
        except Exception as e:
            logging.warning(
                "Exception when reading a printer name from a printer policy XML file"
            )
            logging.exception(e)

        for xmlPrinterProperty in xmlPrinter:
            if xmlPrinterProperty.tag == "Properties":
                try:
                    rc, printerUrl = printers.translateSambaToIpp(
                        xmlPrinterProperty.attrib["path"])
                    if rc:
                        printer["path"] = printerUrl
                except Exception as e:
                    logging.warning(
                        "Exception when parsing a printer policy XML file")
                    logging.exception(e)
                    continue

            if xmlPrinterProperty.tag == "Filters":
                printer["filters"] = _parseXmlFilters(xmlPrinterProperty)

        printerList.append(printer)

    printerList = _processFilters(printerList)

    logging.info("Found printers:")
    for printer in printerList:
        logging.info("* {0}\t\t| {1}\t| {2}".format(printer["name"],
                                                    printer["path"],
                                                    printer["filters"]))
        printers.installPrinter(printer["path"], printer["name"])

    logging.info("==> Successfully parsed a printer policy! ==")
Пример #9
0
def _processDrivesPolicy(policyBasepath):
    logging.info("== Parsing a drive policy! ==")
    policyFile = "{}/User/Preferences/Drives/Drives.xml".format(policyBasepath)
    shareList = []

    rc, tree = _parseXmlPolicy(policyFile)

    if not rc:
        logging.error(
            "==> Error while reading Drives policy file, skipping! ==")
        return

    xmlDrives = tree.getroot()

    if not xmlDrives.tag == "Drives":
        logging.warning(
            "==> Drive policy xml File is of invalid format, skipping! ==")
        return

    for xmlDrive in xmlDrives:

        if xmlDrive.tag != "Drive" or ("disabled" in xmlDrive.attrib
                                       and xmlDrive.attrib["disabled"] == "1"):
            continue

        drive = {}
        drive["filters"] = []
        for xmlDriveProperty in xmlDrive:
            if xmlDriveProperty.tag == "Properties":
                try:
                    drive["label"] = xmlDriveProperty.attrib["label"]
                    drive["letter"] = xmlDriveProperty.attrib["letter"]
                    drive["path"] = xmlDriveProperty.attrib["path"]
                    drive["useLetter"] = xmlDriveProperty.attrib["useLetter"]
                except Exception as e:
                    logging.warning(
                        "Exception when parsing a drive policy XML file")
                    logging.exception(e)
                    continue

            if xmlDriveProperty.tag == "Filters":
                drive["filters"] = _parseXmlFilters(xmlDriveProperty)

        shareList.append(drive)

    shareList = _processFilters(shareList)

    logging.info("Found shares:")
    for drive in shareList:
        logging.info("* {:10}| {:5}| {:40}| {:5}".format(
            drive["label"], drive["letter"], drive["path"],
            drive["useLetter"]))

    for drive in shareList:
        if drive["useLetter"] == "1":
            shareName = f"{drive['label']} ({drive['letter']}:)"
        else:
            drive["label"]
        shares.mountShare(drive["path"], shareName=shareName)

    logging.info("==> Successfully parsed a drive policy! ==")