# Authors: Sumit Bose # # 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 . # import logging import os import errno import ldap import service import tempfile import installutils from ipaserver import ipaldap from ipaserver.install.dsinstance import realm_to_serverid from ipalib import errors from ipapython import sysrestore from ipapython import ipautil import random import string import struct allowed_netbios_chars = string.ascii_uppercase + string.digits def check_inst(unattended): for f in ['/usr/sbin/smbd', '/usr/bin/net', '/usr/bin/smbpasswd']: if not os.path.exists(f): print "%s was not found on this system" % f print "Please install the 'samba' packages and start the installation again" return False #TODO: Add check for needed samba4 libraries return True def ipa_smb_conf_exists(): try: fd = open('/etc/samba/smb.conf', 'r') except IOError, e: if e.errno == errno.ENOENT: return False lines = fd.readlines() fd.close() for line in lines: if line.startswith('### Added by IPA Installer ###'): return True return False def check_netbios_name(s): # NetBIOS names may not be longer than 15 allowed characters if not s or len(s) > 15 or ''.join([c for c in s if c not in allowed_netbios_chars]): return False return True def make_netbios_name(s): return ''.join([c for c in s.split('.')[0].upper() if c in allowed_netbios_chars])[:15] class ADTRUSTInstance(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, resetting password" self.admin_conn.modify_s(self.smb_dn, [(ldap.MOD_REPLACE, "userPassword", self.smb_dn_pwd)]) 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. # Also the premission to create trusted domain objects below the # domain object is granted. 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)), (ldap.MOD_ADD, 'aci', str('(target = "ldap:///cn=ad,cn=trusts,%s")' \ '(targetattr = "sambaTrustType || sambaTrustAttributes || sambaTrustDirection || sambaTrustPartner || sambaFlatName || sambaTrustAuthOutgoing || sambaTrustAuthIncoming || sambaSecurityIdentifier || sambaTrustForestTrustInfo || sambaTrustPosixOffset || sambaSupportedEncryptionTypes")' \ '(version 3.0;acl "Allow samba user to create and delete trust accounts";' \ 'allow (write,add,delete) userdn = "ldap:///%s";)' % \ (self.suffix, 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("