# 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 os import errno import ldap import tempfile import uuid from ipaserver import ipaldap from ipaserver.install import installutils from ipaserver.install import service from ipaserver.install.dsinstance import realm_to_serverid from ipaserver.install.bindinstance import get_rr, add_rr, del_rr, \ dns_zone_exists from ipalib import errors, api from ipapython import sysrestore from ipapython import ipautil from ipapython.ipa_log_manager import * import string import struct ALLOWED_NETBIOS_CHARS = string.ascii_uppercase + string.digits def check_inst(): for smbfile in ['/usr/sbin/smbd', '/usr/bin/net', '/usr/bin/smbpasswd']: if not os.path.exists(smbfile): print "%s was not found on this system" % file 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: conf_fd = open('/etc/samba/smb.conf', 'r') except IOError, err: if err.errno == errno.ENOENT: return False lines = conf_fd.readlines() conf_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): ATTR_SID = "ipaNTSecurityIdentifier" ATTR_FLAT_NAME = "ipaNTFlatName" ATTR_GUID = "ipaNTDomainGUID" OBJC_USER = "ipaNTUserAttrs" OBJC_GROUP = "ipaNTGroupAttrs" OBJC_DOMAIN = "ipaNTDomainAttrs" def __init__(self, fstore=None, dm_password=None): self.fqdn = None self.ip_address = None self.realm_name = None self.domain_name = None self.netbios_name = None self.no_msdcs = None self.smbd_user = None self.suffix = None self.ldapi_socket = None self.smb_conf = None self.smb_dn = None self.smb_dn_pwd = None self.trust_dn = None self.smb_dom_dn = None self.sub_dict = 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.addEntry(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 = "ipaNTHash")' \ '(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 = "ipaNTTrustType || ipaNTTrustAttributes || ' \ 'ipaNTTrustDirection || ' \ 'ipaNTTrustPartner || ipaNTFlatName || ' \ 'ipaNTTrustAuthOutgoing || ' \ 'ipaNTTrustAuthIncoming || ' \ 'ipaNTSecurityIdentifier || ' \ 'ipaNTTrustForestTrustInfo || ' \ 'ipaNTTrustPosixOffset || ' \ 'ipaNTSupportedEncryptionTypes")' \ '(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: root_logger.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("