From 270a5219b69fc92111c4d8ec1ba7356411fcecda Mon Sep 17 00:00:00 2001 From: Louis Abel Date: Sun, 3 Sep 2023 14:43:13 -0700 Subject: [PATCH] lookahead should delete on sync --- mangle/ipa/.ipaauditor.py.swp | Bin 0 -> 12288 bytes mangle/ipa/ipaauditor.py | 26 ++++++ mangle/ipa/ipainfo.py | 133 +++++++++++++++++++++++++++++ mangle/ipa/ipaquery.py | 7 ++ sync/lh-release-sync-to-staging.sh | 4 +- 5 files changed, 168 insertions(+), 2 deletions(-) create mode 100644 mangle/ipa/.ipaauditor.py.swp create mode 100644 mangle/ipa/ipaauditor.py create mode 100644 mangle/ipa/ipainfo.py create mode 100644 mangle/ipa/ipaquery.py diff --git a/mangle/ipa/.ipaauditor.py.swp b/mangle/ipa/.ipaauditor.py.swp new file mode 100644 index 0000000000000000000000000000000000000000..4d89f97aea7b894ea5ccb2c44f4f08689a14c60a GIT binary patch literal 12288 zcmeI2J#W-77{^^iH(C%(bm1u-`l2>z=~Au~(H9VvXhEW7VL-mbxmtDX;5gUbLIn%r zBfux%3$U@l3@m&HpcLALwLHnC$K4Hpx>b6t`^#}`|DPv6JHsiiPCi&(fvesm!*Y(X zrQZGU*KmK&-iKbMcvYzU{y$2}we+~I36+{CP$t;iGIrC`!gWr3QW*L*>HJjI{J>b@ zJ7d%)-iUF&6244$E}n(b8S5pDP6uic0U~fL0-1{@X8PFlm8s%YAG$mU7tXIA%Zeru z0U|&IhyW2F0z`la5CI}^G6}e(hwWhMr^@sP%DShkE}K*l0U|&IhyW2F0z`la5CI}U z1c(3;AOa_l01p{^b%wElK1?3J{~!JT|9qCQH>ek==cqZM?2>bqRHVe*36h)LYbR)HBpm)I-!5Dvx;)bs9y52oM1xKm>>Y5g-CYfCvx)BJe*1 z0883PJ+Up_$kZsy+liIhjSR0ESiUz8NyBXz4Y3I`B~sv40IzeY@{wtS9UdO;FR2PuA=^jw`P!F+9p-1ll;jNSs}2e!iqTMm^oNATC~#n(w2_c z4n*Q$IZljqH?1|cQp}93iH}0aq7!%`TNYp2ESznW;W~4GuCU+Q=KM8mmrWUdQAwfQ zig3J@#crEpGmF*(ui5O+1AlKD*JVBj9V7SJMzS(6ZUM%IK~$Q07RO6=f)!>xrsD37lf;W^yGrOr2D)6;{6281HwnR4SG9j1^wp%>3^liCX0 zF&Uc9Vev?PLrI-&d&btT +# +# This script acts as a auditor for a FreeIPA domain. By default, it will +# communicate with an IPA server of a domain, login, and attempt to get all +# information for HBAC and SUDO. + +import sys + +python_freeipa = True +ipalib = True + +try: + from python_freeipa import ClientMeta +except ImportError: + python_freeipa = None + +try: + from ipalib import api +except ImportError: + ipalib = None + +if not ipalib and not python_freeipa: + print('No IPA python modules are available') + sys.exit(1) diff --git a/mangle/ipa/ipainfo.py b/mangle/ipa/ipainfo.py new file mode 100644 index 0000000..96810ac --- /dev/null +++ b/mangle/ipa/ipainfo.py @@ -0,0 +1,133 @@ +#!/usr/bin/env python3 +# -*-:python; coding:utf-8; -*- +# author: Louis Abel +# +# This scripts attempts to be an adinfo lookalike. This does not implement all +# features that are available. + +import os +import sys +import socket +import configparser +import subprocess +#from python_freeipa import ClientMeta +try: + from ipalib import api +except ImportError as exc: + raise ImportError('No IPA libraries found.') from exc + +try: + api.bootstrap(context="custom") + api.finalize() + # pylint: disable=no-member + api.Backend.rpcclient.connect() + api_access = True +except: + print('WARNING: No kerberos credentials') + api_access = False + +class EtcIPADefault: + """ + Reads just the /etc/ipa/default.conf file that is generated + """ + @staticmethod + def read(): + """ + Attempt to read the config file + """ + if not os.path.exists('/etc/ipa/default.conf'): + print('File does not exist (/etc/ipa/default.conf)') + sys.exit(1) + + __config = configparser.ConfigParser() + __config.read('/etc/ipa/default.conf') + outter_info = {} + outter_info['local_host_name'] = socket.gethostname() + outter_info['ipa_joined_name'] = __config['global']['host'] + outter_info['ipa_domain'] = __config['global']['domain'] + outter_info['registered_dc'] = __config['global']['server'] + return outter_info + +class SssctlInfo: + @staticmethod + def domain_status(ipa_domain): + """ + Gets the status from sssctl + """ + sssctl_cmd = f'/usr/sbin/sssctl domain-status -o {ipa_domain}' + if not os.path.exists('/usr/sbin/sssctl'): + return 'sssctl command not found' + + if not os.getuid() == 0: + return 'Unknown; root required' + + if sys.version_info <= (3, 6): + processor = subprocess.run(args=sssctl_cmd, + shell=True, check=False, + universal_newlines=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + else: + processor = subprocess.run(args=f'/usr/sbin/sssctl domain-status -o {ipa_domain}', + check=False, capture_output=True, text=True, shell=True) + + domain_status_out = processor.stdout.strip().split(':')[1].strip() + return domain_status_out + + @staticmethod + def current_dc(ipa_domain): + """ + Gets the current connected DC + """ + sssctl_cmd = f'/usr/sbin/sssctl domain-status -a {ipa_domain} | grep IPA' + if not os.path.exists('/usr/sbin/sssctl'): + return 'sssctl command not found' + + if not os.getuid() == 0: + return 'Unknown; root required' + + if sys.version_info <= (3, 6): + processor = subprocess.run(args=sssctl_cmd, + shell=True, check=False, + universal_newlines=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + else: + processor = subprocess.run(args=f'/usr/sbin/sssctl domain-status -a {ipa_domain} | grep IPA', + check=False, capture_output=True, text=True, shell=True) + + current_dc_out = processor.stdout.strip().split(':')[1].strip() + return current_dc_out + +class IPAInfo: + """ + Get IPA specific information + """ + @staticmethod + def get_host_groups(host): + if api_access: + results = api.Command.host_show(host, all=True)['result']['memberof_hostgroup'] + return results + return ['Unknown'] + +etc_ipa_default = EtcIPADefault.read() +domain_status = SssctlInfo.domain_status(etc_ipa_default['ipa_domain']) +current_dc = SssctlInfo.current_dc(etc_ipa_default['ipa_domain']) +current_hostname = etc_ipa_default['local_host_name'] +current_domain = etc_ipa_default['ipa_domain'] +hostgroups = '\n '.join(IPAInfo.get_host_groups(current_hostname)) + +def main(): + output = f''' +Local host name: {etc_ipa_default['local_host_name']} +Joined to domain: {etc_ipa_default['ipa_domain']} +Joined as: {etc_ipa_default['ipa_joined_name']} +Registered DC: {etc_ipa_default['registered_dc']} +Current DC: {current_dc} +Domain Status: {domain_status} +Host Group(s): {hostgroups} +''' + print(output) + +if __name__ == '__main__': + main() diff --git a/mangle/ipa/ipaquery.py b/mangle/ipa/ipaquery.py new file mode 100644 index 0000000..b0c012e --- /dev/null +++ b/mangle/ipa/ipaquery.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 +# -*-:python; coding:utf-8; -*- +# author: Louis Abel +# +# This scripts attempts to be an adquery lookalike. + +from python_freeipa import ClientMeta diff --git a/sync/lh-release-sync-to-staging.sh b/sync/lh-release-sync-to-staging.sh index 00031d1..ec40ec0 100644 --- a/sync/lh-release-sync-to-staging.sh +++ b/sync/lh-release-sync-to-staging.sh @@ -50,9 +50,9 @@ for COMPOSE in "${NONSIG_COMPOSE[@]}"; do mkdir -p "${TARGET}" pushd "${SYNCSRC}" || { echo "${COMPOSE}: Failed to change directory"; break; } if [[ "${COMPOSE}" != "Rocky" ]]; then - rsync_no_delete_staging_with_excludes "${TARGET}" "metadata" + rsync_delete_staging_with_excludes "${TARGET}" "metadata" else - rsync_no_delete_staging "${TARGET}" + rsync_delete_staging "${TARGET}" fi popd || { echo "${COMPOSE}: Failed to change directory"; break; } done