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 <sb...@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 _______________________________________________ Freeipa-devel mailing list Freeipa-devel@redhat.com https://www.redhat.com/mailman/listinfo/freeipa-devel