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
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)
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
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
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
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
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