Merge branch 'upstream'

This commit is contained in:
Timo Aaltonen committed 2025-06-25 12:36:07 +03:00
commit a3857e8611
31 files changed
+308 -103

No files matched your search

+1 -1
View File
@@ -21,7 +21,7 @@
########################################################
define(IPA_VERSION_MAJOR, 4)
define(IPA_VERSION_MINOR, 12)
define(IPA_VERSION_RELEASE, 2)
define(IPA_VERSION_RELEASE, 4)
########################################################
# For 'pre' releases the version will be #
+24 -7
View File
@@ -530,26 +530,43 @@ int ipadb_get_connection(struct ipadb_context *ipactx)
/* get adtrust options using default refresh interval */
ret = ipadb_reinit_mspac(ipactx, false, &stmsg);
if (ret && stmsg)
krb5_klog_syslog(LOG_WARNING, "MS-PAC generator: %s", stmsg);
if (ret) {
if (stmsg) {
krb5_klog_syslog(LOG_WARNING, "MS-PAC generator: %s", stmsg);
}
/* Initialization of the MS-PAC generator is an optional dependency.
* Fail only if the connection was lost. */
if (!ipactx->lcontext) {
goto done;
}
}
ret = 0;
done:
ldap_msgfree(res);
/* LDAP context should never be null on success, but keep this test out of
* security to make sure we do not return an invalid context. */
if (ret == 0 && !ipactx->lcontext) {
krb5_klog_syslog(LOG_WARNING, "Internal malfunction: LDAP connection "
"process resulted in an invalid context "
"(please report this incident)");
ret = LDAP_SERVER_DOWN;
}
if (ret) {
/* Cleanup LDAP context if connection failed. */
if (ipactx->lcontext) {
ldap_unbind_ext_s(ipactx->lcontext, NULL, NULL);
ipactx->lcontext = NULL;
}
if (ret == LDAP_SERVER_DOWN) {
return ETIMEDOUT;
}
return EIO;
/* Replace LDAP error code by POSIX error code. */
ret = ret == LDAP_SERVER_DOWN ? ETIMEDOUT : EIO;
}
return 0;
return ret;
}
static krb5_principal ipadb_create_local_tgs(krb5_context kcontext,
+14 -10
View File
@@ -31,6 +31,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <sys/random.h>
#include <sys/uio.h>
#include "internal.h"
@@ -93,6 +94,7 @@ static void oauth2_on_child_writable(verto_ctx *vctx, verto_ev *ev)
(void)vctx; /* Unused */
ssize_t io;
struct child_ctx *child_ctx;
struct iovec iov[3];
child_ctx = verto_get_private(ev);
if (child_ctx == NULL) {
@@ -102,15 +104,18 @@ static void oauth2_on_child_writable(verto_ctx *vctx, verto_ev *ev)
}
if (child_ctx->oauth2_state == OAUTH2_GET_DEVICE_CODE) {
/* no input needed */
verto_del(ev);
return;
io = write(verto_get_fd(ev), child_ctx->item->idp.ipaidpClientSecret,
strlen(child_ctx->item->idp.ipaidpClientSecret));
} else {
iov[0].iov_base = child_ctx->item->idp.ipaidpClientSecret;
iov[0].iov_len = strlen(child_ctx->item->idp.ipaidpClientSecret);
iov[1].iov_base = "\n";
iov[1].iov_len = 1;
iov[2].iov_base = child_ctx->saved_item->oauth2.device_code_reply;
iov[2].iov_len = strlen(child_ctx->saved_item->oauth2.device_code_reply);
io = writev(verto_get_fd(ev), iov, 3);
}
io = write(verto_get_fd(ev),
child_ctx->saved_item->oauth2.device_code_reply,
strlen(child_ctx->saved_item->oauth2.device_code_reply));
otpd_queue_item_free(child_ctx->saved_item);
if (io < 0) {
@@ -429,8 +434,7 @@ int oauth2(struct otpd_queue_item **item, enum oauth2_state oauth2_state)
args[args_idx++] = (*item)->idp.ipaidpClientID;
if ((*item)->idp.ipaidpClientSecret) {
args[args_idx++] = "--client-secret";
args[args_idx++] = (*item)->idp.ipaidpClientSecret;
args[args_idx++] = "--client-secret-stdin";
}
if ((*item)->idp.ipaidpScope) {
@@ -15,6 +15,7 @@ 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
@@ -52,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
+1
View File
@@ -239,6 +239,7 @@ objectClass: ipasshuser
uid: admin
krbPrincipalName: admin@$REALM
krbPrincipalName: root@$REALM
krbCanonicalName: admin@$REALM
cn: Administrator
sn: Administrator
uidNumber: $IDSTART
+3 -4
View File
@@ -29,19 +29,17 @@ import sys
import six
from optparse import SUPPRESS_HELP # pylint: disable=deprecated-module
from ipalib.install import sysrestore
from ipaserver.install import adtrust, service
from ipaserver.install.installutils import (
read_password,
check_server_configuration,
run_script)
from ipapython.admintool import ScriptError
from ipapython.admintool import ScriptError, admin_cleanup_global_argv
from ipapython import version
from ipapython import ipautil
from ipalib import api, errors, krb_utils
from ipapython.config import IPAOptionParser
from ipapython.config import IPAOptionParser, SUPPRESS_HELP
from ipaplatform.paths import paths
from ipapython.ipa_log_manager import standard_logging_setup
@@ -95,6 +93,7 @@ def parse_options():
options, _args = parser.parse_args()
safe_options = parser.get_safe_opts(options)
admin_cleanup_global_argv(parser, options, sys.argv)
return safe_options, options
+2
View File
@@ -42,6 +42,7 @@ from ipalib.constants import DOMAIN_LEVEL_1
from ipapython.config import IPAOptionParser
from ipapython.ipa_log_manager import standard_logging_setup
from ipaplatform.paths import paths
from ipapython.admintool import admin_cleanup_global_argv
logger = logging.getLogger(os.path.basename(__file__))
@@ -132,6 +133,7 @@ def parse_options():
options, args = parser.parse_args()
safe_options = parser.get_safe_opts(options)
admin_cleanup_global_argv(parser, options, sys.argv)
if args:
parser.error("Too many arguments provided")
+4 -2
View File
@@ -24,13 +24,13 @@ from __future__ import print_function
import sys
from ipaplatform.paths import paths
try:
from optparse import OptionParser # pylint: disable=deprecated-module
from ipapython import ipautil, config
from ipaserver.install import installutils
from ipaserver.install.ldapupdate import LDAPUpdate
from ipalib import api, errors
from ipapython.ipa_log_manager import standard_logging_setup
from ipapython.dn import DN
from ipapython.admintool import admin_cleanup_global_argv
except ImportError as e:
print("""\
There was a problem importing one of the required Python modules. The
@@ -46,7 +46,8 @@ nis_config_dn = DN(('cn', 'NIS Server'), ('cn', 'plugins'), ('cn', 'config'))
def parse_options():
usage = "%prog [options] <enable|disable|status>\n"
usage += "%prog [options]\n"
parser = OptionParser(usage=usage, formatter=config.IPAFormatter())
parser = config.IPAOptionParser(usage=usage,
formatter=config.IPAFormatter())
parser.add_option("-d", "--debug", action="store_true", dest="debug",
help="Display debugging information about the update(s)")
@@ -55,6 +56,7 @@ def parse_options():
config.add_standard_options(parser)
options, args = parser.parse_args()
admin_cleanup_global_argv(parser, options, sys.argv)
return options, args
+6 -6
View File
@@ -32,8 +32,8 @@ from ipaserver.install import (replication, installutils, bindinstance,
from ipalib import api, errors
from ipalib.constants import FQDN
from ipalib.util import has_managed_topology, print_replication_status
from ipapython import ipautil, ipaldap, version
from ipapython.admintool import ScriptError
from ipapython import ipautil, ipaldap, version, config
from ipapython.admintool import admin_cleanup_global_argv, ScriptError
from ipapython.dn import DN
logger = logging.getLogger(os.path.basename(__file__))
@@ -54,11 +54,10 @@ commands = {
def parse_options():
from optparse import OptionParser # pylint: disable=deprecated-module
parser = OptionParser(version=version.VERSION)
parser = config.IPAOptionParser(version=version.VERSION)
parser.add_option("-H", "--host", dest="host", help="starting host")
parser.add_option("-p", "--password", dest="dirman_passwd", help="Directory Manager password")
parser.add_option("-p", "--password", dest="dirman_passwd", sensitive=True,
help="Directory Manager password")
parser.add_option("-v", "--verbose", dest="verbose", action="store_true", default=False,
help="provide additional information")
parser.add_option("-f", "--force", dest="force", action="store_true", default=False,
@@ -66,6 +65,7 @@ def parse_options():
parser.add_option("--from", dest="fromhost", help="Host to get data from")
options, args = parser.parse_args()
admin_cleanup_global_argv(parser, options, sys.argv)
valid_syntax = False
+5 -3
View File
@@ -24,7 +24,6 @@ import logging
import os
import re
import sys
from optparse import OptionParser # pylint: disable=deprecated-module
from ipaplatform.paths import paths
from ipapython import config
@@ -32,6 +31,7 @@ from ipaserver.install import installutils
from ipalib import api, errors
from ipapython.ipa_log_manager import standard_logging_setup
from ipapython.dn import DN
from ipapython.admintool import admin_cleanup_global_argv
logger = logging.getLogger(os.path.basename(__file__))
@@ -39,7 +39,8 @@ logger = logging.getLogger(os.path.basename(__file__))
def parse_options():
usage = "%prog [options] <status|enable|disable>\n"
usage += "%prog [options]\n"
parser = OptionParser(usage=usage, formatter=config.IPAFormatter())
parser = config.IPAOptionParser(usage=usage,
formatter=config.IPAFormatter())
parser.add_option("-d", "--debug", action="store_true", dest="debug",
help="Display debugging information about the update(s)")
@@ -50,9 +51,10 @@ def parse_options():
action="store_true",
help="List available Managed Entries")
parser.add_option("-p", "--password", dest="dirman_password",
help="Directory Manager password")
sensitive=True, help="Directory Manager password")
options, args = parser.parse_args()
admin_cleanup_global_argv(parser, options, sys.argv)
return options, args
+4 -3
View File
@@ -23,15 +23,15 @@ from __future__ import print_function
import logging
from ipapython import ipachangeconf
from ipapython.config import IPAOptionParser
from ipapython.config import (IPAOptionParser, OptionGroup,
OptionValueError)
from ipapython.admintool import admin_cleanup_global_argv
from ipapython.dn import DN
from ipapython import version
from ipapython import ipautil, certdb
from ipalib import api, errors, x509
from ipalib.constants import FQDN
from ipaserver.install import installutils
# pylint: disable=deprecated-module
from optparse import OptionGroup, OptionValueError
# pylint: enable=deprecated-module
from ipapython.ipa_log_manager import standard_logging_setup
import copy
@@ -189,6 +189,7 @@ def parse_options():
options, _args = parser.parse_args()
safe_options = parser.get_safe_opts(options)
admin_cleanup_global_argv(parser, options, sys.argv)
if options.master and options.replica:
parser.error("on-master and on-replica options are mutually exclusive!")
+7 -3
View File
@@ -43,6 +43,7 @@ from ipalib.util import (
print_replication_status,
verify_host_resolvable,
)
from ipapython.admintool import admin_cleanup_global_argv
from ipapython.ipa_log_manager import standard_logging_setup
from ipapython.dn import DN
from ipapython.config import IPAOptionParser
@@ -84,7 +85,8 @@ class NoRUVsFound(Exception):
def parse_options():
parser = IPAOptionParser(version=version.VERSION)
parser.add_option("-H", "--host", dest="host", help="starting host")
parser.add_option("-p", "--password", dest="dirman_passwd", help="Directory Manager password")
parser.add_option("-p", "--password", dest="dirman_passwd", sensitive=True,
help="Directory Manager password")
parser.add_option("-v", "--verbose", dest="verbose", action="store_true", default=False,
help="provide additional information")
parser.add_option("-d", "--debug", dest="debug", action="store_true", default=False,
@@ -95,7 +97,7 @@ def parse_options():
help="DANGER: clean up references to a ghost master")
parser.add_option("--binddn", dest="binddn", default=None, type="dn",
help="Bind DN to use with remote server")
parser.add_option("--bindpw", dest="bindpw", default=None,
parser.add_option("--bindpw", dest="bindpw", default=None, sensitive=True,
help="Password for Bind DN to use with remote server")
parser.add_option("--winsync", dest="winsync", action="store_true", default=False,
help="This is a Windows Sync Agreement")
@@ -103,13 +105,15 @@ def parse_options():
help="Full path and filename of CA certificate to use with TLS/SSL to the remote server")
parser.add_option("--win-subtree", dest="win_subtree", default=None,
help="DN of Windows subtree containing the users you want to sync (default cn=Users,<domain suffix)")
parser.add_option("--passsync", dest="passsync", default=None,
parser.add_option("--passsync", dest="passsync",
default=None, sensitive=True,
help="Password for the IPA system user used by the Windows PassSync plugin to synchronize passwords")
parser.add_option("--from", dest="fromhost", help="Host to get data from")
parser.add_option("--no-lookup", dest="nolookup", action="store_true", default=False,
help="do not perform DNS lookup checks")
options, args = parser.parse_args()
admin_cleanup_global_argv(parser, options, sys.argv)
valid_syntax = False
@@ -27,6 +27,7 @@ plugin: update_mapping_Guests_to_nobody
plugin: fix_kra_people_entry
plugin: update_pwpolicy
plugin: update_pwpolicy_grace
plugin: add_admin_krbcanonicalname
# last
# DNS version 1
+2 -2
View File
@@ -34,7 +34,6 @@ import SSSDConfig
from six.moves.urllib.parse import urlsplit
from optparse import OptionParser # pylint: disable=deprecated-module
from ipapython import ipachangeconf
from ipaclient import discovery
from ipaclient.install.client import (
@@ -52,6 +51,7 @@ from ipaplatform.tasks import tasks
from ipaplatform import services
from ipaplatform.paths import paths
from ipapython.admintool import ScriptError
from ipapython.config import IPAOptionParser
logger = logging.getLogger(os.path.basename(__file__))
@@ -59,7 +59,7 @@ logger = logging.getLogger(os.path.basename(__file__))
def parse_options():
usage = "%prog [options]\n"
parser = OptionParser(usage=usage)
parser = IPAOptionParser(usage=usage)
parser.add_option("--server", dest="server", help="FQDN of IPA server")
parser.add_option(
"--location",
+2 -2
View File
@@ -9,7 +9,6 @@ import logging
import os
import gssapi
from urllib.parse import urlsplit
from optparse import OptionParser # pylint: disable=deprecated-module
from contextlib import contextmanager
from ipaclient import discovery
@@ -31,6 +30,7 @@ from ipaplatform.constants import constants
from ipaplatform import services
from ipapython.admintool import ScriptError
from samba import generate_random_password
from ipapython.config import IPAOptionParser
logger = logging.getLogger(os.path.basename(__file__))
logger.setLevel(logging.DEBUG)
@@ -68,7 +68,7 @@ def use_api_as_principal(principal, keytab):
def parse_options():
usage = "%prog [options]\n"
parser = OptionParser(usage=usage)
parser = IPAOptionParser(usage=usage)
parser.add_option(
"--server",
dest="server",
+12 -9
View File
@@ -30,7 +30,6 @@ import textwrap
import sys
import getpass
import code
import optparse # pylint: disable=deprecated-module
import os
import pprint
import fcntl
@@ -71,6 +70,8 @@ from ipalib.text import _
from ipalib import api
from ipapython.dnsutil import DNSName
from ipapython.admintool import ScriptError
from ipapython.config import (IPAOptionParser, IPAFormatter,
OptionGroup, make_option)
import datetime
@@ -1121,7 +1122,8 @@ class Collector:
def __todict__(self):
return dict(self.__options)
class CLIOptionParserFormatter(optparse.IndentedHelpFormatter):
class CLIOptionParserFormatter(IPAFormatter):
def format_argument(self, name, help_string):
result = []
opt_width = self.help_position - self.current_indent - 2
@@ -1141,7 +1143,8 @@ class CLIOptionParserFormatter(optparse.IndentedHelpFormatter):
result.append("\n")
return "".join(result)
class CLIOptionParser(optparse.OptionParser):
class CLIOptionParser(IPAOptionParser):
"""
This OptionParser subclass adds an ability to print positional
arguments in CLI help. Custom formatter is used to format the argument
@@ -1151,13 +1154,13 @@ class CLIOptionParser(optparse.OptionParser):
self._arguments = []
if 'formatter' not in kwargs:
kwargs['formatter'] = CLIOptionParserFormatter()
optparse.OptionParser.__init__(self, *args, **kwargs)
IPAOptionParser.__init__(self, *args, **kwargs)
def format_option_help(self, formatter=None):
"""
Prepend argument help to standard OptionParser's option help
"""
option_help = optparse.OptionParser.format_option_help(self, formatter)
option_help = IPAOptionParser.format_option_help(self, formatter)
if isinstance(formatter, CLIOptionParserFormatter):
heading = unicode(_("Positional arguments"))
@@ -1272,7 +1275,7 @@ class cli(backend.Executioner):
"""Get or create an option group for the given name"""
option_group = option_groups.get(group_name)
if option_group is None:
option_group = optparse.OptionGroup(parser, group_name)
option_group = OptionGroup(parser, group_name)
parser.add_option_group(option_group)
option_groups[group_name] = option_group
return option_group
@@ -1298,7 +1301,7 @@ class cli(backend.Executioner):
option_names = ['--%s' % cli_name]
if option.cli_short_name:
option_names.append('-%s' % option.cli_short_name)
opt = optparse.make_option(*option_names, **kw)
opt = make_option(*option_names, **kw)
if option.option_group is None:
parser.add_option(opt)
else:
@@ -1312,7 +1315,7 @@ class cli(backend.Executioner):
group = _get_option_group(unicode(_('Deprecated options')))
for alias in option.deprecated_cli_aliases:
name = '--%s' % alias
group.add_option(optparse.make_option(name, **new_kw))
group.add_option(make_option(name, **new_kw))
for arg in cmd.args():
name = self.__get_arg_name(arg, format_name=False)
@@ -1442,7 +1445,7 @@ class cli(backend.Executioner):
)
class IPAHelpFormatter(optparse.IndentedHelpFormatter):
class IPAHelpFormatter(IPAFormatter):
"""Formatter suitable for printing IPA command help
The default help formatter reflows text to fit the terminal, but it
+4 -4
View File
@@ -33,7 +33,6 @@ import sys
import threading
import os
from os import path
import optparse # pylint: disable=deprecated-module
import textwrap
import collections
import importlib
@@ -47,6 +46,7 @@ from ipalib.util import classproperty
from ipalib.base import ReadOnly, lock, islocked
from ipalib.constants import DEFAULT_CONFIG
from ipapython import ipa_log_manager, ipautil
from ipapython.config import IPAOptionParser, IPAFormatter
from ipapython.ipa_log_manager import (
LOGGING_FORMAT_FILE,
LOGGING_FORMAT_STDERR)
@@ -526,7 +526,7 @@ class API(ReadOnly):
def build_global_parser(self, parser=None, context=None):
"""
Add global options to an optparse.OptionParser instance.
Add global options to an IPAOptionParser instance.
"""
def config_file_callback(option, opt, value, parser):
if not os.path.isfile(value):
@@ -536,7 +536,7 @@ class API(ReadOnly):
parser.values.conf = value
if parser is None:
parser = optparse.OptionParser(
parser = IPAOptionParser(
add_help_option=False,
formatter=IPAHelpFormatter(),
usage='%prog [global-options] COMMAND [command-options]',
@@ -821,7 +821,7 @@ class API(ReadOnly):
return self.__next[plugin]
class IPAHelpFormatter(optparse.IndentedHelpFormatter):
class IPAHelpFormatter(IPAFormatter):
def format_epilog(self, epilog):
text_width = self.width - self.current_indent
indent = " " * self.current_indent
+41 -2
View File
@@ -26,7 +26,6 @@ import logging
import sys
import os
import traceback
from optparse import OptionGroup # pylint: disable=deprecated-module
from ipaplatform.osinfo import osinfo
from ipapython import version
@@ -40,6 +39,45 @@ SERVER_NOT_CONFIGURED = 2
logger = logging.getLogger(__name__)
def admin_cleanup_global_argv(option_parser, options, argv):
"""Takes option parser and generated options and scrubs sensitive arguments
from the global program arguments. Note that this only works for GNU GLIBC
as Python has no generic way to get access to the original argv values to
modify them in place.
The code assumes Python behavior, e.g. there are two additional args in the
list (/path/to/python -I ...) than what's passed as 'argv' here.
"""
import ctypes
import ctypes.util
try:
_c = ctypes.CDLL(ctypes.util.find_library("c"))
if _c._name is None:
return
_argv = ctypes.POINTER(ctypes.c_voidp).in_dll(_c, "_dl_argv")
# since we run as 'python -I <executable> ...', add two args
_argc = len(argv) + 2
all_options = []
if '_get_all_options' in dir(option_parser):
# OptParse parser
all_options = option_parser._get_all_options()
elif '_actions' in dir(option_parser):
# ArgParse parser
all_options = option_parser._actions
for opt in all_options:
if getattr(opt, 'sensitive', False):
v = getattr(options, opt.dest)
for i in range(0, _argc):
vi = ctypes.cast(_argv[i],
ctypes.c_char_p
).value.decode('utf-8')
if vi == v:
ctypes.memset(_argv[i], ord('X'), len(v))
except Exception:
pass
class ScriptError(Exception):
"""An exception that records an error message and a return value
"""
@@ -113,7 +151,7 @@ class AdminTool:
:param parser: The parser to add options to
:param debug_option: Add a --debug option as an alias to --verbose
"""
group = OptionGroup(parser, "Logging and output options")
group = config.OptionGroup(parser, "Logging and output options")
group.add_option("-v", "--verbose", dest="verbose", default=False,
action="store_true", help="print debugging information")
if debug_option:
@@ -149,6 +187,7 @@ class AdminTool:
cls._option_parsers[cls] = cls.option_parser
options, args = cls.option_parser.parse_args(argv[1:])
admin_cleanup_global_argv(cls.option_parser, options, argv)
command_class = cls.get_command_class(options, args)
command = command_class(options, args)
+11 -7
View File
@@ -18,9 +18,9 @@
#
from __future__ import absolute_import
# pylint: disable=deprecated-module
from optparse import (
Option, Values, OptionParser, IndentedHelpFormatter, OptionValueError)
# pylint: disable=deprecated-module, disable=unused-import
from optparse import (Option, Values, OptionGroup, OptionParser, SUPPRESS_HELP,
IndentedHelpFormatter, OptionValueError, make_option)
# pylint: enable=deprecated-module
from copy import copy
from configparser import ConfigParser as SafeConfigParser
@@ -113,10 +113,14 @@ class IPAOptionParser(OptionParser):
description=None,
formatter=None,
add_help_option=True,
prog=None):
OptionParser.__init__(self, usage, option_list, option_class,
version, conflict_handler, description,
formatter, add_help_option, prog)
prog=None,
epilog=None):
OptionParser.__init__(self, usage=usage, option_list=option_list,
option_class=option_class, version=version,
conflict_handler=conflict_handler,
description=description, formatter=formatter,
add_help_option=add_help_option, prog=prog,
epilog=epilog)
def get_safe_opts(self, opts):
"""
+4 -5
View File
@@ -9,12 +9,11 @@ Command line support.
import collections
import enum
import logging
import optparse # pylint: disable=deprecated-module
import signal
import six
from ipapython import admintool
from ipapython import admintool, config
from ipapython.ipa_log_manager import standard_logging_setup
from ipapython.ipautil import (CheckedIPAddress, CheckedIPAddressLoopback,
private_ccache)
@@ -158,7 +157,7 @@ class ConfigureTool(admintool.AdminTool):
try:
opt_group = groups[group_cls]
except KeyError:
opt_group = groups[group_cls] = optparse.OptionGroup(
opt_group = groups[group_cls] = config.OptionGroup(
parser, "{0} options".format(group_cls.description))
parser.add_option_group(opt_group)
@@ -232,7 +231,7 @@ class ConfigureTool(admintool.AdminTool):
if not hidden:
help = knob_cls.description
else:
help = optparse.SUPPRESS_HELP
help = config.SUPPRESS_HELP
opt_group.add_option(
*opt_strs,
@@ -256,7 +255,7 @@ class ConfigureTool(admintool.AdminTool):
# fake option parser to parse positional arguments
# (because optparse does not support positional argument parsing)
fake_option_parser = optparse.OptionParser()
fake_option_parser = config.IPAOptionParser()
self.add_options(fake_option_parser, True)
fake_option_map = {option.dest: option
+2 -4
View File
@@ -7,14 +7,12 @@ import enum
import pki.util
import logging
from optparse import OptionGroup # pylint: disable=deprecated-module
from ipalib import api, errors, x509
from ipalib import _
from ipalib.facts import is_ipa_configured
from ipaplatform.paths import paths
from ipapython.admintool import AdminTool
from ipapython import cookie, dogtag
from ipapython import cookie, dogtag, config
from ipapython.ipautil import run
from ipapython.certdb import NSSDatabase, EXTERNAL_CA_TRUST_FLAGS
from ipaserver.install import cainstance
@@ -143,7 +141,7 @@ class IPAACMEManage(AdminTool):
@classmethod
def add_options(cls, parser):
group = OptionGroup(parser, 'Pruning')
group = config.OptionGroup(parser, 'Pruning')
group.add_option(
"--enable", dest="enable", action="store_true",
default=False, help="Enable certificate pruning")
+2 -3
View File
@@ -20,7 +20,6 @@
from __future__ import absolute_import, print_function
import logging
import optparse # pylint: disable=deprecated-module
import os
import shutil
import sys
@@ -32,7 +31,7 @@ import six
from ipaplatform.paths import paths
from ipaplatform import services
from ipalib import api, errors
from ipapython import version
from ipapython import version, config
from ipapython.ipautil import run, write_tmp_file
from ipapython import admintool, certdb
from ipapython.dn import DN
@@ -245,7 +244,7 @@ class Backup(admintool.AdminTool):
parser.add_option(
"--gpg-keyring", dest="gpg_keyring",
help=optparse.SUPPRESS_HELP)
help=config.SUPPRESS_HELP)
parser.add_option(
"--gpg", dest="gpg", action="store_true",
default=False, help="Encrypt the backup")
+4 -5
View File
@@ -22,14 +22,13 @@ from __future__ import print_function, absolute_import
import datetime
import logging
import os
from optparse import OptionGroup # pylint: disable=deprecated-module
import gssapi
from ipalib.constants import (
RENEWAL_CA_NAME, RENEWAL_REUSE_CA_NAME, RENEWAL_SELFSIGNED_CA_NAME,
IPA_CA_CN)
from ipalib.install import certmonger, certstore
from ipapython import admintool, ipautil
from ipapython import admintool, ipautil, config
from ipapython.certdb import (EMPTY_TRUST_FLAGS,
EXTERNAL_CA_TRUST_FLAGS,
TrustFlags,
@@ -61,7 +60,7 @@ class CACertManage(admintool.AdminTool):
"-p", "--password", dest='password',
help="Directory Manager password")
renew_group = OptionGroup(parser, "Renew options")
renew_group = config.OptionGroup(parser, "Renew options")
renew_group.add_option(
"--self-signed", dest='self_signed',
action='store_true',
@@ -89,7 +88,7 @@ class CACertManage(admintool.AdminTool):
"certificate chain")
parser.add_option_group(renew_group)
install_group = OptionGroup(parser, "Install options")
install_group = config.OptionGroup(parser, "Install options")
install_group.add_option(
"-n", "--nickname", dest='nickname',
help="Nickname for the certificate")
@@ -98,7 +97,7 @@ class CACertManage(admintool.AdminTool):
help="Trust flags for the certificate in certutil format")
parser.add_option_group(install_group)
delete_group = OptionGroup(parser, "Delete options")
delete_group = config.OptionGroup(parser, "Delete options")
delete_group.add_option(
"-f", "--force", action='store_true',
help="Force removing the CA even if chain validation fails")
+2 -3
View File
@@ -22,13 +22,12 @@ from __future__ import print_function, absolute_import
import logging
import sys
import tempfile
from optparse import SUPPRESS_HELP # pylint: disable=deprecated-module
from textwrap import dedent
from ipalib import api
from ipalib.constants import DOMAIN_LEVEL_1
from ipaplatform.paths import paths
from ipapython import admintool
from ipapython import admintool, config
from ipaserver.install import service
from ipaserver.install import cainstance
from ipaserver.install import custodiainstance
@@ -73,7 +72,7 @@ class KRAInstall(admintool.AdminTool):
parser.add_option(
"--uninstall",
dest="uninstall", action="store_true", default=False,
help=SUPPRESS_HELP)
help=config.SUPPRESS_HELP)
parser.add_option(
"--pki-config-override", dest="pki_config_override",
+16 -1
View File
@@ -28,6 +28,7 @@ from ipaplatform.paths import paths
from ipapython.dn import DN
from ipapython.ipaldap import LDAPClient, LDAPEntry, realm_to_ldapi_uri
from ipapython.ipa_log_manager import standard_logging_setup
from ipapython.admintool import admin_cleanup_global_argv
from ipaserver.install.ipa_migrate_constants import (
DS_CONFIG, DB_OBJECTS, DS_INDEXES, BIND_DN, LOG_FILE_NAME,
STRIP_OP_ATTRS, STRIP_ATTRS, STRIP_OC, PROD_ATTRS,
@@ -284,6 +285,18 @@ class LDIFParser(ldif.LDIFParser):
self.mc.process_db_entry(entry_dn=dn, entry_attrs=entry_attrs)
class SensitiveStoreAction(argparse._StoreAction):
def __init__(self, *, sensitive, **options):
super(SensitiveStoreAction, self).__init__(**options)
self.sensitive = sensitive
def _get_kwargs(self):
names = super(SensitiveStoreAction, self)._get_kwargs()
sensitive_name = 'sensitive'
names.extend((sensitive_name, getattr(self, sensitive_name)))
return names
#
# Migrate IPA to IPA Class
#
@@ -344,7 +357,8 @@ class IPAMigrate():
help='Password for the Bind DN. If a password '
'is not provided then the user will be '
'prompted to enter it',
default=None)
default=None, sensitive=True,
action=SensitiveStoreAction)
parser.add_argument('-j', '--bind-pw-file',
help='A text file containing the clear text '
'password for the Bind DN', default=None)
@@ -2023,6 +2037,7 @@ class IPAMigrate():
parser = argparse.ArgumentParser(description=desc, allow_abbrev=True)
self.add_options(parser)
self.validate_options()
admin_cleanup_global_argv(parser, self.args, sys.argv)
# Check for dryrun mode
if self.args.dryrun or self.args.dryrun_record is not None:
+3 -4
View File
@@ -20,7 +20,6 @@
from __future__ import absolute_import, print_function
import logging
import optparse # pylint: disable=deprecated-module
import os
import shutil
import sys
@@ -34,7 +33,7 @@ import six
from ipaclient.install.client import update_ipa_nssdb
from ipalib import api, errors
from ipalib.constants import FQDN
from ipapython import version, ipautil
from ipapython import version, ipautil, config
from ipapython.ipautil import run, user_input
from ipapython import admintool, certdb
from ipapython.dn import DN
@@ -186,11 +185,11 @@ class Restore(admintool.AdminTool):
super(Restore, cls).add_options(parser, debug_option=True)
parser.add_option(
"-p", "--password", dest="password",
"-p", "--password", dest="password", sensitive=True,
help="Directory Manager password")
parser.add_option(
"--gpg-keyring", dest="gpg_keyring",
help=optparse.SUPPRESS_HELP)
help=config.SUPPRESS_HELP)
parser.add_option(
"--data", dest="data_only", action="store_true",
default=False, help="Restore only the data")
+4 -5
View File
@@ -22,12 +22,11 @@ from __future__ import print_function, absolute_import
import os
import os.path
import tempfile
import optparse # pylint: disable=deprecated-module
from ipalib import x509
from ipalib.install import certmonger
from ipaplatform.paths import paths
from ipapython import admintool, dogtag
from ipapython import admintool, dogtag, config
from ipapython.certdb import NSSDatabase, get_ca_nickname
from ipapython.dn import DN
from ipapython import ipaldap
@@ -65,15 +64,15 @@ class ServerCertInstall(admintool.AdminTool):
help="The password of the PKCS#12 file")
parser.add_option(
"--dirsrv_pin", "--http_pin",
dest="pin",
help=optparse.SUPPRESS_HELP)
dest="pin", sensitive=True,
help=config.SUPPRESS_HELP)
parser.add_option(
"--cert-name",
dest="cert_name", metavar="NAME",
help="Name of the certificate to install")
parser.add_option(
"-p", "--dirman-password",
dest="dirman_password",
dest="dirman_password", sensitive=True,
help="Directory Manager password")
def validate_options(self):
@@ -0,0 +1,79 @@
#
# Copyright (C) 2025 FreeIPA Contributors see COPYING for license
#
from __future__ import absolute_import
import logging
from ipalib import errors
from ipalib import Registry
from ipalib import Updater
from ipapython.dn import DN
logger = logging.getLogger(__name__)
register = Registry()
@register()
class add_admin_krbcanonicalname(Updater):
"""
Ensures that only the admin user has the krbCanonicalName of
admin@$REALM.
"""
def execute(self, **options):
ldap = self.api.Backend.ldap2
search_filter = (
"(krbcanonicalname=admin@{})".format(self.api.env.realm))
try:
(entries, _truncated) = ldap.find_entries(
filter=search_filter, base_dn=self.api.env.basedn,
time_limit=0, size_limit=0)
except errors.EmptyResult:
logger.debug("add_admin_krbcanonicalname: No user set with "
"admin krbcanonicalname")
entries = []
# fall through
except errors.ExecutionError as e:
logger.error("add_admin_krbcanonicalname: Can not get list "
"of krbcanonicalname: %s", e)
return False, []
admin_set = False
# admin should be only user with admin@ as krbcanonicalname
# It has a uniquness setting so there can be only one, we
# just didn't automatically set it for admin.
for entry in entries:
if entry.single_value.get('uid') != 'admin':
logger.critical(
"add_admin_krbcanonicalname: "
"entry %s has a krbcanonicalname of admin. Removing.",
entry.dn)
del entry['krbcanonicalname']
ldap.update_entry(entry)
else:
admin_set = True
if not admin_set:
dn = DN(
('uid', 'admin'),
self.api.env.container_user,
self.api.env.basedn)
entry = ldap.get_entry(dn)
entry['krbcanonicalname'] = 'admin@%s' % self.api.env.realm
try:
ldap.update_entry(entry)
except errors.DuplicateEntry:
logger.critical(
"add_admin_krbcanonicalname: "
"Failed to set krbcanonicalname on admin. It is set "
"on another entry.")
except errors.ExecutionError as e:
logger.critical(
"add_admin_krbcanonicalname: "
"Failed to set krbcanonicalname on admin: %s", e)
return False, []
+4 -4
View File
@@ -22,7 +22,6 @@ from __future__ import print_function
# WARNING: Do not import ipa modules, this is also used as a
# stand-alone script (invoked from po Makefile).
import optparse # pylint: disable=deprecated-module
import sys
import gettext
import re
@@ -30,6 +29,7 @@ import os
import traceback
import polib
from collections import namedtuple
from ipapython import config
import six
@@ -722,9 +722,9 @@ usage ='''
def main():
global verbose, print_traceback, pedantic, show_strings
parser = optparse.OptionParser(usage=usage)
parser = config.IPAOptionParser(usage=usage)
mode_group = optparse.OptionGroup(parser, 'Operational Mode',
mode_group = config.OptionGroup(parser, 'Operational Mode',
'You must select one these modes to run in')
mode_group.add_option('-g', '--test-gettext', action='store_const', const='test_gettext', dest='mode',
@@ -748,7 +748,7 @@ def main():
parser.add_option('--traceback', action='store_true', dest='print_traceback', default=False,
help='print the traceback when an exception occurs')
param_group = optparse.OptionGroup(parser, 'Run Time Parameters',
param_group = config.OptionGroup(parser, 'Run Time Parameters',
'These may be used to modify the run time defaults')
param_group.add_option('--test-lang', action='store', dest='test_lang', default='test',
@@ -1883,6 +1883,44 @@ class TestIPACommandWithoutReplica(IntegrationTest):
assert old_err_msg not in dirsrv_error_log
assert re.search(new_err_msg, dirsrv_error_log)
def test_unique_krbcanonicalname(self):
"""Verify that the uniqueness for krbcanonicalname is working"""
master = self.master
base_dn = str(master.domain.basedn)
hostname = master.hostname
realm = master.domain.realm
principal = f'test/{hostname}@{realm}'
entry_ldif = textwrap.dedent("""
dn: krbprincipalname={principal},cn=services,cn=accounts,{base_dn}
changetype: add
ipakrbprincipalalias: test/{hostname}@{realm}
krbprincipalname: {principal}
objectclass: ipakrbprincipal
objectclass: ipaobject
objectclass: ipaservice
objectclass: krbprincipal
objectclass: krbprincipalaux
objectclass: top
krbcanonicalname: admin@{realm}
managedby: fqdn={hostname},cn=computers,cn=accounts,{base_dn}
""").format(
base_dn=base_dn,
hostname=hostname,
principal=principal,
realm=realm)
tasks.kdestroy_all(master)
master.run_command(
['kinit', '-kt', '/etc/krb5.keytab', f'host/{hostname}@{realm}'])
args = [
'ldapmodify',
'-Y',
'GSSAPI'
]
result = master.run_command(args, stdin_text=entry_ldif,
raiseonerr=False)
assert "entry with the same attribute value" in result.stderr_text
class TestIPAautomount(IntegrationTest):
@classmethod
+2 -3
View File
@@ -38,6 +38,7 @@ from ipalib.parameters import Param
from ipalib.output import Output
from ipalib.text import Gettext, NGettext, ConcatenatedLazyText
from ipalib.capabilities import capabilities
from ipapython import config
API_FILE='API.txt'
@@ -84,9 +85,7 @@ OUTPUT_IGNORED_ATTRIBUTES = (
)
def parse_options():
from optparse import OptionParser # pylint: disable=deprecated-module
parser = OptionParser()
parser = config.IPAOptionParser()
parser.add_option("--validate", dest="validate", action="store_true",
default=False, help="Validate the API vs the stored API")