Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build-and-publish-documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ on:

jobs:
deploy:
runs-on: ubuntu-20.04
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v2
with:
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
8 changes: 8 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -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 <dorian@itsblue.de> 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.
Expand Down
4 changes: 2 additions & 2 deletions debian/control
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
Source: linuxmuster-linuxclient7
Section: linuxmuster
Priority: optional
Maintainer: Dorian Zedler <dorian@itsblue.de>, Andreas Till <andreas.till@netzint.de>
Maintainer: Dorian Zedler <dorian@itsblue.de>
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
3 changes: 1 addition & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
'**': [
Expand Down Expand Up @@ -91,4 +90,4 @@ def setup(app):
'Miscellaneous'),
]

intersphinx_mapping = {'https://docs.python.org/': None}
intersphinx_mapping = {'python': ('https://docs.python.org/3', None)}
2 changes: 1 addition & 1 deletion docs/python/otherHelpers.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion etc/profile.d/99-linuxmuster-linuxclient7.sh
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
scriptDir=$(linuxmuster-linuxclient7 get-constant scriptDir)
scriptDir=$(/usr/sbin/linuxmuster-linuxclient7 get-constant scriptDir)
source $scriptDir/executeHookWithEnvFix.sh onLogin
4 changes: 1 addition & 3 deletions etc/sudoers.d/99-linuxmuster-linuxclient7
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
10 changes: 8 additions & 2 deletions usr/lib/python3/dist-packages/linuxmusterLinuxclient7/realm.py
Original file line number Diff line number Diff line change
Expand Up @@ -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!")
Expand Down
55 changes: 52 additions & 3 deletions usr/lib/python3/dist-packages/linuxmusterLinuxclient7/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -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")
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -361,4 +369,45 @@ def _deleteObsoleteFiles():
logging.info(f"* {obsoleteDirectory}")
fileHelper.deleteDirectory(obsoleteDirectory)

return True
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
Original file line number Diff line number Diff line change
@@ -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!"
Expand All @@ -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

Expand Down