Add option to the installer for uid/gid starting numbers.

This also adds a new option to the template system. If you include
eval(string) in a file that goes through the templater then the
string in the eval will be evaluated by the Python interpreter. This is
used so one can do $UIDSTART+1. If any errors occur during the evaluation
the original string is is returned, eval() and all so it is up to the
developer to make sure the evaluation passes.

The default value for uid and gid is now a random value between
1,000,000 and (2^31 - 1,000,000)
This commit is contained in:
Rob Crittenden 2009-08-27 14:12:55 -04:00
parent cab5525076
commit 559c76f761
6 changed files with 37 additions and 11 deletions

View File

@ -69,8 +69,8 @@ uid: admin
krbPrincipalName: admin@$REALM krbPrincipalName: admin@$REALM
cn: Administrator cn: Administrator
sn: Administrator sn: Administrator
uidNumber: 999 uidNumber: $UIDSTART
gidNumber: 1001 gidNumber: $GIDSTART
homeDirectory: /home/admin homeDirectory: /home/admin
loginShell: /bin/bash loginShell: /bin/bash
gecos: Administrator gecos: Administrator
@ -107,7 +107,7 @@ objectClass: groupofnames
objectClass: posixgroup objectClass: posixgroup
cn: admins cn: admins
description: Account administrators group description: Account administrators group
gidNumber: 1001 gidNumber: $GIDSTART
member: uid=admin,cn=users,cn=accounts,$SUFFIX member: uid=admin,cn=users,cn=accounts,$SUFFIX
nsAccountLock: False nsAccountLock: False
@ -118,7 +118,7 @@ objectClass: groupofnames
objectClass: nestedgroup objectClass: nestedgroup
objectClass: ipausergroup objectClass: ipausergroup
objectClass: posixgroup objectClass: posixgroup
gidNumber: 1002 gidNumber: eval($GIDSTART+1)
description: Default group for all users description: Default group for all users
cn: ipausers cn: ipausers
@ -127,7 +127,7 @@ changetype: add
objectClass: top objectClass: top
objectClass: groupofnames objectClass: groupofnames
objectClass: posixgroup objectClass: posixgroup
gidNumber: 1003 gidNumber: eval($GIDSTART+2)
description: Limited admins who can edit other users description: Limited admins who can edit other users
cn: editors cn: editors

View File

@ -6,7 +6,7 @@ objectclass: top
objectclass: extensibleObject objectclass: extensibleObject
cn: Posix Accounts cn: Posix Accounts
dnaType: uidNumber dnaType: uidNumber
dnaNextValue: 1100 dnaNextValue: eval($UIDSTART+1)
dnaInterval: 1 dnaInterval: 1
dnaMaxValue: 1000000000 dnaMaxValue: 1000000000
dnaMagicRegen: 999 dnaMagicRegen: 999
@ -21,7 +21,7 @@ objectclass: top
objectclass: extensibleObject objectclass: extensibleObject
cn: Posix Groups cn: Posix Groups
dnaType: gidNumber dnaType: gidNumber
dnaNextValue: 1100 dnaNextValue: eval($GIDSTART+3)
dnaInterval: 1 dnaInterval: 1
dnaMaxValue: 1000000000 dnaMaxValue: 1000000000
dnaMagicRegen: 999 dnaMagicRegen: 999

View File

@ -36,6 +36,7 @@ import shutil
import glob import glob
import traceback import traceback
from optparse import OptionParser from optparse import OptionParser
import random
from ipaserver.install import dsinstance from ipaserver.install import dsinstance
from ipaserver.install import krbinstance from ipaserver.install import krbinstance
@ -54,7 +55,11 @@ from ipalib import util
pw_name = None pw_name = None
# Used to determine the the highest possible uid/gid
MAXINT_32BIT = 2147483648
def parse_options(): def parse_options():
namespace = random.randint(1000000, (MAXINT_32BIT - 1000000))
parser = OptionParser(version=version.VERSION) parser = OptionParser(version=version.VERSION)
parser.add_option("-u", "--user", dest="ds_user", parser.add_option("-u", "--user", dest="ds_user",
help="ds user") help="ds user")
@ -97,6 +102,10 @@ def parse_options():
default=False, default=False,
help="Do not use DNS for hostname lookup during installation") 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)")
options, args = parser.parse_args() options, args = parser.parse_args()
if options.uninstall: if options.uninstall:
@ -537,7 +546,7 @@ def main():
finally: finally:
os.remove(pw_name) os.remove(pw_name)
else: else:
ds.create_instance(ds_user, realm_name, host_name, domain_name, dm_password, self_signed_ca=not options.ca) ds.create_instance(ds_user, realm_name, host_name, domain_name, dm_password, self_signed_ca=not options.ca, uidstart=options.uidstart, gidstart=options.gidstart)
# Create a kerberos instance # Create a kerberos instance
krb = krbinstance.KrbInstance(fstore) krb = krbinstance.KrbInstance(fstore)

View File

@ -75,6 +75,12 @@ The password of the Directory Server PKCS#12 file
\fB\-\-http_pin\fR=\fIHTTP_PIN\fR \fB\-\-http_pin\fR=\fIHTTP_PIN\fR
The password of the Apache Server PKCS#12 file The password of the Apache Server PKCS#12 file
.PP .PP
\fB\-\-uidstart\fR=\fIUIDSTART\fR
The starting user id number (default random)
.PP
\fB\-\-gidstart\fR=\fIGIDSTART\fR
The starting group id number (default random)
.PP
.SH "EXIT STATUS" .SH "EXIT STATUS"
0 if the installation was successful 0 if the installation was successful

View File

@ -68,7 +68,15 @@ def realm_to_suffix(realm_name):
return ",".join(terms) return ",".join(terms)
def template_str(txt, vars): def template_str(txt, vars):
return string.Template(txt).substitute(vars) val = string.Template(txt).substitute(vars)
# eval() is a special string one can insert into a template to have the
# Python interpreter evaluate the string. This is intended to allow
# math to be performed in templates.
pattern = re.compile('(eval\s*\(([^()]*)\))')
val = pattern.sub(lambda x: str(eval(x.group(2))), val)
return val
def template_file(infilename, vars): def template_file(infilename, vars):
txt = open(infilename).read() txt = open(infilename).read()

View File

@ -151,7 +151,7 @@ class DsInstance(service.Service):
else: else:
self.suffix = None self.suffix = None
def create_instance(self, ds_user, realm_name, host_name, domain_name, dm_password, pkcs12_info=None, self_signed_ca=False): def create_instance(self, ds_user, realm_name, host_name, domain_name, dm_password, pkcs12_info=None, self_signed_ca=False, uidstart=1100, gidstart=1100):
self.ds_user = ds_user self.ds_user = ds_user
self.realm_name = realm_name.upper() self.realm_name = realm_name.upper()
self.serverid = realm_to_serverid(self.realm_name) self.serverid = realm_to_serverid(self.realm_name)
@ -161,6 +161,8 @@ class DsInstance(service.Service):
self.domain = domain_name self.domain = domain_name
self.pkcs12_info = pkcs12_info self.pkcs12_info = pkcs12_info
self.self_signed_ca = self_signed_ca self.self_signed_ca = self_signed_ca
self.uidstart = uidstart
self.gidstart = gidstart
self.__setup_sub_dict() self.__setup_sub_dict()
self.step("creating directory server user", self.__create_ds_user) self.step("creating directory server user", self.__create_ds_user)
@ -198,7 +200,8 @@ class DsInstance(service.Service):
PASSWORD=self.dm_password, SUFFIX=self.suffix.lower(), PASSWORD=self.dm_password, SUFFIX=self.suffix.lower(),
REALM=self.realm_name, USER=self.ds_user, REALM=self.realm_name, USER=self.ds_user,
SERVER_ROOT=server_root, DOMAIN=self.domain, SERVER_ROOT=server_root, DOMAIN=self.domain,
TIME=int(time.time())) TIME=int(time.time()), UIDSTART=self.uidstart,
GIDSTART=self.gidstart)
def __create_ds_user(self): def __create_ds_user(self):
user_exists = True user_exists = True