예제 #1
0
def isObjectInGroup(objectDn, groupName):
    logging.debug("= Testing if object {0} is a member of group {1} =".format(
        objectDn, groupName))
    rc, groupAdObject = searchOne(
        "(&(member:1.2.840.113556.1.4.1941:={0})(sAMAccountName={1}))".format(
            objectDn, groupName))
    logging.debug("=> Result: {} =".format(rc))
    return rc
예제 #2
0
def _getShareMountpoint(networkPath, username, hidden, shareName=None):
    logging.debug(f"Calculating mountpoint of {networkPath}")

    shareName = _getDefaultShareName(networkPath, shareName)

    if hidden:
        return "{0}/{1}".format(
            constants.hiddenShareMountBasepath.format(username), shareName)
    else:
        return "{0}/{1}".format(constants.shareMountBasepath.format(username),
                                shareName)
def unset(key):
    """
    Unset a previously exported environment variable

    :param key: The key to unset
    :type key: str
    :return: True or False
    :rtype: bool
    """
    logging.debug("Saving unset '{}' to tmp file".format(key))
    return _appendToTmpEnvFile("unset", key)
예제 #4
0
def patchKeytab():
    """
    Patches the `/etc/krb5.keytab` file. It inserts the correct hostname of the current computer.

    :return: True on success, False otherwise
    :rtype: bool
    """
    krb5KeytabFilePath = "/etc/krb5.keytab"
    logging.info("Patching {}".format(krb5KeytabFilePath))
    krb5KeytabUtil = Krb5KeytabUtil(krb5KeytabFilePath)

    try:
        krb5KeytabUtil.read()
    except:
        logging.error("Error reading {}".format(krb5KeytabFilePath))
        return False

    for entry in krb5KeytabUtil.keytab.entries:
        oldData = entry.principal.components[-1].data
        if len(entry.principal.components) == 1:
            newData = computer.hostname().upper() + "$"
            entry.principal.components[0].data = newData

        elif len(entry.principal.components) == 2 and (
                entry.principal.components[0].data == "host"
                or entry.principal.components[0].data == "RestrictedKrbHost"):
            rc, networkConfig = config.network()
            if not rc:
                continue

            newData = ""
            domain = networkConfig["domain"]
            if domain in entry.principal.components[1].data:
                newData = computer.hostname().lower() + "." + domain
            else:
                newData = computer.hostname().upper()

            entry.principal.components[1].data = newData

        logging.debug("{} was changed to {}".format(
            oldData, entry.principal.components[-1].data))

    logging.info("Trying to overwrite {}".format(krb5KeytabFilePath))
    try:
        result = krb5KeytabUtil.write()
    except:
        result = False

    if not result:
        logging.error("Error overwriting {}".format(krb5KeytabFilePath))

    return result
def export(keyValuePair):
    """
    Export an environment variable

    :param keyValuePair: Key value pair in format `key=value`
    :type keyValuePait: str
    :return: True or False
    :rtype: bool
    """
    logging.debug("Saving export '{}' to tmp file".format(keyValuePair))

    envList = keyValuePair.split("=")
    if len(envList) == 2:
        os.putenv(envList[0], envList[1])

    return _appendToTmpEnvFile("export", keyValuePair)
def searchOne(filter):
    """Searches the LDAP with a filter and returns the first found object

    :param filter: A valid ldap filter
    :type filter: str
    :return: Tuple (success, ldap object as dict)
    :rtype: tuple
    """
    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(f"Search \"{filter}\" did not return any objects")
            return False, None

        for k in rawResult[0][1]:
            if rawResult[0][1][k] != None:
                rawAttribute = rawResult[0][1][k]
                try:
                    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()))
                except UnicodeDecodeError:
                    continue

        return True, result

    except Exception as e:
        logging.error("Error while reading ldap search results!")
        logging.exception(e)
        return False, None
def isObjectInGroup(objectDn, groupName):
    """
    Check if a given object is in a given group

    :param objectDn: The DN of the object
    :type objectDn: str
    :param groupName: The name of the group
    :type groupName: str
    :return: True if it is a member, False otherwise
    :rtype: bool
    """
    logging.debug("= Testing if object {0} is a member of group {1} =".format(
        objectDn, groupName))
    rc, groupAdObject = searchOne(
        "(&(member:1.2.840.113556.1.4.1941:={0})(sAMAccountName={1}))".format(
            objectDn, groupName))
    logging.debug("=> Result: {} =".format(rc))
    return rc
def _apply(templatePath):
    try:
        # read template file
        rc, fileData = _readTextfile(templatePath)

        if not rc:
            logging.error('Failed!')
            return False

        fileData = _resolveVariables(fileData)

        # get target path
        firstLine = fileData.split('\n')[0]
        targetFilePath = firstLine.partition(' ')[2]

        # remove first line (the target file path)
        fileData = fileData[fileData.find('\n'):]

        # never ever overwrite sssd.conf, this will lead to issues!
        # sssd.conf is written by `realm join`!
        if targetFilePath in constants.notTemplatableFiles:
            logging.warning(
                "Skipping forbidden file {}".format(targetFilePath))
            return True

        # create target directory
        Path(Path(targetFilePath).parent.absolute()).mkdir(parents=True,
                                                           exist_ok=True)

        # remove comment lines beginning with # from .xml files
        if targetFilePath.endswith('.xml'):
            fileData = _stripComment(fileData)

        # write config file
        logging.debug("-> to {}".format(targetFilePath))
        with open(targetFilePath, 'w') as targetFile:
            targetFile.write(fileData)

        return True

    except Exception as e:
        logging.error('Failed!')
        logging.exception(e)
        return False
예제 #9
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
예제 #10
0
def _processFilters(policies):
    filteredPolicies = []

    for policy in policies:
        if not len(policy["filters"]) > 0:
            filteredPolicies.append(policy)
        else:
            filtersPassed = True
            for filter in policy["filters"]:
                logging.debug("Testing filter: {}".format(filter))
                # TODO: check for AND and OR
                if filter["bool"] == "AND":
                    filtersPassed = filtersPassed and _processFilter(filter)
                elif filter["bool"] == "OR":
                    filtersPassed = filtersPassed or _processFilter(filter)
                else:
                    logging.warning(
                        "Unknown boolean operation: {}! Cannot process filter!"
                        .format(filter["bool"]))

            if filtersPassed:
                filteredPolicies.append(policy)

    return filteredPolicies
예제 #11
0
def _installPrinter(username, networkPath, name):
    logging.debug("Installing Printer {0} on {1}".format(name, networkPath))
    installCommand = [
        "lpadmin", "-p", name, "-E", "-v", networkPath, "-m", "everywhere",
        "-u", f"allow:{username}"
    ]
    logging.debug("* running '{}'".format(" ".join(installCommand)))

    if not subprocess.call(installCommand,
                           stdout=subprocess.PIPE,
                           stderr=subprocess.PIPE) == 0:
        logging.fatal(f"* Error installing printer {name} on {networkPath}!\n")
        return False

    logging.debug("* Success!")
    return True
예제 #12
0
def _mountShare(username,
                networkPath,
                shareName,
                hiddenShare,
                useCruidOfExecutingUser=False):

    mountpoint = _getShareMountpoint(networkPath, username, hiddenShare,
                                     shareName)

    mountCommandOptions = f"file_mode=0700,dir_mode=0700,sec=krb5,nodev,nosuid,mfsymlinks,nobrl,vers=3.0,user={username}"
    rc, networkConfig = config.network()
    domain = None

    if rc:
        domain = networkConfig["domain"]
        mountCommandOptions += f",domain={domain.upper()}"

    try:
        pwdInfo = pwd.getpwnam(username)
        uid = pwdInfo.pw_uid
        gid = pwdInfo.pw_gid
        mountCommandOptions += f",gid={gid},uid={uid}"

        if not useCruidOfExecutingUser:
            mountCommandOptions += f",cruid={uid}"

    except KeyError:
        uid = -1
        gid = -1
        logging.warning("Uid could not be found! Continuing anyway!")

    mountCommand = [
        "/usr/sbin/mount.cifs", "-o", mountCommandOptions, networkPath,
        mountpoint
    ]

    logging.debug(f"Trying to mount '{networkPath}' to '{mountpoint}'")
    logging.debug("* Creating directory...")

    try:
        Path(mountpoint).mkdir(parents=True, exist_ok=False)
    except FileExistsError:
        # Test if a share is already mounted there
        if _directoryIsMountpoint(mountpoint):
            logging.debug("* The mountpoint is already mounted.")
            return True, mountpoint
        else:
            logging.warning(
                "* The target directory already exists, proceeding anyway!")

    logging.debug("* Executing '{}' ".format(" ".join(mountCommand)))
    logging.debug("* Trying to mount...")
    if not subprocess.call(
            mountCommand, stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0:
        logging.fatal(
            f"* Error mounting share {networkPath} to {mountpoint}!\n")
        return False, None

    logging.debug("* Success!")

    # hide the shares parent dir (/home/%user/media) in case it is not a hidden share
    if not hiddenShare:
        try:
            hiddenFilePath = f"{mountpoint}/../../.hidden"
            logging.debug(f"* hiding parent dir {hiddenFilePath}")
            hiddenFile = open(hiddenFilePath, "w+")
            hiddenFile.write(mountpoint.split("/")[-2])
            hiddenFile.close()
        except:
            logging.warning(f"Could not hide parent dir of share {mountpoint}")

    return True, mountpoint