[Freeipa-devel] [PATCH] 1 Add ipa-adtrust-install utility
Simo Sorce
simo at redhat.com
Fri Aug 26 13:14:27 UTC 2011
More comments.
On Fri, 2011-08-26 at 11:39 +0200, Sumit Bose wrote:
[..]
> + if not options.unattended:
> + print ""
> + print "The following operations may take some minutes to
> complete."
> + print "Please wait until the prompt is returned."
> + print ""
> +
> + # Create a BIND instance
comment seem to be wrong here :)
> + if options.unattended and not options.dm_password:
> + sys.exit("\nIn unattended mode you need to provide at least
> the -p option")
> +
> + dm_password = options.dm_password or read_password("Directory
> Manager",
> + confirm=False,
> validate=False)
> + smb = smbinstance.SMBInstance(fstore, dm_password)
[..]
> diff --git a/ipaserver/install/service.py
> b/ipaserver/install/service.py
> index
> a7f6ff4eea1b67f714e18f882a082d4ad7d83026..7e0d2bd314f00ccf0b0ee37a9d572bdd5ee89414 100644
> --- a/ipaserver/install/service.py
> +++ b/ipaserver/install/service.py
> @@ -37,7 +37,8 @@ SERVICE_LIST = {
> 'KPASSWD':('kadmin', 20),
> 'DNS':('named', 30),
> 'HTTP':('httpd', 40),
> - 'CA':('pki-cad', 50)
> + 'CA':('pki-cad', 50),
> + 'SMB':('smb', 60)
Please do not use SMB (in general I do not think SMB is the right
prefix). Use something like ADTRUST or MSRPC or WINCOMPAT.
> }
>
> def stop(service_name, instance_name="", capture_output=True):
> diff --git a/ipaserver/install/smbinstance.py
> b/ipaserver/install/smbinstance.py
> new file mode 100644
> index
> 0000000000000000000000000000000000000000..5988f1e056d29af6686d53237b82d460cdc719da
> --- /dev/null
> +++ b/ipaserver/install/smbinstance.py
> @@ -0,0 +1,261 @@
> +# Authors: Sumit Bose <sbose at redhat.com>
> +#
> +# Copyright (C) 2011 Red Hat
> +# see file 'COPYING' for use and warranty information
> +#
> +# This program is free software; you can redistribute it and/or
> modify
> +# it under the terms of the GNU General Public License as published
> by
> +# the Free Software Foundation, either version 3 of the License, or
> +# (at your option) any later version.
> +#
> +# This program is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with this program. If not, see
> <http://www.gnu.org/licenses/>.
> +#
> +
> +import logging
> +
> +import os
> +import ldap
> +import service
> +import tempfile
> +from ipaserver import ipaldap
> +from ipalib import errors
> +from ipapython import sysrestore
> +from ipapython import ipautil
> +
> +import random
> +import string
> +import struct
> +
> +def check_inst(unattended):
> + has_smb = True
> +
> + if not os.path.exists('/usr/sbin/smbd'):
> + print "Samba was not found on this system"
> + print "Please install the 'samba' package and start the
> installation again"
> + has_smb = False
> +
> + #TODO: Add check for needed samba4 libraries
> +
> + return has_smb
> +
> +def ipa_smb_conf_exists():
> + if os.path.exists('/etc/ipa/smb.conf'):
> + print "Samba is already configured for this IPA server."
> + return True
> +
> + return False
> +
> +def random_password(length=16):
> + myrg = random.SystemRandom()
> + alphabet = string.letters[0:52] + string.digits +
> string.punctuation
> + pw = str().join(myrg.choice(alphabet) for _ in range(length))
> + return pw
We have a utility function to generate a proper random password IIRC.
> +class SMBInstance(service.Service):
> + def __init__(self, fstore=None, dm_password=None):
> + service.Service.__init__(self, "smb",
> dm_password=dm_password)
> +
> + if fstore:
> + self.fstore = fstore
> + else:
> + self.fstore =
> sysrestore.FileStore('/var/lib/ipa/sysrestore')
> +
> + def __create_samba_user(self):
> + print "The user for Samba is %s" % self.smb_dn
> + try:
> + self.admin_conn.getEntry(self.smb_dn, ldap.SCOPE_BASE)
> + print "Samba user entry exists, not resetting password"
> + return
> + except errors.NotFound:
> + pass
> +
> + # The user doesn't exist, add it
> + entry = ipaldap.Entry(self.smb_dn)
> + entry.setValues("objectclass", ["account",
> "simplesecurityobject"])
> + entry.setValues("uid", "samba")
> + entry.setValues("userPassword", self.smb_dn_pwd)
> + self.admin_conn.add_s(entry)
> +
> + # And finally grant it permission to read NT passwords, we do
> not want
> + # to support LM passwords so there is no need to allow access
> to them
> + mod = [(ldap.MOD_ADD, 'aci',
> + str(['(targetattr = "sambaNTPassword")(version 3.0; acl
> "Samba user can read NT passwords"; allow (read) userdn="ldap:///%
> s";)' % self.smb_dn]))]
> + try:
> + self.admin_conn.modify_s(self.suffix, mod)
> + except ldap.TYPE_OR_VALUE_EXISTS:
> + logging.debug("samba user aci already exists in suffix %s
> on %s" % (self.suffix, self.admin_conn.host))
> +
> + def __gen_sid_string(self):
> + sub_ids = struct.unpack("<LLL", os.urandom(12))
> + return "S-1-5-21-%d-%d-%d" % (sub_ids[0], sub_ids[1],
> sub_ids[2])
> +
> + def __create_samba_domain_object(self):
> + trust_dn = "cn=trusts,%s" % self.suffix
> + smb_dom_dn = "cn=ad,%s" % trust_dn
> +
> + try:
> + self.admin_conn.getEntry(smb_dom_dn, ldap.SCOPE_BASE)
> + print "Samba domain object already exists"
> + return
> + except errors.NotFound:
> + pass
> +
> + try:
> + self.admin_conn.getEntry(trust_dn, ldap.SCOPE_BASE)
> + except errors.NotFound:
> + entry = ipaldap.Entry(trust_dn)
> + entry.setValues("objectclass", ["nsContainer"])
> + entry.setValues("cn", "trusts")
> + self.admin_conn.add_s(entry)
> +
> + entry = ipaldap.Entry(smb_dom_dn)
> + entry.setValues("objectclass", ["sambaDomain",
> "nsContainer"])
> + entry.setValues("cn", "ad")
> + entry.setValues("sambaDomainName", self.domain_name)
The sambaDomainName is generally a netbios name (or short name), it
appears you are setting the DNS domain name here.
Should we prompt the user for a short domain name to be used instead ?
Or maybe default to the first DNS domain component and allow the user to
override ?
> + entry.setValues("sambaSID", self.__gen_sid_string())
> + #TODO: which MAY attributes do we want to set ?
> + self.admin_conn.add_s(entry)
> +
> + def __write_sysconfig_samba(self):
> + self.fstore.backup_file(self.sysconfig_file)
> +
> + fd = open(self.sysconfig_file, "w")
> + fd.write('### Added by IPA Installer ###\n')
> + fd.write('# Options to smbd\n')
> + fd.write('SMBDOPTIONS="-D -s /etc/ipa/smb.conf"\n')
> + fd.write('# Options to nmbd\n')
> + fd.write('NMBDOPTIONS="-D"\n')
> + fd.write('# Options for winbindd\n')
> + fd.write('WINBINDOPTIONS=""\n')
> + fd.close()
If we are running nmbd and/or winbindd we need to pass them the proper
smb.conf file too.
> + def __write_smb_conf(self):
> + fd = open(self.smb_conf, "w")
> + fd.write('### Added by IPA Installer ###\n')
> + fd.write('[global]\n')
> + fd.write('config backend = registry\n')
> + fd.close()
> +
> +
> + def __write_smb_registry(self):
> + [fd, tmp_name] = tempfile.mkstemp()
> +
> + os.write(fd, '[global]\n')
> + os.write(fd, 'workgroup = %s\n' % self.domain_name)
This again shuld be the netbios domain name, not the fqdn.
The workgroup name can't be longer than 15 chars IIRC.
> + os.write(fd, 'realm = %s\n' % self.realm_name)
> + os.write(fd, 'security = ads\n')
Why ADS ? This should probably be security = user
> + os.write(fd, 'domain master = yes\n')
> + os.write(fd, 'domain logons = yes\n')
> + os.write(fd, 'passdb backend = IPA_ldapsam:ldap://%s\n' %
> self.fqdn)
We should use ldapi here, not ldap://
> + os.write(fd, 'ldapsam:trusted=yes\n')
> + os.write(fd, 'ldapsam:editposix=yes\n')
We do not allow to create users so editposix should not be necessary.
> + os.write(fd, 'ldap ssl = startTLS\n')
We shouldn't need SSL if we use ldapi above.
> + os.write(fd, 'ldap admin dn = %s\n' % self.smb_dn)
> + os.write(fd, 'ldap suffix = cn=accounts,dc=ipa,dc=test\n')
> + os.write(fd, 'ldap user suffix = cn=users\n')
> + os.write(fd, 'ldap group suffix = cn=groups\n')
> + os.write(fd, 'ldap machine suffix = cn=computers\n')
> + os.write(fd, 'ldap idmap suffix = cn=idmap\n')
We probably won't use this.
> + os.write(fd, 'rpc_server:epmapper = external\n')
> + os.write(fd, 'rpc_server:lsarpc = external\n')
We may need also the alias 'lsass' pipe name configured here.
> + os.write(fd, 'rpc_server:samr = external\n')
> + os.write(fd, 'rpc_server:netlogon = external\n')
> + os.write(fd, 'rpc_daemon:epmd = fork\n')
> + os.write(fd, 'rpc_daemon:lsasd = fork\n')
> + os.close(fd)
We may also want to set some defaults for logging
(log level, max size of logs before rotating, log name format ?)
> + args = ["/usr/bin/net", "conf", "import", tmp_name]
> +
> + try:
> + ipautil.run(args)
> + finally:
> + os.remove(tmp_name)
> +
> + def __set_smb_ldap_password(self):
> + args = ["/usr/bin/smbpasswd", "-c", self.smb_conf, "-w",
> self.smb_dn_pwd ]
We should either pass this password in via stdin (using -W) or you
should at least pass ipautil.run below the password to be blacked out of
install logs.
> + ipautil.run(args)
> +
[..]
Do we want to run winbindd at all on ipa servers ?
Should we join it to ourselves ? (Would require creation of a computer
account).
Simo.
--
Simo Sorce * Red Hat, Inc * New York
More information about the Freeipa-devel
mailing list