mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Add Domain Level feature
https://fedorahosted.org/freeipa/ticket/5018 Reviewed-By: Jan Cholasta <jcholast@redhat.com> Reviewed-By: Petr Vobornik <pvoborni@redhat.com>
This commit is contained in:
committed by
Jan Cholasta
parent
9eedffdfa6
commit
f3010498af
2
ACI.txt
2
ACI.txt
@@ -322,6 +322,8 @@ dn: cn=dna,cn=ipa,cn=etc,dc=ipa,dc=example
|
||||
aci: (targetattr = "cn || createtimestamp || dnahostname || dnaportnum || dnaremainingvalues || dnaremotebindmethod || dnaremoteconnprotocol || dnasecureportnum || entryusn || modifytimestamp || objectclass")(targetfilter = "(objectclass=dnasharedconfig)")(version 3.0;acl "permission:System: Read DNA Configuration";allow (compare,read,search) userdn = "ldap:///all";)
|
||||
dn: ou=profile,dc=ipa,dc=example
|
||||
aci: (targetattr = "attributemap || authenticationmethod || bindtimelimit || cn || createtimestamp || credentiallevel || defaultsearchbase || defaultsearchscope || defaultserverlist || dereferencealiases || entryusn || followreferrals || modifytimestamp || objectclass || objectclassmap || ou || preferredserverlist || profilettl || searchtimelimit || serviceauthenticationmethod || servicecredentiallevel || servicesearchdescriptor")(targetfilter = "(|(objectclass=organizationalUnit)(objectclass=DUAConfigProfile))")(version 3.0;acl "permission:System: Read DUA Profile";allow (compare,read,search) userdn = "ldap:///anyone";)
|
||||
dn: cn=Domain Level,cn=ipa,cn=etc,dc=ipa,dc=example
|
||||
aci: (targetattr = "createtimestamp || entryusn || ipadomainlevel || modifytimestamp || objectclass")(targetfilter = "(objectclass=ipadomainlevelconfig)")(version 3.0;acl "permission:System: Read Domain Level";allow (compare,read,search) userdn = "ldap:///all";)
|
||||
dn: cn=masters,cn=ipa,cn=etc,dc=ipa,dc=example
|
||||
aci: (targetattr = "cn || createtimestamp || entryusn || ipaconfigstring || modifytimestamp || objectclass")(targetfilter = "(objectclass=nscontainer)")(version 3.0;acl "permission:System: Read IPA Masters";allow (compare,read,search) groupdn = "ldap:///cn=System: Read IPA Masters,cn=permissions,cn=pbac,dc=ipa,dc=example";)
|
||||
dn: cn=config
|
||||
|
||||
9
API.txt
9
API.txt
@@ -1283,6 +1283,15 @@ option: Str('version?', exclude='webui')
|
||||
output: Entry('result', <type 'dict'>, Gettext('A dictionary representing an LDAP entry', domain='ipa', localedir=None))
|
||||
output: Output('summary', (<type 'unicode'>, <type 'NoneType'>), None)
|
||||
output: PrimaryKey('value', None, None)
|
||||
command: domainlevel_get
|
||||
args: 0,1,1
|
||||
option: Str('version?', exclude='webui')
|
||||
output: Output('result', <type 'int'>, None)
|
||||
command: domainlevel_set
|
||||
args: 1,1,1
|
||||
arg: Int('ipadomainlevel', cli_name='level', minvalue=0)
|
||||
option: Str('version?', exclude='webui')
|
||||
output: Output('result', <type 'int'>, None)
|
||||
command: env
|
||||
args: 1,3,4
|
||||
arg: Str('variables*')
|
||||
|
||||
4
VERSION
4
VERSION
@@ -90,5 +90,5 @@ IPA_DATA_VERSION=20100614120000
|
||||
# #
|
||||
########################################################
|
||||
IPA_API_VERSION_MAJOR=2
|
||||
IPA_API_VERSION_MINOR=119
|
||||
# Last change: edewata - Added vault plugin
|
||||
IPA_API_VERSION_MINOR=120
|
||||
# Last change: tbabej - Add Domain Level feature
|
||||
|
||||
6
install/share/72domainlevels.ldif
Normal file
6
install/share/72domainlevels.ldif
Normal file
@@ -0,0 +1,6 @@
|
||||
dn: cn=schema
|
||||
attributeTypes: (2.16.840.1.113730.3.8.19.2.1 NAME 'ipaDomainLevel' DESC 'Domain Level value' EQUALITY numericStringMatch ORDERING numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 SINGLE-VALUE X-ORIGIN 'IPA v4')
|
||||
attributeTypes: (2.16.840.1.113730.3.8.19.2.2 NAME 'ipaMinDomainLevel' DESC 'Minimal supported Domain Level value' EQUALITY numericStringMatch ORDERING numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 SINGLE-VALUE X-ORIGIN 'IPA v4')
|
||||
attributeTypes: (2.16.840.1.113730.3.8.19.2.3 NAME 'ipaMaxDomainLevel' DESC 'Maximal supported Domain Level value' EQUALITY numericStringMatch ORDERING numericStringMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.36 SINGLE-VALUE X-ORIGIN 'IPA v4')
|
||||
objectClasses: (2.16.840.1.113730.3.8.19.1.1 NAME 'ipaDomainLevelConfig' SUP ipaConfigObject AUXILIARY DESC 'Domain Level Configuration' MUST (ipaDomainLevel) X-ORIGIN 'IPA v4')
|
||||
objectClasses: (2.16.840.1.113730.3.8.19.1.2 NAME 'ipaSupportedDomainLevelConfig' SUP ipaConfigObject AUXILIARY DESC 'Supported Domain Level Configuration' MUST (ipaMinDomainLevel $ ipaMaxDomainLevel) X-ORIGIN 'IPA v4')
|
||||
@@ -22,6 +22,7 @@ app_DATA = \
|
||||
70ipaotp.ldif \
|
||||
70topology.ldif \
|
||||
71idviews.ldif \
|
||||
72domainlevels.ldif \
|
||||
anonymous-vlv.ldif \
|
||||
bootstrap-template.ldif \
|
||||
caJarSigningCert.cfg.template \
|
||||
@@ -34,6 +35,7 @@ app_DATA = \
|
||||
ds-nfiles.ldif \
|
||||
dns.ldif \
|
||||
dnssec.ldif \
|
||||
domainlevel.ldif \
|
||||
kerberos.ldif \
|
||||
indices.ldif \
|
||||
bind.named.conf.template \
|
||||
|
||||
7
install/share/domainlevel.ldif
Normal file
7
install/share/domainlevel.ldif
Normal file
@@ -0,0 +1,7 @@
|
||||
# Create default Domain Level for new masters
|
||||
dn: cn=Domain Level,cn=ipa,cn=etc,$SUFFIX
|
||||
changetype: add
|
||||
objectClass: top
|
||||
objectClass: nsContainer
|
||||
objectClass: ipaDomainLevelConfig
|
||||
ipaDomainLevel: $DOMAIN_LEVEL
|
||||
@@ -3,5 +3,9 @@ changetype: add
|
||||
objectclass: top
|
||||
objectclass: nsContainer
|
||||
objectclass: ipaReplTopoManagedServer
|
||||
ipaReplTopoManagedSuffix: $SUFFIX
|
||||
objectClass: ipaConfigObject
|
||||
objectClass: ipaSupportedDomainLevelConfig
|
||||
cn: $FQDN
|
||||
ipaReplTopoManagedSuffix: $SUFFIX
|
||||
ipaMinDomainLevel: $MIN_DOMAIN_LEVEL
|
||||
ipaMaxDomainLevel: $MAX_DOMAIN_LEVEL
|
||||
|
||||
@@ -43,7 +43,7 @@ from ipaserver.install import cainstance
|
||||
from ipaserver.install import kra
|
||||
from ipaserver.install import dns as dns_installer
|
||||
from ipalib import api, create_api, errors, util, certstore, x509
|
||||
from ipalib.constants import CACERT
|
||||
from ipalib import constants
|
||||
from ipapython import version
|
||||
from ipapython.config import IPAOptionParser
|
||||
from ipapython import sysrestore
|
||||
@@ -224,12 +224,12 @@ def install_ca_cert(ldap, base_dn, realm, cafile):
|
||||
try:
|
||||
certs = certstore.get_ca_certs(ldap, base_dn, realm, False)
|
||||
except errors.NotFound:
|
||||
shutil.copy(cafile, CACERT)
|
||||
shutil.copy(cafile, constants.CACERT)
|
||||
else:
|
||||
certs = [c[0] for c in certs if c[2] is not False]
|
||||
x509.write_certificate_list(certs, CACERT)
|
||||
x509.write_certificate_list(certs, constants.CACERT)
|
||||
|
||||
os.chmod(CACERT, 0444)
|
||||
os.chmod(constants.CACERT, 0444)
|
||||
except Exception, e:
|
||||
print "error copying files: " + str(e)
|
||||
sys.exit(1)
|
||||
@@ -569,6 +569,30 @@ def main():
|
||||
print " %% ipa-replica-manage del %s --force" % config.host_name
|
||||
exit(3)
|
||||
|
||||
# Detect the current domain level
|
||||
try:
|
||||
current = remote_api.Command['domainlevel_get']()['result']
|
||||
except errors.NotFound:
|
||||
# If we're joining an older master, domain entry is not
|
||||
# available
|
||||
current = 0
|
||||
|
||||
# Detect if current level is out of supported range
|
||||
# for this IPA version
|
||||
under_lower_bound = current < constants.MIN_DOMAIN_LEVEL
|
||||
above_upper_bound = current > constants.MAX_DOMAIN_LEVEL
|
||||
|
||||
if under_lower_bound or above_upper_bound:
|
||||
message = ("This version of FreeIPA does not support "
|
||||
"the Domain Level which is currently set for "
|
||||
"this domain. The Domain Level needs to be "
|
||||
"raised before installing a replica with "
|
||||
"this version is allowed to be installed "
|
||||
"within this domain.")
|
||||
root_logger.error(message)
|
||||
print(message)
|
||||
exit(3)
|
||||
|
||||
# Check pre-existing host entry
|
||||
try:
|
||||
entry = conn.find_entries(u'fqdn=%s' % config.host_name, ['fqdn'], DN(api.env.container_host, api.env.basedn))
|
||||
|
||||
@@ -70,7 +70,7 @@ from ipapython import sysrestore
|
||||
from ipapython.ipautil import *
|
||||
from ipapython import ipautil
|
||||
from ipapython import dogtag
|
||||
from ipalib import api, errors, util, x509
|
||||
from ipalib import api, errors, util, x509, constants
|
||||
from ipapython.config import IPAOptionParser
|
||||
from ipalib.util import validate_domain_name
|
||||
from ipalib.constants import CACERT
|
||||
@@ -176,6 +176,8 @@ def parse_options():
|
||||
help="create home directories for users "
|
||||
"on their first login")
|
||||
basic_group.add_option("--hostname", dest="host_name", help="fully qualified name of server")
|
||||
basic_group.add_option("--domain-level", dest="domainlevel", help="IPA domain level",
|
||||
default=constants.MAX_DOMAIN_LEVEL, type=int)
|
||||
basic_group.add_option("--ip-address", dest="ip_addresses",
|
||||
type="ip", ip_local=True, action="append", default=[],
|
||||
help="Master Server IP Address. This option can be used multiple times",
|
||||
@@ -327,6 +329,15 @@ def parse_options():
|
||||
except ValueError, e:
|
||||
parser.error("invalid domain: " + unicode(e))
|
||||
|
||||
# Check that Domain Level is within the allowed range
|
||||
if not options.uninstall:
|
||||
if options.domainlevel < constants.MIN_DOMAIN_LEVEL:
|
||||
parser.error("Domain Level cannot be lower than {0}"
|
||||
.format(constants.MIN_DOMAIN_LEVEL))
|
||||
elif options.domainlevel > constants.MAX_DOMAIN_LEVEL:
|
||||
parser.error("Domain Level cannot be higher than {0}"
|
||||
.format(constants.MAX_DOMAIN_LEVEL))
|
||||
|
||||
if not options.setup_dns:
|
||||
if options.forwarders:
|
||||
parser.error("You cannot specify a --forwarder option without the --setup-dns option")
|
||||
@@ -1143,21 +1154,24 @@ def main():
|
||||
ntp.create_instance()
|
||||
|
||||
if options.dirsrv_cert_files:
|
||||
ds = dsinstance.DsInstance(fstore=fstore)
|
||||
ds = dsinstance.DsInstance(fstore=fstore,
|
||||
domainlevel=options.domainlevel)
|
||||
ds.create_instance(realm_name, host_name, domain_name,
|
||||
dm_password, dirsrv_pkcs12_info,
|
||||
idstart=options.idstart, idmax=options.idmax,
|
||||
subject_base=options.subject,
|
||||
hbac_allow=not options.hbac_allow)
|
||||
else:
|
||||
ds = dsinstance.DsInstance(fstore=fstore)
|
||||
ds = dsinstance.DsInstance(fstore=fstore,
|
||||
domainlevel=options.domainlevel)
|
||||
ds.create_instance(realm_name, host_name, domain_name,
|
||||
dm_password,
|
||||
idstart=options.idstart, idmax=options.idmax,
|
||||
subject_base=options.subject,
|
||||
hbac_allow=not options.hbac_allow)
|
||||
else:
|
||||
ds = dsinstance.DsInstance(fstore=fstore)
|
||||
ds = dsinstance.DsInstance(fstore=fstore,
|
||||
domainlevel=options.domainlevel)
|
||||
ds.init_info(
|
||||
realm_name, host_name, domain_name, dm_password,
|
||||
options.subject, 1101, 1100, None)
|
||||
|
||||
14
install/updates/72-domainlevels.update
Normal file
14
install/updates/72-domainlevels.update
Normal file
@@ -0,0 +1,14 @@
|
||||
# Create default Domain Level entry if it does not exist
|
||||
dn: cn=Domain Level,cn=ipa,cn=etc,$SUFFIX
|
||||
default: objectClass: top
|
||||
default: objectClass: nsContainer
|
||||
default: objectClass: ipaDomainLevelConfig
|
||||
default: ipaDomainLevel: 0
|
||||
|
||||
# Create entry proclaiming Domain Level support of this master
|
||||
# This will update the supported Domain Levels during upgrade
|
||||
dn: cn=$FQDN,cn=masters,cn=ipa,cn=etc,$SUFFIX
|
||||
add: objectClass: ipaConfigObject
|
||||
add: objectClass: ipaSupportedDomainLevelConfig
|
||||
only: ipaMinDomainLevel: $MIN_DOMAIN_LEVEL
|
||||
only: ipaMaxDomainLevel: $MAX_DOMAIN_LEVEL
|
||||
@@ -49,6 +49,7 @@ app_DATA = \
|
||||
61-trusts-s4u2proxy.update \
|
||||
62-ranges.update \
|
||||
71-idviews.update \
|
||||
72-domainlevels.update \
|
||||
90-post_upgrade_plugins.update \
|
||||
$(NULL)
|
||||
|
||||
|
||||
@@ -224,3 +224,6 @@ LDAP_GENERALIZED_TIME_FORMAT = "%Y%m%d%H%M%SZ"
|
||||
|
||||
IPA_ANCHOR_PREFIX = ':IPA:'
|
||||
SID_ANCHOR_PREFIX = ':SID:'
|
||||
|
||||
MIN_DOMAIN_LEVEL = 0
|
||||
MAX_DOMAIN_LEVEL = 1
|
||||
|
||||
@@ -1344,6 +1344,22 @@ class EmptyResult(NotFound):
|
||||
|
||||
errno = 4031
|
||||
|
||||
class InvalidDomainLevelError(ExecutionError):
|
||||
"""
|
||||
**4032** Raised when a operation could not be completed due to a invalid
|
||||
domain level.
|
||||
|
||||
For example:
|
||||
|
||||
>>> raise InvalidDomainLevelError(reason='feature requires domain level 4')
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
InvalidDomainLevelError: feature requires domain level 4
|
||||
|
||||
"""
|
||||
|
||||
errno = 4032
|
||||
|
||||
class BuiltinError(ExecutionError):
|
||||
"""
|
||||
**4100** Base class for builtin execution errors (*4100 - 4199*).
|
||||
|
||||
138
ipalib/plugins/domainlevel.py
Normal file
138
ipalib/plugins/domainlevel.py
Normal file
@@ -0,0 +1,138 @@
|
||||
#
|
||||
# Copyright (C) 2015 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
|
||||
from collections import namedtuple
|
||||
|
||||
from ipalib import _
|
||||
from ipalib import Command
|
||||
from ipalib import errors
|
||||
from ipalib import output
|
||||
from ipalib.parameters import Int
|
||||
from ipalib.plugable import Registry
|
||||
from ipalib.plugins.baseldap import LDAPObject, LDAPUpdate, LDAPRetrieve
|
||||
|
||||
from ipapython.dn import DN
|
||||
|
||||
|
||||
__doc__ = _("""
|
||||
Raise the IPA Domain Level.
|
||||
""")
|
||||
|
||||
register = Registry()
|
||||
|
||||
DomainLevelRange = namedtuple('DomainLevelRange', ['min', 'max'])
|
||||
|
||||
domainlevel_output = (
|
||||
output.Output('result', int, _('Current domain level:')),
|
||||
)
|
||||
|
||||
|
||||
def get_domainlevel_dn(api):
|
||||
domainlevel_dn = DN(
|
||||
('cn', 'Domain Level'),
|
||||
('cn', 'ipa'),
|
||||
('cn', 'etc'),
|
||||
api.env.basedn
|
||||
)
|
||||
|
||||
return domainlevel_dn
|
||||
|
||||
|
||||
def get_domainlevel_range(master_entry):
|
||||
try:
|
||||
return DomainLevelRange(
|
||||
int(master_entry['ipaMinDomainLevel'][0]),
|
||||
int(master_entry['ipaMaxDomainLevel'][0])
|
||||
)
|
||||
except KeyError:
|
||||
return DomainLevelRange(0, 0)
|
||||
|
||||
|
||||
def get_master_entries(ldap, api):
|
||||
"""
|
||||
Returns list of LDAPEntries representing IPA masters.
|
||||
"""
|
||||
|
||||
container_masters = DN(
|
||||
('cn', 'masters'),
|
||||
('cn', 'ipa'),
|
||||
('cn', 'etc'),
|
||||
api.env.basedn
|
||||
)
|
||||
|
||||
masters, _ = ldap.find_entries(
|
||||
filter="(cn=*)",
|
||||
base_dn=container_masters,
|
||||
scope=ldap.SCOPE_ONELEVEL,
|
||||
paged_search=True, # we need to make sure to get all of them
|
||||
)
|
||||
|
||||
return masters
|
||||
|
||||
|
||||
@register()
|
||||
class domainlevel_get(Command):
|
||||
__doc__ = _('Query current Domain Level.')
|
||||
|
||||
has_output = domainlevel_output
|
||||
|
||||
def execute(self, *args, **options):
|
||||
ldap = self.api.Backend.ldap2
|
||||
entry = ldap.get_entry(
|
||||
get_domainlevel_dn(self.api),
|
||||
['ipaDomainLevel']
|
||||
)
|
||||
|
||||
return {'result': int(entry.single_value['ipaDomainLevel'])}
|
||||
|
||||
|
||||
@register()
|
||||
class domainlevel_set(Command):
|
||||
__doc__ = _('Change current Domain Level.')
|
||||
|
||||
has_output = domainlevel_output
|
||||
|
||||
takes_args = (
|
||||
Int('ipadomainlevel',
|
||||
cli_name='level',
|
||||
label=_('Domain Level'),
|
||||
minvalue=0,
|
||||
),
|
||||
)
|
||||
|
||||
def execute(self, *args, **options):
|
||||
"""
|
||||
Checks all the IPA masters for supported domain level ranges.
|
||||
|
||||
If the desired domain level is within the supported range of all
|
||||
masters, it will be raised.
|
||||
|
||||
Domain level cannot be lowered.
|
||||
"""
|
||||
|
||||
ldap = self.api.Backend.ldap2
|
||||
|
||||
current_entry = ldap.get_entry(get_domainlevel_dn(self.api))
|
||||
current_value = int(current_entry.single_value['ipadomainlevel'])
|
||||
desired_value = int(args[0])
|
||||
|
||||
# Domain level cannot be lowered
|
||||
if int(desired_value) < int(current_value):
|
||||
message = _("Domain Level cannot be lowered.")
|
||||
raise errors.InvalidDomainLevelError(message)
|
||||
|
||||
# Check if every master supports the desired level
|
||||
for master in get_master_entries(ldap, self.api):
|
||||
supported = get_domainlevel_range(master)
|
||||
|
||||
if supported.min > desired_value or supported.max < desired_value:
|
||||
message = _("Domain Level cannot be raised to {0}, server {1} "
|
||||
"does not support it."
|
||||
.format(desired_value, master['cn'][0]))
|
||||
raise errors.InvalidDomainLevelError(message)
|
||||
|
||||
current_entry.single_value['ipaDomainLevel'] = desired_value
|
||||
ldap.update_entry(current_entry)
|
||||
|
||||
return {'result': int(current_entry.single_value['ipaDomainLevel'])}
|
||||
@@ -40,6 +40,7 @@ from ipaserver.install import upgradeinstance
|
||||
from ipalib import api
|
||||
from ipalib import certstore
|
||||
from ipalib import errors
|
||||
from ipalib import constants
|
||||
from ipaplatform.tasks import tasks
|
||||
from ipalib.constants import CACERT
|
||||
from ipapython.dn import DN
|
||||
@@ -62,6 +63,7 @@ IPA_SCHEMA_FILES = ("60kerberos.ldif",
|
||||
"70ipaotp.ldif",
|
||||
"70topology.ldif",
|
||||
"71idviews.ldif",
|
||||
"72domainlevels.ldif",
|
||||
"15rfc2307bis.ldif",
|
||||
"15rfc4876.ldif")
|
||||
|
||||
@@ -186,7 +188,7 @@ info: IPA V2.0
|
||||
|
||||
class DsInstance(service.Service):
|
||||
def __init__(self, realm_name=None, domain_name=None, dm_password=None,
|
||||
fstore=None):
|
||||
fstore=None, domainlevel=None):
|
||||
service.Service.__init__(self, "dirsrv",
|
||||
service_desc="directory server",
|
||||
dm_password=dm_password,
|
||||
@@ -209,6 +211,7 @@ class DsInstance(service.Service):
|
||||
self.subject_base = None
|
||||
self.open_ports = []
|
||||
self.run_init_memberof = True
|
||||
self.domainlevel = domainlevel
|
||||
if realm_name:
|
||||
self.suffix = ipautil.realm_to_suffix(self.realm)
|
||||
self.__setup_sub_dict()
|
||||
@@ -254,6 +257,7 @@ class DsInstance(service.Service):
|
||||
def __common_post_setup(self):
|
||||
self.step("initializing group membership", self.init_memberof)
|
||||
self.step("adding master entry", self.__add_master_entry)
|
||||
self.step("initializing domain level", self.__set_domain_level)
|
||||
self.step("configuring Posix uid/gid generation",
|
||||
self.__config_uidgid_gen)
|
||||
self.step("adding replication acis", self.__add_replication_acis)
|
||||
@@ -395,7 +399,10 @@ class DsInstance(service.Service):
|
||||
IDMAX=self.idmax, HOST=self.fqdn,
|
||||
ESCAPED_SUFFIX=str(self.suffix),
|
||||
GROUP=DS_GROUP,
|
||||
IDRANGE_SIZE=idrange_size
|
||||
IDRANGE_SIZE=idrange_size,
|
||||
DOMAIN_LEVEL=self.domainlevel,
|
||||
MAX_DOMAIN_LEVEL=constants.MAX_DOMAIN_LEVEL,
|
||||
MIN_DOMAIN_LEVEL=constants.MIN_DOMAIN_LEVEL,
|
||||
)
|
||||
|
||||
def __create_instance(self):
|
||||
@@ -1011,3 +1018,8 @@ class DsInstance(service.Service):
|
||||
root_logger.debug('Unable to find certificate subject base in '
|
||||
'certmap.conf')
|
||||
return None
|
||||
|
||||
def __set_domain_level(self):
|
||||
# Create global domain level entry and set the domain level
|
||||
if self.domainlevel is not None:
|
||||
self._ldap_mod("domainlevel.ldif", self.sub_dict)
|
||||
|
||||
@@ -39,6 +39,7 @@ from ipaserver.install import installutils
|
||||
from ipapython import ipautil, ipaldap
|
||||
from ipalib import errors
|
||||
from ipalib import api, create_api
|
||||
from ipalib import constants
|
||||
from ipaplatform.paths import paths
|
||||
from ipaplatform import services
|
||||
from ipapython.dn import DN
|
||||
@@ -305,6 +306,10 @@ class LDAPUpdate:
|
||||
self.sub_dict["TIME"] = int(time.time())
|
||||
if not self.sub_dict.get("DOMAIN") and domain is not None:
|
||||
self.sub_dict["DOMAIN"] = domain
|
||||
if not self.sub_dict.get("MIN_DOMAIN_LEVEL"):
|
||||
self.sub_dict["MIN_DOMAIN_LEVEL"] = str(constants.MIN_DOMAIN_LEVEL)
|
||||
if not self.sub_dict.get("MAX_DOMAIN_LEVEL"):
|
||||
self.sub_dict["MAX_DOMAIN_LEVEL"] = str(constants.MAX_DOMAIN_LEVEL)
|
||||
self.api = create_api(mode=None)
|
||||
self.api.bootstrap(in_server=True, context='updates')
|
||||
self.api.finalize()
|
||||
|
||||
@@ -338,7 +338,16 @@ NONOBJECT_PERMISSIONS = {
|
||||
'serviceAuthenticationMethod', 'objectclassMap', 'attributeMap',
|
||||
'profileTTL'
|
||||
},
|
||||
}
|
||||
},
|
||||
'System: Read Domain Level': {
|
||||
'ipapermlocation': DN('cn=Domain Level,cn=ipa,cn=etc', api.env.basedn),
|
||||
'ipapermtargetfilter': {'(objectclass=ipadomainlevelconfig)'},
|
||||
'ipapermbindruletype': 'all',
|
||||
'ipapermright': {'read', 'search', 'compare'},
|
||||
'ipapermdefaultattr': {
|
||||
'ipadomainlevel', 'objectclass',
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user