id ranges: change DNA configuration

Change the way we specify the id ranges to force uid and gid ranges to always
be the same. Add option to specify a maximum id.

Change DNA configuration to use shared ranges so that masters and replicas can
actually share the same overall range in a safe way.

Configure replicas so that their default range is depleted. This will force
them to fetch a range portion from the master on the first install.

fixes: https://fedorahosted.org/freeipa/ticket/198
This commit is contained in:
Simo Sorce 2010-11-11 18:15:28 -05:00 committed by Adam Young
parent 61e2016ee3
commit 6a5c4763af
9 changed files with 68 additions and 72 deletions

View File

@ -32,8 +32,7 @@ app_DATA = \
krbrealm.con.template \
preferences.html.template \
referint-conf.ldif \
dna-posix.ldif \
dna-upg.ldif \
dna.ldif \
master-entry.ldif \
memberof-task.ldif \
memberof-conf.ldif \

View File

@ -100,6 +100,18 @@ objectClass: nsContainer
objectClass: top
cn: masters
dn: cn=dna,cn=ipa,cn=etc,$SUFFIX
changetype: add
objectClass: nsContainer
objectClass: top
cn: dna
dn: cn=posix-ids,cn=dna,cn=ipa,cn=etc,$SUFFIX
changetype: add
objectClass: nsContainer
objectClass: top
cn: posix-ids
dn: uid=admin,cn=users,cn=accounts,$SUFFIX
changetype: add
objectClass: top
@ -113,8 +125,8 @@ uid: admin
krbPrincipalName: admin@$REALM
cn: Administrator
sn: Administrator
uidNumber: $UIDSTART
gidNumber: $GIDSTART
uidNumber: $IDSTART
gidNumber: $IDSTART
homeDirectory: /home/admin
loginShell: /bin/bash
gecos: Administrator
@ -153,7 +165,7 @@ objectClass: posixgroup
objectClass: ipausergroup
cn: admins
description: Account administrators group
gidNumber: $GIDSTART
gidNumber: $IDSTART
member: uid=admin,cn=users,cn=accounts,$SUFFIX
nsAccountLock: False
@ -164,7 +176,7 @@ objectClass: groupofnames
objectClass: nestedgroup
objectClass: ipausergroup
objectClass: posixgroup
gidNumber: eval($GIDSTART+1)
gidNumber: eval($IDSTART+1)
description: Default group for all users
cn: ipausers
@ -174,7 +186,7 @@ objectClass: top
objectClass: groupofnames
objectClass: posixgroup
objectClass: ipausergroup
gidNumber: eval($GIDSTART+2)
gidNumber: eval($IDSTART+2)
description: Limited admins who can edit other users
cn: editors

View File

@ -1,30 +0,0 @@
# add plugin configuration for posix users
dn: cn=Posix Accounts,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config
changetype: add
objectclass: top
objectclass: extensibleObject
cn: Posix Accounts
dnaType: uidNumber
dnaNextValue: eval($UIDSTART+1)
dnaInterval: 1
dnaMaxValue: eval($UIDSTART+100000)
dnaMagicRegen: 999
dnaFilter: (objectclass=posixAccount)
dnaScope: $SUFFIX
# add plugin configuration for posix groups
dn: cn=Posix Groups,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config
changetype: add
objectclass: top
objectclass: extensibleObject
cn: Posix Groups
dnaType: gidNumber
dnaNextValue: eval($GIDSTART+3)
dnaInterval: 1
dnaMaxValue: eval($GIDSTART+100000)
dnaMagicRegen: 999
dnaFilter: (objectclass=posixGroup)
dnaScope: $SUFFIX

View File

@ -1,16 +1,17 @@
# add plugin configuration for user private groups
dn: cn=User Private Groups,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config
dn: cn=Posix IDs,cn=Distributed Numeric Assignment Plugin,cn=plugins,cn=config
changetype: add
objectclass: top
objectclass: extensibleObject
cn: Posix Accounts
cn: Posix IDs
dnaType: uidNumber
dnaType: gidNumber
dnaNextValue: eval($UIDSTART+1)
dnaInterval: 1
dnaMaxValue: eval($UIDSTART+100000)
dnaNextValue: eval($IDSTART)
dnaMaxValue: eval($IDMAX)
dnaMagicRegen: 999
dnaFilter: (|(objectclass=posixAccount)(objectClass=posixGroup))
dnaScope: $SUFFIX
dnaThreshold: 500
dnaSharedCfgDN: cn=posix-ids,cn=dna,cn=ipa,cn=etc,$SUFFIX

View File

@ -3,5 +3,3 @@ changetype: add
objectclass: top
objectclass: extensibleObject
cn: $FQHN
dnabase: 1100
dnainterval: 4

View File

@ -176,7 +176,13 @@ def install_ds(config):
config.dir + "/dirsrv_pin.txt")
ds = dsinstance.DsInstance()
ds.create_instance(config.ds_user, config.realm_name, config.host_name, config.domain_name, config.dirman_password, pkcs12_info)
# idstart and idmax are configured so that the range is seen as depleted
# by the DNA plugin and the replica will go and get a new range from the
# master.
# This way all servers use the initially defined range by default.
ds.create_instance(config.ds_user, config.realm_name, config.host_name,
config.domain_name, config.dirman_password,
pkcs12_info, idstart=1101, idmax=1100)
return ds

View File

@ -124,10 +124,10 @@ def parse_options():
default=False,
help="Do not use DNS for hostname lookup during installation")
parser.add_option("--uidstart", dest="uidstart", default=namespace, type=int,
help="The starting uid value (default random)")
parser.add_option("--gidstart", dest="gidstart", default=namespace, type=int,
help="The starting gid value (default random)")
parser.add_option("--idstart", dest="idstart", default=namespace, type=int,
help="The starting value for the IDs range (default random)")
parser.add_option("--idmax", dest="idmax", default=0, type=int,
help="The max value value for the IDs range (default random)")
parser.add_option("--subject", dest="subject",
help="The certificate subject base (default O=<realm-name>)")
parser.add_option("--no_hbac_allow", dest="hbac_allow", default=False,
@ -176,6 +176,13 @@ def parse_options():
if (options.external_cert_file and not os.path.isabs(options.external_cert_file)):
parser.error("--external-cert-file must use an absolute path")
if options.idmax == 0:
options.idmax = int(options.idstart) + 1000000 - 1
if options.idmax < options.idstart:
parse.error("idmax (%u) cannot be smaller than idstart (%u)" %
(options.idmax, options.idstart))
#Automatically disable pkinit w/ dogtag until that is supported
if not options.pkinit_pkcs12 and not options.selfsign:
options.setup_pkinit = False
@ -739,7 +746,11 @@ def main():
finally:
os.remove(pw_name)
else:
ds.create_instance(ds_user, realm_name, host_name, domain_name, dm_password, self_signed_ca=options.selfsign, uidstart=options.uidstart, gidstart=options.gidstart, subject_base=options.subject, hbac_allow=not options.hbac_allow)
ds.create_instance(ds_user, realm_name, host_name, domain_name,
dm_password, self_signed_ca=options.selfsign,
idstart=options.idstart, idmax=options.idmax,
subject_base=options.subject,
hbac_allow=not options.hbac_allow)
if options.pkinit_pin:
[pw_fd, pw_name] = tempfile.mkstemp()

View File

@ -95,11 +95,8 @@ The password of the Directory Server PKCS#12 file
\fB\-\-http_pin\fR=\fIHTTP_PIN\fR
The password of the Apache Server PKCS#12 file
.TP
\fB\-\-uidstart\fR=\fIUIDSTART\fR
The starting user id number (default random)
.TP
\fB\-\-gidstart\fR=\fIGIDSTART\fR
The starting group id number (default random)
\fB\-\-idstart\fR=\fIIDSTART\fR
The starting user and group id number (default random)
.TP
\fB\-\-subject\fR=\fISUBJECT\fR
The certificate subject base (default O=REALM.NAME)

View File

@ -176,15 +176,18 @@ class DsInstance(service.Service):
self.pkcs12_info = None
self.ds_user = None
self.dercert = None
self.uidstart = 1100
self.gidstart = 1100
self.idstart = None
self.idmax = None
if realm_name:
self.suffix = util.realm_to_suffix(self.realm_name)
self.__setup_sub_dict()
else:
self.suffix = None
def create_instance(self, ds_user, realm_name, fqdn, domain_name, dm_password, pkcs12_info=None, self_signed_ca=False, uidstart=1100, gidstart=1100, subject_base=None, hbac_allow=True):
def create_instance(self, ds_user, realm_name, fqdn, domain_name,
dm_password, pkcs12_info=None, self_signed_ca=False,
idstart=1100, idmax=999999, subject_base=None,
hbac_allow=True):
self.ds_user = ds_user
self.realm_name = realm_name.upper()
self.serverid = realm_to_serverid(self.realm_name)
@ -194,8 +197,8 @@ class DsInstance(service.Service):
self.domain = domain_name
self.pkcs12_info = pkcs12_info
self.self_signed_ca = self_signed_ca
self.uidstart = uidstart
self.gidstart = gidstart
self.idstart = idstart
self.idmax = idmax
self.principal = "ldap/%s@%s" % (self.fqdn, self.realm_name)
self.subject_base = subject_base
self.__setup_sub_dict()
@ -206,8 +209,7 @@ class DsInstance(service.Service):
self.step("enabling memberof plugin", self.__add_memberof_module)
self.step("enabling referential integrity plugin", self.__add_referint_module)
self.step("enabling winsync plugin", self.__add_winsync_module)
if self.uidstart == self.gidstart:
self.step("configuring user private groups", self.__user_private_groups)
self.step("configuring user private groups", self.__user_private_groups)
self.step("configuring replication version plugin", self.__config_version_module)
self.step("enabling IPA enrollment plugin", self.__add_enrollment_module)
self.step("enabling ldapi", self.__enable_ldapi)
@ -242,11 +244,12 @@ class DsInstance(service.Service):
def __setup_sub_dict(self):
server_root = find_server_root()
self.sub_dict = dict(FQHN=self.fqdn, SERVERID=self.serverid,
PASSWORD=self.dm_password, SUFFIX=self.suffix.lower(),
PASSWORD=self.dm_password,
SUFFIX=self.suffix.lower(),
REALM=self.realm_name, USER=self.ds_user,
SERVER_ROOT=server_root, DOMAIN=self.domain,
TIME=int(time.time()), UIDSTART=self.uidstart,
GIDSTART=self.gidstart, HOST=self.fqdn,
TIME=int(time.time()), IDSTART=self.idstart,
IDMAX=self.idmax, HOST=self.fqdn,
ESCAPED_SUFFIX= escape_dn_chars(self.suffix.lower()),
)
@ -366,11 +369,9 @@ class DsInstance(service.Service):
self._ldap_mod("unique-attributes.ldif", self.sub_dict)
def __config_uidgid_gen_first_master(self):
if (self.uidstart == self.gidstart and
has_managed_entries(self.fqdn, self.dm_password)):
self._ldap_mod("dna-upg.ldif", self.sub_dict)
else:
self._ldap_mod("dna-posix.ldif", self.sub_dict)
if not has_managed_entries(self.fqdn, self.dm_password):
raise errors.NotFound(reason='Missing Managed Entries Plugin')
self._ldap_mod("dna.ldif", self.sub_dict)
def __add_master_entry_first_master(self):
self._ldap_mod("master-entry.ldif", self.sub_dict)
@ -396,8 +397,9 @@ class DsInstance(service.Service):
self._ldap_mod("modrdn-krbprinc.ldif", self.sub_dict)
def __user_private_groups(self):
if has_managed_entries(self.fqdn, self.dm_password):
self._ldap_mod("user_private_groups.ldif", self.sub_dict)
if not has_managed_entries(self.fqdn, self.dm_password):
raise errors.NotFound(reason='Missing Managed Entries Plugin')
self._ldap_mod("user_private_groups.ldif", self.sub_dict)
def __add_enrollment_module(self):
self._ldap_mod("enrollment-conf.ldif", self.sub_dict)