diff --git a/.github/workflows/build-and-publish-documentation.yml b/.github/workflows/build-and-publish-documentation.yml index 9061ba5..d99f457 100644 --- a/.github/workflows/build-and-publish-documentation.yml +++ b/.github/workflows/build-and-publish-documentation.yml @@ -13,7 +13,7 @@ on: jobs: deploy: - runs-on: ubuntu-20.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v2 with: diff --git a/README.md b/README.md index 65c5fc4..e7a49d0 100644 --- a/README.md +++ b/README.md @@ -32,8 +32,8 @@ Linuxmuster.net official | ❌ NO* :---: | :---: [Community support](https://ask.linuxmuster.net) | ✅ YES** Actively developed | ✅ YES -Maintainer organisation | Netzint GmbH -Primary maintainer | dorian@itsblue.de / andreas.till@netzint.de +Maintainer organisation | Linuxmuster.net +Primary maintainer | dorian@itsblue.de \* Even though this is not an official package, pull requests and issues are being looked at. ** The linuxmuster community consits of people who are nice and happy to help. They are not directly involved in the development though, and might not be able to help in any case. diff --git a/debian/changelog b/debian/changelog index 1b6d478..4095d25 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +linuxmuster-linuxclient7 (1.0.12) lmn73; urgency=medium + + * Implement fixes for Debian 13 (#85) + * Fix issues for new roles partens and staff (#84) + * Pass optionally specified domain to realm discover (#78) + + -- Dorian Zedler Sat, 8 Nov 2025 21:51:06 +0200 + linuxmuster-linuxclient7 (1.0.11) lmn73; urgency=medium * Merge pull request #76 from ks98/master, fixes mount problems with Kerberos after cifs-utils update. diff --git a/debian/control b/debian/control index 77de2f5..0122971 100644 --- a/debian/control +++ b/debian/control @@ -1,12 +1,12 @@ Source: linuxmuster-linuxclient7 Section: linuxmuster Priority: optional -Maintainer: Dorian Zedler , Andreas Till +Maintainer: Dorian Zedler Build-Depends: debhelper (>= 5.0.0) Standards-Version: 5.0.0 Package: linuxmuster-linuxclient7 Architecture: all -Depends: python3, python3-ldap, cifs-utils, ldb-tools, bind9-host, ipcalc, hxtools, network-manager, krb5-user, keyutils, samba, sssd, sssd-tools, libsss-sudo, adcli, libpam-sss, sudo, realmd, cups (>= 2.3.0), coreutils +Depends: python3, python3-ldap, cifs-utils, ldb-tools, bind9-host, ipcalc, hxtools, network-manager, krb5-user, keyutils, samba, sssd, sssd-tools, libsss-sudo, adcli, libpam-sss, sudo, realmd, cups (>= 2.3.0), coreutils, libcap2-bin Description: Package for Ubuntu clients to connect to the linuxmuster.net 7 active directory server. Conflicts: linuxmuster-client-adsso, linuxmuster-client-adsso7, ni-lmn-client-adsso diff --git a/docs/conf.py b/docs/conf.py index 8eb4e07..0bd9455 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -45,7 +45,6 @@ def setup(app): html_theme = 'sphinx_rtd_theme' html_logo = '_static/logo.png' -html_theme_path = [sphinx_rtd_theme.get_html_theme_path()] html_static_path = ['_static'] html_sidebars = { '**': [ @@ -91,4 +90,4 @@ def setup(app): 'Miscellaneous'), ] -intersphinx_mapping = {'https://docs.python.org/': None} +intersphinx_mapping = {'python': ('https://docs.python.org/3', None)} diff --git a/docs/python/otherHelpers.rst b/docs/python/otherHelpers.rst index 98e3f01..22d1d90 100644 --- a/docs/python/otherHelpers.rst +++ b/docs/python/otherHelpers.rst @@ -28,7 +28,7 @@ This module is used to setup, clean and upgrade the client. Members ------- -.. automodule:: linuxmusterLinuxclient7.seup +.. automodule:: linuxmusterLinuxclient7.setup :members: Module: imageHelper diff --git a/etc/profile.d/99-linuxmuster-linuxclient7.sh b/etc/profile.d/99-linuxmuster-linuxclient7.sh index 9b025a6..ab5b0f5 100755 --- a/etc/profile.d/99-linuxmuster-linuxclient7.sh +++ b/etc/profile.d/99-linuxmuster-linuxclient7.sh @@ -1,2 +1,2 @@ -scriptDir=$(linuxmuster-linuxclient7 get-constant scriptDir) +scriptDir=$(/usr/sbin/linuxmuster-linuxclient7 get-constant scriptDir) source $scriptDir/executeHookWithEnvFix.sh onLogin \ No newline at end of file diff --git a/etc/sudoers.d/99-linuxmuster-linuxclient7 b/etc/sudoers.d/99-linuxmuster-linuxclient7 index f5ba9b9..68ecd00 100644 --- a/etc/sudoers.d/99-linuxmuster-linuxclient7 +++ b/etc/sudoers.d/99-linuxmuster-linuxclient7 @@ -1,8 +1,6 @@ # # WARNING! All changes to this file will be overwritten by linuxmuster-linuxclient7 upgrades! # -%examusers ALL=(root) NOPASSWD: /usr/share/linuxmuster-linuxclient7/scripts/sudoTools -%role-student ALL=(root) NOPASSWD: /usr/share/linuxmuster-linuxclient7/scripts/sudoTools -%role-teacher ALL=(root) NOPASSWD: /usr/share/linuxmuster-linuxclient7/scripts/sudoTools +%domain\ users ALL=(root) NOPASSWD: /usr/share/linuxmuster-linuxclient7/scripts/sudoTools %role-schooladministrator ALL=(ALL:ALL) NOPASSWD: ALL %role-globaladministrator ALL=(ALL:ALL) NOPASSWD: ALL diff --git a/usr/lib/python3/dist-packages/linuxmusterLinuxclient7/keytab.py b/usr/lib/python3/dist-packages/linuxmusterLinuxclient7/keytab.py index ce8556a..1e6dbf0 100644 --- a/usr/lib/python3/dist-packages/linuxmusterLinuxclient7/keytab.py +++ b/usr/lib/python3/dist-packages/linuxmusterLinuxclient7/keytab.py @@ -24,16 +24,18 @@ def patchKeytab(): 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"): + elif len(entry.principal.components) == 2 and entry.principal.components[0].data in ["host", "HOST", "RestrictedKrbHost"]: rc, networkConfig = config.network() if not rc: continue newData = "" domain = networkConfig["domain"] - if domain in entry.principal.components[1].data: + if entry.principal.components[0].data == "RestrictedKrbHost": newData = computer.hostname().lower() + "." + domain - else: + elif entry.principal.components[0].data == "HOST": + newData = computer.hostname().upper() + "." + domain + elif entry.principal.components[0].data == "host": newData = computer.hostname().upper() entry.principal.components[1].data = newData diff --git a/usr/lib/python3/dist-packages/linuxmusterLinuxclient7/realm.py b/usr/lib/python3/dist-packages/linuxmusterLinuxclient7/realm.py index 3847529..ea176cc 100644 --- a/usr/lib/python3/dist-packages/linuxmusterLinuxclient7/realm.py +++ b/usr/lib/python3/dist-packages/linuxmusterLinuxclient7/realm.py @@ -123,14 +123,20 @@ def getJoinedDomains(): return True, list(filter(None, result.stdout.split("\n"))) -def discoverDomains(): +def discoverDomains(domain=None): """ Searches for avialable domains on the current network + :param domain: The domain to discover (optional) + :type domain: str :return: Tuple (success, list of available domains) :rtype: tuple """ - result = subprocess.run("realm discover --name-only", stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, shell=True) + command = ["realm", "discover", "--name-only"] + if domain != None: + command.append(domain) + + result = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) if result.returncode != 0: logging.error("Failed to discover available domains!") diff --git a/usr/lib/python3/dist-packages/linuxmusterLinuxclient7/setup.py b/usr/lib/python3/dist-packages/linuxmusterLinuxclient7/setup.py index 85994fe..0494071 100644 --- a/usr/lib/python3/dist-packages/linuxmusterLinuxclient7/setup.py +++ b/usr/lib/python3/dist-packages/linuxmusterLinuxclient7/setup.py @@ -20,6 +20,9 @@ def setup(domain=None, user=None): if not _cleanOldDomainJoins(): return False + + if not _checkSssdKrb5ChildCaps(): + return False rc, domain = _findDomain(domain) if not rc: @@ -83,6 +86,11 @@ def status(): return False logging.info("Linuxmuster-linuxclient7 is setup!") + + logging.info("Checking sssd krb5_child capabilities...") + if not _checkSssdKrb5ChildCaps(): + return False + logging.info("Testing if domain is joined...") logging.info("Checking joined domains") @@ -210,7 +218,7 @@ def _cleanOldDomainJoins(): def _findDomain(domain=None): logging.info("Trying to discover available domains...") - rc, availableDomains = realm.discoverDomains() + rc, availableDomains = realm.discoverDomains(domain) if not rc or len(availableDomains) < 1: logging.error("Could not discover any domain!") return False, None @@ -248,7 +256,7 @@ def _preparePam(): logging.info('Updating pam configuration ... ') subprocess.call(['pam-auth-update', '--package', '--enable', 'libpam-mount', 'pwquality', 'sss', '--force']) ## mkhomedir was injected in template not using pam-auth-update - subprocess.call(['pam-auth-update', '--package', '--remove', 'krb5', 'mkhomedir', '--force']) + subprocess.call(['pam-auth-update', '--package', '--remove', 'krb5', 'winbind', 'mkhomedir', '--force']) return True @@ -361,4 +369,45 @@ def _deleteObsoleteFiles(): logging.info(f"* {obsoleteDirectory}") fileHelper.deleteDirectory(obsoleteDirectory) - return True \ No newline at end of file + return True + +def _parseVersion(versionString): + return tuple(int(p) for p in versionString.split(".")) + +def _getSssdVersion(): + try: + out = subprocess.check_output(["sssd", "--version"], text=True).strip() + return _parseVersion(out) + except Exception as e: + raise RuntimeError(f"Could not read SSSD version: {e}") + +def _checkSssdKrb5ChildCaps(): + """ + Checks if /usr/libexec/sssd/krb5_child has the correct capabilities set. + + :return: True if capabilities are correctly set, False otherwise + :rtype: bool + """ + + if _getSssdVersion() < _parseVersion("2.9.5"): + # Prior to this version, the capabilities were not needed + logging.info("SSSD version < 2.9.5 detected, skipping capability check") + return True + + sssdKrb5ChildPath = "/usr/libexec/sssd/krb5_child" + result = subprocess.check_output(["getcap", sssdKrb5ChildPath], text=True) + + expectedCaps = ["cap_dac_read_search", "cap_setgid", "cap_setuid=p"] + for cap in expectedCaps: + if not cap in result: + logging.error(f"Missing capability: {cap}") + print() + print("===============================================================================================") + print("sssd krb5_child does not have the correct capabilities set. The login WILL NOT WORK!") + print("Please reinstall sssd-krb5-common to fix this issue.") + print("On Debian-based systems you can do this by running:") + print(" sudo apt reinstall sssd-krb5-common") + print("===============================================================================================\n") + return False + + return True diff --git a/usr/share/linuxmuster-linuxclient7/scripts/executeHookWithEnvFix.sh b/usr/share/linuxmuster-linuxclient7/scripts/executeHookWithEnvFix.sh index db35bde..73e24ed 100755 --- a/usr/share/linuxmuster-linuxclient7/scripts/executeHookWithEnvFix.sh +++ b/usr/share/linuxmuster-linuxclient7/scripts/executeHookWithEnvFix.sh @@ -1,7 +1,7 @@ # This script calls the desired hook and sources the temporary env # file afterwards to apply environment changes from lmn-export and lmn-unset -scriptDir=$(linuxmuster-linuxclient7 get-constant scriptDir) +scriptDir=$(/usr/sbin/linuxmuster-linuxclient7 get-constant scriptDir) if [ ! -f $scriptDir/$1 ]; then echo "Unknown hook: $1!" @@ -10,7 +10,8 @@ if [ ! -f $scriptDir/$1 ]; then fi export LinuxmusterLinuxclient7EnvFixActive=1 -tmpEnvFile=$(linuxmuster-linuxclient7 get-constant tmpEnvironmentFilePath) +export PATH=$PATH:/usr/sbin/lmn-export:/usr/sbin/lmn-unset +tmpEnvFile=$(/usr/sbin/linuxmuster-linuxclient7 get-constant tmpEnvironmentFilePath) rm -f $tmpEnvFile