コード例 #1
0
ファイル: samba-shares.py プロジェクト: bopopescu/smart-1
def handler(dn, new, old, command):

    configRegistry = ConfigRegistry()
    configRegistry.load()
    interfaces = Interfaces(configRegistry)

    # dymanic module object filter
    current_fqdn = "%s.%s" % (configRegistry['hostname'], domainname)
    current_ip = str(interfaces.get_default_ip_address().ip)

    new_univentionShareHost = new.get('univentionShareHost', [None])[0]
    if new and not new_univentionShareHost in (current_fqdn, current_ip):
        new = {}  ## new object is not for this host

    old_univentionShareHost = old.get('univentionShareHost', [None])[0]
    if old and not old_univentionShareHost in (current_fqdn, current_ip):
        old = {}  ## old object is not for this host

    if not (new or old):
        return

    # create tmp dir
    tmpDir = os.path.dirname(tmpFile)
    listener.setuid(0)
    try:
        if not os.path.exists(tmpDir):
            os.makedirs(tmpDir)
    except Exception, e:
        univention.debug.debug(
            univention.debug.LISTENER, univention.debug.ERROR,
            "%s: could not create tmp dir %s (%s)" % (name, tmpDir, str(e)))
        return
コード例 #2
0
ファイル: samba-shares.py プロジェクト: B-Rich/smart
def handler(dn, new, old, command):

	configRegistry = ConfigRegistry()
	configRegistry.load()
	interfaces = Interfaces(configRegistry)

	# dymanic module object filter
	current_fqdn = "%s.%s" % (configRegistry['hostname'], domainname)
	current_ip = str(interfaces.get_default_ip_address().ip)

	new_univentionShareHost = new.get('univentionShareHost', [None])[0]
	if new and not new_univentionShareHost in (current_fqdn, current_ip):
		new = {}	## new object is not for this host

	old_univentionShareHost = old.get('univentionShareHost', [None])[0]
	if old and not old_univentionShareHost in (current_fqdn, current_ip):
		old = {}	## old object is not for this host

	if not (new or old):
		return

	# create tmp dir
	tmpDir = os.path.dirname(tmpFile)
	listener.setuid(0)
	try:
		if not os.path.exists(tmpDir):
			os.makedirs(tmpDir)
	except Exception, e:
		univention.debug.debug(
			univention.debug.LISTENER, univention.debug.ERROR,
			"%s: could not create tmp dir %s (%s)" % (name, tmpDir, str(e)))
		return
コード例 #3
0
 def test_ipv6_order_multi(self):
     """Test multiple IPv6 ordering."""
     t = Interfaces(
         ucr={
             'interfaces/eth0/ipv6/foo/address': '1:2:3:4:5:6:7:8',
             'interfaces/eth0/ipv6/foo/prefix': '64',
             'interfaces/eth1/order': '2',
             'interfaces/eth1/ipv6/default/address': '1:2:3:4:5:6:7:8',
             'interfaces/eth1/ipv6/default/prefix': '64',
             'interfaces/eth1/ipv6/a/address': '2:3:4:5:6:7:8:9',
             'interfaces/eth1/ipv6/a/prefix': '72',
             'interfaces/eth2/order': '1',
             'interfaces/eth2/ipv6/z/address': '1:2:3:4:5:6:7:8',
             'interfaces/eth2/ipv6/z/prefix': '64',
             'interfaces/eth2/ipv6/default/address': '2:3:4:5:6:7:8:9',
             'interfaces/eth2/ipv6/default/prefix': '72',
             'interfaces/primary': 'eth2,eth1',
         })
     assert [] == [s.name for _n, s in t.ipv4_interfaces]
     assert [
      ('eth2', 'default'),
      ('eth2', 'z'),
      ('eth1', 'default'),
      ('eth1', 'a'),
      ('eth0', 'foo')] == \
      [(s.name, n) for s, n in t.ipv6_interfaces]
     assert IPv6Interface(
         u'2:3:4:5:6:7:8:9/72') == t.get_default_ip_address()
     assert t.get_default_ipv4_address() is None
     assert IPv6Interface(
         u'2:3:4:5:6:7:8:9/72') == t.get_default_ipv6_address()
コード例 #4
0
 def test_incomplete_net(self):
     """Test incomplete interface with netmask/prefix."""
     t = Interfaces(
         ucr={
             'interfaces/eth0/netmask': '255.255.255.0',
             'interfaces/eth0/ipv6/default/prefix': '64',
         })
     assert [] == [s.name for _n, s in t.ipv4_interfaces]
     assert [] == [s.name for s, _n in t.ipv6_interfaces]
     assert t.get_default_ip_address() is None
     assert t.get_default_ipv4_address() is None
     assert t.get_default_ipv6_address() is None
コード例 #5
0
 def test_ipv4_only(self):
     """Test IPv4 only interface."""
     t = Interfaces(
         ucr={
             'interfaces/eth0/address': '1.2.3.4',
             'interfaces/eth0/netmask': '255.255.255.0',
         })
     assert ['eth0'] == [s.name for _n, s in t.ipv4_interfaces]
     assert [] == [s.name for s, _n in t.ipv6_interfaces]
     assert IPv4Interface(u'1.2.3.4/24') == t.get_default_ip_address()
     assert IPv4Interface(u'1.2.3.4/24') == t.get_default_ipv4_address()
     assert t.get_default_ipv6_address() is None
コード例 #6
0
 def test_empty(self):
     """Test no interface."""
     t = Interfaces(ucr={})
     assert 'eth0' == t.primary
     assert t.ipv4_gateway is None
     assert t.ipv6_gateway is None
     assert t.ipv6_gateway_zone_index is None
     assert [] == [s.name for _n, s in t.ipv4_interfaces]
     assert [] == [s.name for s, _n in t.ipv6_interfaces]
     assert t.get_default_ip_address() is None
     assert t.get_default_ipv4_address() is None
     assert t.get_default_ipv6_address() is None
コード例 #7
0
 def test_incomplete_addr(self):
     """Test incomplete interface with address."""
     t = Interfaces(
         ucr={
             'interfaces/eth0/address': '2.3.4.5',
             'interfaces/eth0/ipv6/default/address': '1:2:3:4:5:6:7:8',
         })
     assert [] == [s.name for _n, s in t.ipv4_interfaces]
     assert [] == [s.name for s, _n in t.ipv6_interfaces]
     assert t.get_default_ip_address() is None
     assert t.get_default_ipv4_address() is None
     assert t.get_default_ipv6_address() is None
コード例 #8
0
 def test_ipv4_multi(self):
     """Test multiple IPv4 interfaces."""
     t = Interfaces(
         ucr={
             'interfaces/eth0/address': '1.2.3.4',
             'interfaces/eth0/netmask': '255.255.255.0',
             'interfaces/eth1/address': '2.3.4.5',
             'interfaces/eth1/netmask': '255.255.255.0',
         })
     assert ['eth0' == 'eth1'], [s.name for _n, s in t.ipv4_interfaces]
     assert [] == [s.name for s, _n in t.ipv6_interfaces]
     assert IPv4Interface(u'1.2.3.4/24') == t.get_default_ip_address()
     assert IPv4Interface(u'1.2.3.4/24') == t.get_default_ipv4_address()
     assert t.get_default_ipv6_address() is None
コード例 #9
0
 def test_ipv6_disjunct(self):
     """Test disjunct IPv4 IPv6 interfaces."""
     t = Interfaces(
         ucr={
             'interfaces/eth0/address': '2.3.4.5',
             'interfaces/eth0/netmask': '255.255.255.0',
             'interfaces/eth1/ipv6/default/address': '1:2:3:4:5:6:7:8',
             'interfaces/eth1/ipv6/default/prefix': '64',
         })
     assert ['eth0'] == [s.name for _n, s in t.ipv4_interfaces]
     assert ['eth1'] == [s.name for s, _n in t.ipv6_interfaces]
     assert IPv4Interface(u'2.3.4.5/24') == t.get_default_ip_address()
     assert IPv4Interface(u'2.3.4.5/24') == t.get_default_ipv4_address()
     assert IPv6Interface(
         u'1:2:3:4:5:6:7:8/64') == t.get_default_ipv6_address()
コード例 #10
0
 def test_ipv6_multi(self):
     """Test multiple IPv6 interfaces."""
     t = Interfaces(
         ucr={
             'interfaces/eth0/ipv6/default/address': '1:2:3:4:5:6:7:8',
             'interfaces/eth0/ipv6/default/prefix': '64',
             'interfaces/eth1/ipv6/default/address': '2:3:4:5:6:7:8:9',
             'interfaces/eth1/ipv6/default/prefix': '64',
         })
     assert [] == [s.name for _n, s in t.ipv4_interfaces]
     assert ['eth0', 'eth1'] == [s.name for s, _n in t.ipv6_interfaces]
     assert IPv6Interface(
         u'1:2:3:4:5:6:7:8/64') == t.get_default_ip_address()
     assert t.get_default_ipv4_address() is None
     assert IPv6Interface(
         u'1:2:3:4:5:6:7:8/64') == t.get_default_ipv6_address()
コード例 #11
0
 def setup_parser(self, parser):
     interfaces = Interfaces(ucr_instance())
     ip_address = interfaces.get_default_ip_address()
     if ip_address:
         default_ip_address = ip_address.ip
     else:
         default_ip_address = '127.0.0.1'
     super(DevSetupLocalAppcenter, self).setup_parser(parser)
     parser.add_argument(
         '--appcenter-host',
         default=default_ip_address,
         help='The hostname of the new App Center. Default: %(default)s')
     parser.add_argument(
         '--revert',
         action='store_true',
         help='Reverts the changes of a previous dev-setup-local-appcenter')
コード例 #12
0
 def test_ipv4_order(self):
     """Test IPv4 ordering."""
     t = Interfaces(
         ucr={
             'interfaces/eth0/address': '1.2.3.4',
             'interfaces/eth0/netmask': '255.255.255.0',
             'interfaces/eth1/address': '2.3.4.5',
             'interfaces/eth1/netmask': '255.255.0.0',
             'interfaces/eth2/order': '1',
             'interfaces/eth2/address': '3.4.5.6',
             'interfaces/eth2/netmask': '255.0.0.0',
         })
     assert ['eth2', 'eth0',
             'eth1'] == [s.name for _n, s in t.ipv4_interfaces]
     assert [] == [s.name for s, _n in t.ipv6_interfaces]
     assert IPv4Interface(u'1.2.3.4/24') == t.get_default_ip_address()
     assert IPv4Interface(u'1.2.3.4/24') == t.get_default_ipv4_address()
     assert t.get_default_ipv6_address() is None
コード例 #13
0
 def test_ipv6_order(self):
     """Test IPv6 ordering."""
     t = Interfaces(
         ucr={
             'interfaces/eth0/ipv6/default/address': '1:2:3:4:5:6:7:8',
             'interfaces/eth0/ipv6/default/prefix': '64',
             'interfaces/eth1/ipv6/default/address': '2:3:4:5:6:7:8:9',
             'interfaces/eth1/ipv6/default/prefix': '72',
             'interfaces/eth2/order': '1',
             'interfaces/eth2/ipv6/default/address': '3:4:5:6:7:8:9:a',
             'interfaces/eth2/ipv6/default/prefix': '80',
         })
     assert [] == [s.name for _n, s in t.ipv4_interfaces]
     assert ['eth2', 'eth0',
             'eth1'] == [s.name for s, _n in t.ipv6_interfaces]
     assert IPv6Interface(
         u'1:2:3:4:5:6:7:8/64') == t.get_default_ip_address()
     assert t.get_default_ipv4_address() is None
     assert IPv6Interface(
         u'1:2:3:4:5:6:7:8/64') == t.get_default_ipv6_address()
コード例 #14
0
ファイル: nfs-shares.py プロジェクト: B-Rich/smart
# /usr/share/common-licenses/AGPL-3; if not, see
# <http://www.gnu.org/licenses/>.

__package__='' 	# workaround for PEP 366
import listener
import os
import re
import univention.debug
import univention.lib.listenerSharePath
import cPickle
from univention.config_registry.interfaces import Interfaces

hostname=listener.baseConfig['hostname']
domainname=listener.baseConfig['domainname']
interfaces = Interfaces(listener.configRegistry)
ip = interfaces.get_default_ip_address().ip

name='nfs-shares'
description='Create configuration for NFS shares'
filter='(&(objectClass=univentionShare)(|(univentionShareHost=%s.%s)(univentionShareHost=%s)))' % (hostname, domainname, ip)
modrdn='1'

__exports = '/etc/exports'
__comment_pattern = re.compile('^"*/.*#[ \t]*LDAP:[ \t]*(.*)')

tmpFile = os.path.join("/var", "cache", "univention-directory-listener", name + ".oldObject")

def handler(dn, new, old, command):

	# create tmp dir
	tmpDir = os.path.dirname(tmpFile)
コード例 #15
0
def handler(dn, new, old, command):
    configRegistry = ConfigRegistry()
    configRegistry.load()
    interfaces = Interfaces(configRegistry)

    # dymanic module object filter
    current_fqdn = "%s.%s" % (configRegistry['hostname'], domainname)
    current_ip = str(interfaces.get_default_ip_address().ip)

    new_univentionShareHost = new.get('univentionShareHost', [None])[0]
    if new and new_univentionShareHost not in (current_fqdn, current_ip):
        new = {}  # new object is not for this host

    old_univentionShareHost = old.get('univentionShareHost', [None])[0]
    if old and old_univentionShareHost not in (current_fqdn, current_ip):
        old = {}  # old object is not for this host

    if not (new or old):
        return

    # create tmp dir
    tmpDir = os.path.dirname(tmpFile)
    listener.setuid(0)
    try:
        if not os.path.exists(tmpDir):
            os.makedirs(tmpDir)
    except Exception as e:
        univention.debug.debug(
            univention.debug.LISTENER, univention.debug.ERROR,
            "%s: could not create tmp dir %s (%s)" % (name, tmpDir, str(e)))
        return
    finally:
        listener.unsetuid()

    # modrdn stuff
    # 'r'+'a' -> renamed
    # command='r' and "not new and old"
    # command='a' and "new and not old"

    # write old object to pickle file
    oldObject = {}
    listener.setuid(0)
    try:
        # object was renamed -> save old object
        if command == "r" and old:
            f = open(tmpFile, "w+")
            os.chmod(tmpFile, 0o600)
            cPickle.dump({"dn": dn, "old": old}, f)
            f.close()
        elif command == "a" and not old and os.path.isfile(tmpFile):
            f = open(tmpFile, "r")
            p = cPickle.load(f)
            f.close()
            oldObject = p.get("old", {})
            os.remove(tmpFile)
    except Exception as e:
        if os.path.isfile(tmpFile):
            os.remove(tmpFile)
        univention.debug.debug(
            univention.debug.LISTENER, univention.debug.ERROR,
            "%s: could not read/write tmp file %s (%s)" %
            (name, tmpFile, str(e)))
    finally:
        listener.unsetuid()

    if old:
        share_name = old.get('univentionShareSambaName', [''])[0]
        share_name_mapped = urllib.quote(share_name, safe='')
        filename = '/etc/samba/shares.conf.d/%s' % (share_name_mapped, )
        listener.setuid(0)
        try:
            if os.path.exists(filename):
                os.unlink(filename)
        finally:
            listener.unsetuid()

    def _quote(arg):
        if ' ' in arg or '"' in arg or '\\' in arg:
            arg = '"%s"' % (arg.replace('\\', '\\\\').replace('"', '\\"'), )
        return arg.replace('\n', '')

    def _simple_quote(arg):
        return arg.replace('\n', '')

    def _map_quote(args):
        return (_quote(arg) for arg in args)

    if new:
        share_name = new.get('univentionShareSambaName', [''])[0]
        if not _validate_smb_share_name(share_name):
            univention.debug.debug(
                univention.debug.LISTENER, univention.debug.ERROR,
                "invalid samba share name: %r" % (share_name, ))
            return
        share_name_mapped = urllib.quote(share_name, safe='')
        filename = '/etc/samba/shares.conf.d/%s' % (share_name_mapped, )

        # important!: createOrRename() checks if the share path is allowed. this must be done prior to writing any files.
        # try to create directory to share
        if share_name != 'homes':
            # object was renamed
            if not old and oldObject and command == "a":
                old = oldObject
            listener.setuid(0)
            try:
                ret = univention.lib.listenerSharePath.createOrRename(
                    old, new, listener.configRegistry)
            finally:
                listener.unsetuid()
            if ret:
                univention.debug.debug(
                    univention.debug.LISTENER, univention.debug.ERROR,
                    "%s: rename/create of sharePath for %s failed (%s)" %
                    (name, dn, ret))
                return

        listener.setuid(0)
        try:
            fp = open(filename, 'w')

            print('[%s]' % (share_name, ), file=fp)
            if share_name != 'homes':
                print('path = %s' % _quote(new['univentionSharePath'][0]),
                      file=fp)
            mapping = [
                ('description', 'comment'),
                ('univentionShareSambaMSDFS', 'msdfs root'),
                ('univentionShareSambaWriteable', 'writeable'),
                ('univentionShareSambaBrowseable', 'browseable'),
                ('univentionShareSambaPublic', 'public'),
                ('univentionShareSambaDosFilemode', 'dos filemode'),
                ('univentionShareSambaHideUnreadable', 'hide unreadable'),
                ('univentionShareSambaCreateMode', 'create mode'),
                ('univentionShareSambaDirectoryMode', 'directory mode'),
                ('univentionShareSambaForceCreateMode', 'force create mode'),
                ('univentionShareSambaForceDirectoryMode',
                 'force directory mode'),
                ('univentionShareSambaLocking', 'locking'),
                ('univentionShareSambaBlockingLocks', 'blocking locks'),
                ('univentionShareSambaStrictLocking', 'strict locking'),
                ('univentionShareSambaOplocks', 'oplocks'),
                ('univentionShareSambaLevel2Oplocks', 'level2 oplocks'),
                ('univentionShareSambaFakeOplocks', 'fake oplocks'),
                ('univentionShareSambaBlockSize', 'block size'),
                ('univentionShareSambaCscPolicy', 'csc policy'),
                ('univentionShareSambaValidUsers', 'valid users'),
                ('univentionShareSambaInvalidUsers', 'invalid users'),
                ('univentionShareSambaForceUser', 'force user'),
                ('univentionShareSambaForceGroup', 'force group'),
                ('univentionShareSambaHideFiles', 'hide files'),
                ('univentionShareSambaNtAclSupport', 'nt acl support'),
                ('univentionShareSambaInheritAcls', 'inherit acls'),
                ('univentionShareSambaPostexec', 'postexec'),
                ('univentionShareSambaPreexec', 'preexec'),
                ('univentionShareSambaWriteList', 'write list'),
                ('univentionShareSambaVFSObjects', 'vfs objects'),
                ('univentionShareSambaInheritOwner', 'inherit owner'),
                ('univentionShareSambaInheritPermissions',
                 'inherit permissions'),
                ('univentionShareSambaHostsAllow', 'hosts allow'),
                ('univentionShareSambaHostsDeny', 'hosts deny'),
            ]

            vfs_objects = []
            samba4_ntacl_backend = listener.configRegistry.get(
                'samba4/ntacl/backend', 'native')
            if samba4_ntacl_backend == 'native':
                vfs_objects.append('acl_xattr')
                if listener.configRegistry.is_true(
                        'samba/vfs/acl_xattr/ignore_system_acls', False):
                    print('acl_xattr:ignore system acls = yes')
            elif samba4_ntacl_backend == 'tdb':
                vfs_objects.append('acl_tdb')

            additional_vfs_objects = new.get('univentionShareSambaVFSObjects',
                                             [])
            if additional_vfs_objects:
                vfs_objects.extend(additional_vfs_objects)

            if vfs_objects:
                print('vfs objects = %s' %
                      (' '.join(_map_quote(vfs_objects)), ),
                      file=fp)

            for attr, var in mapping:
                if not new.get(attr):
                    continue
                if attr == 'univentionShareSambaVFSObjects':
                    continue
                if attr == 'univentionShareSambaDirectoryMode' and new[
                        'univentionSharePath'] in ('/tmp', '/tmp/'):
                    continue
                if attr in ('univentionShareSambaHostsAllow',
                            'univentionShareSambaHostsDeny'):
                    print('%s = %s' % (var,
                                       (', '.join(_map_quote(new[attr])))),
                          file=fp)
                elif attr in ('univentionShareSambaValidUsers',
                              'univentionShareSambaInvalidUsers'):
                    print('%s = %s' % (var, _simple_quote(new[attr][0])),
                          file=fp)
                else:
                    print('%s = %s' % (var, _quote(new[attr][0])), file=fp)

            for setting in new.get(
                    'univentionShareSambaCustomSetting', []
            ):  # FIXME: vulnerable to injection of further paths and entries
                print(setting.replace('\n', ''), file=fp)

            # implicit settings

            # acl and inherit -> map acl inherit (Bug #47850)
            if '1' in new.get('univentionShareSambaNtAclSupport',
                              []) and '1' in new.get(
                                  'univentionShareSambaInheritAcls', []):
                print('map acl inherit = yes', file=fp)
        finally:
            listener.unsetuid()

    if (not (new and old)) or (new['univentionShareSambaName'][0] !=
                               old['univentionShareSambaName'][0]):
        global ucr_handlers
        listener.setuid(0)
        try:
            run_ucs_commit = False
            if not os.path.exists('/etc/samba/shares.conf'):
                run_ucs_commit = True
            fp = open('/etc/samba/shares.conf.temp', 'w')
            print(
                '# Warning: This file is auto-generated and will be overwritten by \n#          univention-directory-listener module. \n#          Please edit the following file instead: \n#          /etc/samba/local.conf \n  \n# Warnung: Diese Datei wurde automatisch generiert und wird durch ein \n#          univention-directory-listener Module überschrieben werden. \n#          Ergänzungen können an folgender Datei vorgenommen werden: \n# \n#          /etc/samba/local.conf \n#',
                file=fp)

            for f in os.listdir('/etc/samba/shares.conf.d'):
                print('include = %s' %
                      _quote(os.path.join('/etc/samba/shares.conf.d', f)),
                      file=fp)
            fp.close()
            os.rename('/etc/samba/shares.conf.temp', '/etc/samba/shares.conf')
            if run_ucs_commit:
                ucr_handlers.commit(listener.configRegistry,
                                    ['/etc/samba/smb.conf'])
        finally:
            listener.unsetuid()
コード例 #16
0
def handler(dn, new, old, command):
    configRegistry = ConfigRegistry()
    configRegistry.load()
    interfaces = Interfaces(configRegistry)

    # dymanic module object filter
    current_fqdn = "%s.%s" % (configRegistry['hostname'], domainname)
    current_ip = str(interfaces.get_default_ip_address().ip)

    new_univentionShareHost = new.get('univentionShareHost', [None])[0]
    if new and new_univentionShareHost not in (current_fqdn, current_ip):
        new = {}  # new object is not for this host

    old_univentionShareHost = old.get('univentionShareHost', [None])[0]
    if old and old_univentionShareHost not in (current_fqdn, current_ip):
        old = {}  # old object is not for this host

    if not (new or old):
        return

    # create tmp dir
    tmpDir = os.path.dirname(tmpFile)
    listener.setuid(0)
    try:
        if not os.path.exists(tmpDir):
            os.makedirs(tmpDir)
    except Exception as e:
        univention.debug.debug(
            univention.debug.LISTENER, univention.debug.ERROR,
            "%s: could not create tmp dir %s (%s)" % (name, tmpDir, str(e)))
        return
    finally:
        listener.unsetuid()

    # modrdn stuff
    # 'r'+'a' -> renamed
    # command='r' and "not new and old"
    # command='a' and "new and not old"

    # write old object to pickle file
    oldObject = {}
    listener.setuid(0)
    try:
        # object was renamed -> save old object
        if command == "r" and old:
            f = open(tmpFile, "w+")
            os.chmod(tmpFile, 0o600)
            cPickle.dump({"dn": dn, "old": old}, f)
            f.close()
        elif command == "a" and not old and os.path.isfile(tmpFile):
            f = open(tmpFile, "r")
            p = cPickle.load(f)
            f.close()
            oldObject = p.get("old", {})
            os.remove(tmpFile)
    except Exception as e:
        if os.path.isfile(tmpFile):
            os.remove(tmpFile)
        univention.debug.debug(
            univention.debug.LISTENER, univention.debug.ERROR,
            "%s: could not read/write tmp file %s (%s)" %
            (name, tmpFile, str(e)))
    finally:
        listener.unsetuid()

    if old:
        share_name = old.get('univentionShareSambaName', [''])[0]
        share_name_mapped = urllib.quote(share_name, safe='')
        filename = '/etc/samba/shares.conf.d/%s' % (share_name_mapped, )
        listener.setuid(0)
        try:
            if os.path.exists(filename):
                os.unlink(filename)
        finally:
            listener.unsetuid()

    def _quote(arg):
        if ' ' in arg or '"' in arg or '\\' in arg:
            arg = '"%s"' % (arg.replace('\\', '\\\\').replace('"', '\\"'), )
        return arg.replace('\n', '')

    def _simple_quote(arg):
        return arg.replace('\n', '')

    def _map_quote(args):
        return (_quote(arg) for arg in args)

    if new:
        share_name = new['univentionShareSambaName'][0]
        if not _validate_smb_share_name(share_name):
            univention.debug.debug(
                univention.debug.LISTENER, univention.debug.ERROR,
                "invalid samba share name: %r" % (share_name, ))
            return
        share_name_mapped = urllib.quote(share_name, safe='')
        filename = '/etc/samba/shares.conf.d/%s' % (share_name_mapped, )

        # important!: createOrRename() checks if the share path is allowed. this must be done prior to writing any files.
        # try to create directory to share
        if share_name != 'homes':
            # object was renamed
            if not old and oldObject and command == "a":
                old = oldObject
            listener.setuid(0)
            try:
                ret = univention.lib.listenerSharePath.createOrRename(
                    old, new, listener.configRegistry)
            finally:
                listener.unsetuid()
            if ret:
                univention.debug.debug(
                    univention.debug.LISTENER, univention.debug.ERROR,
                    "%s: rename/create of sharePath for %s failed (%s)" %
                    (name, dn, ret))
                return

        listener.setuid(0)
        try:
            fp = open(filename, 'w')

            print >> fp, '[%s]' % (share_name, )
            if share_name != 'homes':
                print >> fp, 'path = %s' % _quote(
                    new['univentionSharePath'][0])
            mapping = [
                ('description', 'comment'),
                ('univentionShareSambaMSDFS', 'msdfs root'),
                ('univentionShareSambaWriteable', 'writeable'),
                ('univentionShareSambaBrowseable', 'browseable'),
                ('univentionShareSambaPublic', 'public'),
                ('univentionShareSambaDosFilemode', 'dos filemode'),
                ('univentionShareSambaHideUnreadable', 'hide unreadable'),
                ('univentionShareSambaCreateMode', 'create mode'),
                ('univentionShareSambaDirectoryMode', 'directory mode'),
                ('univentionShareSambaForceCreateMode', 'force create mode'),
                ('univentionShareSambaForceDirectoryMode',
                 'force directory mode'),
                ('univentionShareSambaLocking', 'locking'),
                ('univentionShareSambaBlockingLocks', 'blocking locks'),
                ('univentionShareSambaStrictLocking', 'strict locking'),
                ('univentionShareSambaOplocks', 'oplocks'),
                ('univentionShareSambaLevel2Oplocks', 'level2 oplocks'),
                ('univentionShareSambaFakeOplocks', 'fake oplocks'),
                ('univentionShareSambaBlockSize', 'block size'),
                ('univentionShareSambaCscPolicy', 'csc policy'),
                ('univentionShareSambaValidUsers', 'valid users'),
                ('univentionShareSambaInvalidUsers', 'invalid users'),
                ('univentionShareSambaForceUser', 'force user'),
                ('univentionShareSambaForceGroup', 'force group'),
                ('univentionShareSambaHideFiles', 'hide files'),
                ('univentionShareSambaNtAclSupport', 'nt acl support'),
                ('univentionShareSambaInheritAcls', 'inherit acls'),
                ('univentionShareSambaPostexec', 'postexec'),
                ('univentionShareSambaPreexec', 'preexec'),
                ('univentionShareSambaWriteList', 'write list'),
                ('univentionShareSambaVFSObjects', 'vfs objects'),
                ('univentionShareSambaInheritOwner', 'inherit owner'),
                ('univentionShareSambaInheritPermissions',
                 'inherit permissions'),
                ('univentionShareSambaHostsAllow', 'hosts allow'),
                ('univentionShareSambaHostsDeny', 'hosts deny'),
            ]

            vfs_objects = []
            samba4_ntacl_backend = listener.configRegistry.get(
                'samba4/ntacl/backend', 'native')
            if samba4_ntacl_backend == 'native':
                vfs_objects.append('acl_xattr')
            elif samba4_ntacl_backend == 'tdb':
                vfs_objects.append('acl_tdb')

            additional_vfs_objects = new.get('univentionShareSambaVFSObjects',
                                             [])
            if additional_vfs_objects:
                vfs_objects.extend(additional_vfs_objects)

            if vfs_objects:
                print >> fp, 'vfs objects = %s' % (' '.join(
                    _map_quote(vfs_objects)), )

            for attr, var in mapping:
                if not new.get(attr):
                    continue
                if attr == 'univentionShareSambaVFSObjects':
                    continue
                if attr == 'univentionShareSambaDirectoryMode' and new[
                        'univentionSharePath'] in ('/tmp', '/tmp/'):
                    continue
                if attr in ('univentionShareSambaHostsAllow',
                            'univentionShareSambaHostsDeny'):
                    print >> fp, '%s = %s' % (var, (', '.join(
                        _map_quote(new[attr]))))
                elif attr in ('univentionShareSambaValidUsers',
                              'univentionShareSambaInvalidUsers'):
                    print >> fp, '%s = %s' % (var, _simple_quote(new[attr][0]))
                else:
                    print >> fp, '%s = %s' % (var, _quote(new[attr][0]))

            for setting in new.get(
                    'univentionShareSambaCustomSetting', []
            ):  # FIXME: vulnerable to injection of further paths and entries
                print >> fp, setting.replace('\n', '')

            # implicit settings

            # acl and inherit -> map acl inherit (Bug #47850)
            if '1' in new.get('univentionShareSambaNtAclSupport',
                              []) and '1' in new.get(
                                  'univentionShareSambaInheritAcls', []):
                print >> fp, 'map acl inherit = yes'
        finally:
            listener.unsetuid()

    if (not (new and old)) or (new['univentionShareSambaName'][0] !=
                               old['univentionShareSambaName'][0]):
        global ucr_handlers
        listener.setuid(0)
        try:
            run_ucs_commit = False
            if not os.path.exists('/etc/samba/shares.conf'):
                run_ucs_commit = True
            fp = open('/etc/samba/shares.conf.temp', 'w')
            print >> fp, '# Warning: This file is auto-generated and will be overwritten by \n#          univention-directory-listener module. \n#          Please edit the following file instead: \n#          /etc/samba/local.conf \n  \n# Warnung: Diese Datei wurde automatisch generiert und wird durch ein \n#          univention-directory-listener Modul überschrieben werden. \n#          Ergänzungen können an folgende Datei vorgenommen werden: \n# \n#          /etc/samba/local.conf \n#'

            for f in os.listdir('/etc/samba/shares.conf.d'):
                print >> fp, 'include = %s' % _quote(
                    os.path.join('/etc/samba/shares.conf.d', f))
            fp.close()
            os.rename('/etc/samba/shares.conf.temp', '/etc/samba/shares.conf')
            if run_ucs_commit:
                ucr_handlers.commit(listener.configRegistry,
                                    ['/etc/samba/smb.conf'])
        finally:
            listener.unsetuid()

    if 'univentionShareSambaBaseDirAppendACL' in new or 'univentionShareSambaBaseDirAppendACL' in old:
        listener.setuid(0)
        try:
            proc = subprocess.Popen(
                [
                    'samba-tool', 'ntacl', 'get', '--as-sddl',
                    new['univentionSharePath'][0]
                ],
                stdout=subprocess.PIPE,
                close_fds=True,
            )
            stdout, stderr = proc.communicate()
            stdout = str(stdout)
            prev_aces = set()
            new_aces = set()
            re_ace = re.compile(r'\(.+?\)')
            if 'univentionShareSambaBaseDirAppendACL' in old:
                prev_aces = set(
                    sum([
                        re.findall(re_ace, acl)
                        for acl in old['univentionShareSambaBaseDirAppendACL']
                    ], []))
            if 'univentionShareSambaBaseDirAppendACL' in new:
                new_aces = set(
                    sum([
                        re.findall(re_ace, acl)
                        for acl in new['univentionShareSambaBaseDirAppendACL']
                    ], []))

            if (new_aces and new_aces != prev_aces) or (prev_aces
                                                        and not new_aces):
                # if old != new -> delete everything from old!
                for ace in prev_aces:
                    stdout = stdout.replace(ace, '')

                # Aces might be in there from something else (like explicit setting)
                # We don't want duplicates.
                new_aces = [ace for ace in new_aces if ace not in stdout]
                # Deny must be placed before rest. This is not done implicitly.
                # Since deny might be present before, add allow.
                # Be as explicit as possible, because aliases like Du (domain users)
                # are possible.

                res = re.search(r'(O:.+?G:.+?)D:[^\(]*(.+)', stdout)
                if res:
                    # dacl-flags are removed implicitly.
                    owner = res.group(1)
                    old_aces = res.group(2)

                    old_aces = re.findall(re_ace, old_aces)
                    allow_aces = "".join(
                        [ace for ace in old_aces if 'A;' in ace])
                    deny_aces = "".join(
                        [ace for ace in old_aces if 'D;' in ace])
                    allow_aces += "".join(
                        [ace for ace in new_aces if 'A;' in ace])
                    deny_aces += "".join(
                        [ace for ace in new_aces if 'D;' in ace])

                    dacl_flags = ""
                    if new_aces:
                        dacl_flags = "PAI"
                    sddl = "{}D:{}{}{}".format(owner, dacl_flags,
                                               deny_aces.strip(),
                                               allow_aces.strip())
                    univention.debug.debug(
                        univention.debug.LISTENER, univention.debug.PROCESS,
                        "Set new nt %s acl for dir %s" %
                        (sddl, new['univentionSharePath'][0]))
                    proc = subprocess.Popen([
                        'samba-tool', 'ntacl', 'set', sddl,
                        new['univentionSharePath'][0]
                    ],
                                            stdout=subprocess.PIPE,
                                            close_fds=True)
                    _, stderr = proc.communicate()
                    if stderr:
                        univention.debug.debug(
                            univention.debug.LISTENER, univention.debug.ERROR,
                            "could not set nt acl for dir %s (%s)" %
                            (new['univentionSharePath'][0], stderr))
        finally:
            listener.unsetuid()
コード例 #17
0
# /usr/share/common-licenses/AGPL-3; if not, see
# <http://www.gnu.org/licenses/>.

from __future__ import absolute_import
import listener
import os
import re
import univention.debug
import univention.lib.listenerSharePath
import cPickle
from univention.config_registry.interfaces import Interfaces

hostname = listener.baseConfig['hostname']
domainname = listener.baseConfig['domainname']
interfaces = Interfaces(listener.configRegistry)
ip = interfaces.get_default_ip_address().ip

name = 'nfs-shares'
description = 'Create configuration for NFS shares'
filter = '(&(objectClass=univentionShare)(|(univentionShareHost=%s.%s)(univentionShareHost=%s)))' % (hostname, domainname, ip)
modrdn = '1'

__exports = '/etc/exports'
__comment_pattern = re.compile('^"*/.*#[ \t]*LDAP:[ \t]*(.*)')

tmpFile = '/var/cache/univention-directory-listener/nfs-shares.oldObject'


def handler(dn, new, old, command):
	# create tmp dir
	tmpDir = os.path.dirname(tmpFile)