Import Upstream version 4.12.4

This commit is contained in:
geos_one
2025-08-12 22:28:56 +02:00
parent 03a8170b15
commit 9181ee2487
1629 changed files with 874094 additions and 554378 deletions

View File

@@ -7,6 +7,7 @@ dbusconfdir = $(sysconfdir)/dbus-1/system.d
dist_noinst_DATA = \
com.redhat.idm.trust-fetch-domains.in \
org.freeipa.server.trust-enable-agent.in \
org.freeipa.server.config-enable-sid.in \
etc/oddjobd.conf.d/oddjobd-ipa-trust.conf.in \
etc/oddjobd.conf.d/ipa-server.conf.in \
$(NULL)
@@ -18,6 +19,7 @@ dist_oddjob_SCRIPTS = \
nodist_oddjob_SCRIPTS = \
com.redhat.idm.trust-fetch-domains \
org.freeipa.server.trust-enable-agent \
org.freeipa.server.config-enable-sid \
$(NULL)

View File

@@ -1,7 +1,7 @@
# Makefile.in generated by automake 1.16.2 from Makefile.am.
# Makefile.in generated by automake 1.17 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
# Copyright (C) 1994-2024 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@@ -71,6 +71,8 @@ am__make_running_with_option = \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
am__rm_f = rm -f $(am__rm_f_notfound)
am__rm_rf = rm -rf $(am__rm_f_notfound)
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
@@ -131,10 +133,9 @@ am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
{ test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && echo $$files | $(am__xargs_n) 40 $(am__rm_f); }; \
}
am__installdirs = "$(DESTDIR)$(oddjobdir)" "$(DESTDIR)$(oddjobdir)" \
"$(DESTDIR)$(dbusconfdir)" "$(DESTDIR)$(oddjobconfdir)"
@@ -183,6 +184,8 @@ CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CRYPTO_CFLAGS = @CRYPTO_CFLAGS@
CRYPTO_LIBS = @CRYPTO_LIBS@
CSCOPE = @CSCOPE@
CTAGS = @CTAGS@
CYGPATH_W = @CYGPATH_W@
DATA_VERSION = @DATA_VERSION@
DEFS = @DEFS@
@@ -196,8 +199,10 @@ ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
ETAGS = @ETAGS@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
FILECMD = @FILECMD@
GETTEXT_DOMAIN = @GETTEXT_DOMAIN@
GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GIT_BRANCH = @GIT_BRANCH@
@@ -205,6 +210,7 @@ GIT_VERSION = @GIT_VERSION@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
GREP = @GREP@
HTTPD_GROUP = @HTTPD_GROUP@
INI_CFLAGS = @INI_CFLAGS@
INI_LIBS = @INI_LIBS@
INSTALL = @INSTALL@
@@ -217,9 +223,12 @@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
IPAPLATFORM = @IPAPLATFORM@
IPA_DATA_DIR = @IPA_DATA_DIR@
IPA_SYSCONF_DIR = @IPA_SYSCONF_DIR@
JANSSON_CFLAGS = @JANSSON_CFLAGS@
JANSSON_LIBS = @JANSSON_LIBS@
JSLINT = @JSLINT@
KRAD_LIBS = @KRAD_LIBS@
KRB5KDC_SERVICE = @KRB5KDC_SERVICE@
KRB5_BUILD_VERSION = @KRB5_BUILD_VERSION@
KRB5_CFLAGS = @KRB5_CFLAGS@
KRB5_GSSAPI_CFLAGS = @KRB5_GSSAPI_CFLAGS@
KRB5_GSSAPI_LIBS = @KRB5_GSSAPI_LIBS@
@@ -228,6 +237,8 @@ LD = @LD@
LDAP_CFLAGS = @LDAP_CFLAGS@
LDAP_LIBS = @LDAP_LIBS@
LDFLAGS = @LDFLAGS@
LIBCURL_CFLAGS = @LIBCURL_CFLAGS@
LIBCURL_LIBS = @LIBCURL_LIBS@
LIBICONV = @LIBICONV@
LIBINTL = @LIBINTL@
LIBINTL_LIBS = @LIBINTL_LIBS@
@@ -287,6 +298,8 @@ PLATFORM_PYTHON = @PLATFORM_PYTHON@
POPT_CFLAGS = @POPT_CFLAGS@
POPT_LIBS = @POPT_LIBS@
POSUB = @POSUB@
PWQUALITY_CFLAGS = @PWQUALITY_CFLAGS@
PWQUALITY_LIBS = @PWQUALITY_LIBS@
PYLINT = @PYLINT@
PYTHON = @PYTHON@
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
@@ -295,9 +308,12 @@ PYTHON_PLATFORM = @PYTHON_PLATFORM@
PYTHON_PREFIX = @PYTHON_PREFIX@
PYTHON_VERSION = @PYTHON_VERSION@
RANLIB = @RANLIB@
RESOLV_LIBS = @RESOLV_LIBS@
RPMLINT = @RPMLINT@
SAMBA40EXTRA_LIBPATH = @SAMBA40EXTRA_LIBPATH@
SAMBAUTIL_CFLAGS = @SAMBAUTIL_CFLAGS@
SAMBAUTIL_LIBS = @SAMBAUTIL_LIBS@
SAMBA_SECURITY_LIBS = @SAMBA_SECURITY_LIBS@
SASL_CFLAGS = @SASL_CFLAGS@
SASL_LIBS = @SASL_LIBS@
SED = @SED@
@@ -336,8 +352,10 @@ ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__rm_f_notfound = @am__rm_f_notfound@
am__tar = @am__tar@
am__untar = @am__untar@
am__xargs_n = @am__xargs_n@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
@@ -383,6 +401,7 @@ sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
sysconfenvdir = @sysconfenvdir@
systemdcatalogdir = @systemdcatalogdir@
systemdsystemunitdir = @systemdsystemunitdir@
systemdtmpfilesdir = @systemdtmpfilesdir@
target_alias = @target_alias@
@@ -396,6 +415,7 @@ dbusconfdir = $(sysconfdir)/dbus-1/system.d
dist_noinst_DATA = \
com.redhat.idm.trust-fetch-domains.in \
org.freeipa.server.trust-enable-agent.in \
org.freeipa.server.config-enable-sid.in \
etc/oddjobd.conf.d/oddjobd-ipa-trust.conf.in \
etc/oddjobd.conf.d/ipa-server.conf.in \
$(NULL)
@@ -407,6 +427,7 @@ dist_oddjob_SCRIPTS = \
nodist_oddjob_SCRIPTS = \
com.redhat.idm.trust-fetch-domains \
org.freeipa.server.trust-enable-agent \
org.freeipa.server.config-enable-sid \
$(NULL)
dist_dbusconf_DATA = \
@@ -578,7 +599,6 @@ ctags CTAGS:
cscope cscopelist:
distdir: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) distdir-am
@@ -641,11 +661,11 @@ install-strip:
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
-$(am__rm_f) $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
-$(am__rm_f) $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || $(am__rm_f) $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@@ -754,3 +774,10 @@ python_scripts_sub: $(PYTHON_SHEBANG)
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:
# Tell GNU make to disable its built-in pattern rules.
%:: %,v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%

View File

@@ -4,22 +4,18 @@ from ipaserver import dcerpc
from ipaserver.install.installutils import ScriptError
from ipapython import config, ipautil
from ipalib import api
from ipalib.facts import is_ipa_configured
from ipapython.dn import DN
from ipapython.dnsutil import DNSName
from ipaplatform.constants import constants
from ipaplatform.paths import paths
import io
import sys
import os
import pwd
import tempfile
import textwrap
import six
import gssapi
from ipalib.install.kinit import kinit_keytab, kinit_password
from ipapython.admintool import admin_cleanup_global_argv
if six.PY3:
unicode = str
@@ -57,11 +53,13 @@ def parse_options():
"--password",
action="store",
dest="password",
help="Display debugging information",
help="Password for Active Directory administrator",
sensitive=True
)
options, args = parser.parse_args()
safe_options = parser.get_safe_opts(options)
admin_cleanup_global_argv(parser, options, sys.argv)
# We only use first argument of the passed args but as D-BUS interface
# in oddjobd cannot expose optional, we fill in empty slots from IPA side
@@ -97,9 +95,8 @@ def retrieve_keytab(api, ccache_name, oneway_keytab_name, oneway_principal):
)
# Make sure SSSD is able to read the keytab
try:
sssd = pwd.getpwnam(constants.SSSD_USER)
os.chown(oneway_keytab_name, sssd[2], sssd[3])
except KeyError:
constants.SSSD_USER.chown(oneway_keytab_name)
except ValueError:
# If user 'sssd' does not exist, we don't need to chown from root to sssd
# because it means SSSD does not run as sssd user
pass
@@ -123,43 +120,6 @@ def get_forest_root_domain(api_instance, trusted_domain, server=None):
return remote_domain.info["dns_forest"]
def generate_krb5_config(realm, server):
"""Generate override krb5 config file for trusted domain DC access
:param realm: realm of the trusted AD domain
:param server: server to override KDC to
:returns: tuple (temporary config file name, KRB5_CONFIG string)
"""
cfg = paths.KRB5_CONF
tcfg = None
if server:
content = textwrap.dedent(u"""
[realms]
%s = {
kdc = %s
}
""") % (
realm.upper(),
server,
)
(fd, tcfg) = tempfile.mkstemp(dir="/run/ipa",
prefix="krb5conf", text=True)
with io.open(fd, mode='w', encoding='utf-8') as o:
o.write(content)
cfg = ":".join([tcfg, cfg])
return (tcfg, cfg)
if not is_ipa_configured():
# LSB status code 6: program is not configured
raise ScriptError(
"IPA is not configured "
+ "(see man pages of ipa-server-install for help)",
6,
)
if not os.getegid() == 0:
# LSB status code 4: user had insufficient privilege
raise ScriptError("You must be root to run ipactl.", 4)
@@ -221,7 +181,9 @@ api.Backend.ldap2.connect(ccache_name)
# Retrieve own NetBIOS name and trusted forest's name.
# We use script's input to retrieve the trusted forest's name to sanitize input
# for file-level access as we might need to wipe out keytab in /var/lib/sss/keytabs
# for file-level access as we might need to wipe out keytab in
# paths.SSSD_KEYTABS_DIR
own_trust_dn = DN(
("cn", api.env.domain), ("cn", "ad"), ("cn", "etc"), api.env.basedn
)
@@ -236,97 +198,95 @@ trusted_domain = trusted_domain_entry.single_value.get("cn").lower()
# At this point if we didn't find trusted forest name, an exception will be raised
# and script will quit. This is actually intended.
rc = 0
# Generate MIT Kerberos configuration file that potentially overlays
# the KDC to connect to for a trusted domain to allow --server option
# to take precedence.
cfg_file, cfg = generate_krb5_config(trusted_domain, options.server)
with ipautil.private_krb5_config(trusted_domain, options.server) as cfg_file:
if not (options.admin and options.password):
oneway_keytab_name = os.path.join(paths.SSSD_KEYTABS_DIR,
trusted_domain + ".keytab")
if not (options.admin and options.password):
oneway_keytab_name = "/var/lib/sss/keytabs/" + trusted_domain + ".keytab"
oneway_principal = str(
"%s$@%s" % (own_trust_flatname, trusted_domain.upper())
)
oneway_principal = str(
"%s$@%s" % (own_trust_flatname, trusted_domain.upper())
)
# If keytab does not exist, retrieve it
if not os.path.isfile(oneway_keytab_name):
retrieve_keytab(api, ccache_name, oneway_keytab_name, oneway_principal)
# If keytab does not exist, retrieve it
if not os.path.isfile(oneway_keytab_name):
retrieve_keytab(api, ccache_name,
oneway_keytab_name, oneway_principal)
try:
have_ccache = False
try:
# The keytab may have stale key material (from older trust-add run)
have_ccache = False
try:
# The keytab may have stale key material (from older trust-add run)
cred = kinit_keytab(
oneway_principal,
oneway_keytab_name,
oneway_ccache_name,
)
if cred.lifetime > 0:
have_ccache = True
except (gssapi.exceptions.ExpiredCredentialsError, gssapi.raw.misc.GSSError):
pass
if not have_ccache:
if os.path.exists(oneway_ccache_name):
os.unlink(oneway_ccache_name)
kinit_keytab(
oneway_principal,
oneway_keytab_name,
oneway_ccache_name,
)
except (gssapi.exceptions.GSSError, gssapi.raw.misc.GSSError):
# If there was failure on using keytab, assume it is stale and retrieve again
retrieve_keytab(api, ccache_name, oneway_keytab_name, oneway_principal)
if os.path.exists(oneway_ccache_name):
os.unlink(oneway_ccache_name)
cred = kinit_keytab(
oneway_principal,
oneway_keytab_name,
oneway_ccache_name,
config=cfg,
)
if cred.lifetime > 0:
have_ccache = True
except (gssapi.exceptions.ExpiredCredentialsError, gssapi.raw.misc.GSSError):
pass
if not have_ccache:
if os.path.exists(oneway_ccache_name):
os.unlink(oneway_ccache_name)
kinit_keytab(
oneway_principal,
oneway_keytab_name,
oneway_ccache_name,
config=cfg,
)
except (gssapi.exceptions.GSSError, gssapi.raw.misc.GSSError):
# If there was failure on using keytab, assume it is stale and retrieve again
retrieve_keytab(api, ccache_name, oneway_keytab_name, oneway_principal)
if os.path.exists(oneway_ccache_name):
os.unlink(oneway_ccache_name)
cred = kinit_keytab(
oneway_principal,
oneway_keytab_name,
else:
cred = kinit_password(
options.admin,
options.password,
oneway_ccache_name,
config=cfg,
canonicalize=True,
enterprise=True,
)
else:
cred = kinit_password(
options.admin,
options.password,
oneway_ccache_name,
canonicalize=True,
enterprise=True,
config=cfg,
if cred and cred.lifetime > 0:
have_ccache = True
if not have_ccache:
rc = 1
raise GeneratorExit
# We are done: we have ccache with TDO credentials and can fetch domains
ipa_domain = api.env.domain
os.environ["KRB5CCNAME"] = oneway_ccache_name
# retrieve the forest root domain name and contact it to retrieve trust
# topology info
forest_root = get_forest_root_domain(
api, trusted_domain, server=options.server
)
domains = dcerpc.fetch_domains(
api, ipa_domain, forest_root, creds=True, server=options.server
)
if cred and cred.lifetime > 0:
have_ccache = True
# We still need to use the override for KDC configuration in case the --server
# was forced, thus only switch to the old ccache.
if old_ccache:
os.environ["KRB5CCNAME"] = old_ccache
if not have_ccache:
sys.exit(1)
# We are done: we have ccache with TDO credentials and can fetch domains
ipa_domain = api.env.domain
os.environ["KRB5CCNAME"] = oneway_ccache_name
os.environ["KRB5_CONFIG"] = cfg
trust_domain_object = api.Command.trust_show(trusted_domain, raw=True)[
"result"
]
# retrieve the forest root domain name and contact it to retrieve trust
# topology info
forest_root = get_forest_root_domain(
api, trusted_domain, server=options.server
)
domains = dcerpc.fetch_domains(
api, ipa_domain, forest_root, creds=True, server=options.server
)
trust.add_new_domains_from_trust(api, None, trust_domain_object, domains)
if old_ccache:
os.environ["KRB5CCNAME"] = old_ccache
if old_config:
os.environ["KRB5_CONFIG"] = old_config
if cfg_file:
os.remove(cfg_file)
trust_domain_object = api.Command.trust_show(trusted_domain, raw=True)[
"result"
]
trust.add_new_domains_from_trust(api, None, trust_domain_object, domains)
sys.exit(0)
sys.exit(rc)

View File

@@ -17,6 +17,12 @@
prepend_user_name="no"
argument_passing_method="cmdline"/>
</method>
<method name="config_enable_sid">
<helper exec="/usr/local/libexec/ipa/oddjob/org.freeipa.server.config-enable-sid"
arguments="10"
prepend_user_name="no"
argument_passing_method="cmdline"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<allow min_uid="0" max_uid="0"/>

View File

@@ -17,6 +17,12 @@
prepend_user_name="no"
argument_passing_method="cmdline"/>
</method>
<method name="config_enable_sid">
<helper exec="@ODDJOBDIR@/org.freeipa.server.config-enable-sid"
arguments="10"
prepend_user_name="no"
argument_passing_method="cmdline"/>
</method>
</interface>
<interface name="org.freedesktop.DBus.Introspectable">
<allow min_uid="0" max_uid="0"/>

View File

@@ -0,0 +1,76 @@
#!/usr/bin/python3
#
# Copyright (C) 2021 FreeIPA Contributors see COPYING for license
#
import logging
from ipalib import api
from ipalib.install import sysrestore
from ipaplatform.paths import paths
from ipapython import ipaldap
from ipapython.admintool import AdminTool
from ipaserver.install import adtrust, adtrustinstance
logger = logging.getLogger(__name__)
class IPAConfigEnableSid(AdminTool):
command_name = "ipa-enable-sid"
log_file_name = paths.IPASERVER_ENABLESID_LOG
usage = "%prog"
description = "Enable SID generation"
@classmethod
def add_options(cls, parser):
super(IPAConfigEnableSid, cls).add_options(parser)
parser.add_option(
"--add-sids",
dest="add_sids", default=False, action="store_true",
help="Add SIDs for existing users and groups as the final step"
)
parser.add_option(
"--netbios-name",
dest="netbios_name", default=None,
help="NetBIOS name of the IPA domain"
)
parser.add_option(
"--reset-netbios-name",
dest="reset_netbios_name", default=False, action="store_true",
help="Force reset of the existing NetBIOS name"
)
def validate_options(self):
super(IPAConfigEnableSid, self).validate_options(needs_root=True)
def run(self):
api.bootstrap(in_server=True, confdir=paths.ETC_IPA)
api.finalize()
try:
api.Backend.ldap2.connect()
fstore = sysrestore.FileStore(paths.SYSRESTORE)
smb = adtrustinstance.ADTRUSTInstance(fstore, False)
smb.realm = api.env.realm
smb.autobind = ipaldap.AUTOBIND_ENABLED
smb.setup(api.env.host, api.env.realm,
self.options.netbios_name,
self.options.reset_netbios_name,
adtrust.DEFAULT_PRIMARY_RID_BASE,
adtrust.DEFAULT_SECONDARY_RID_BASE,
self.options.add_sids,
enable_compat=False)
smb.find_local_id_range()
smb.create_instance()
finally:
if api.Backend.ldap2.isconnected():
api.Backend.ldap2.disconnect()
return 0
IPAConfigEnableSid.run_cli()