Ejemplo n.º 1
0
    async def groupmap_add(self, group):
        """
        Map Unix group to NT group. This is required for group members to be
        able to access the SMB share. Name collisions with well-known and
        builtin groups must be avoided. Mapping groups with the same
        names as users should also be avoided.
        """
        passdb_backend = await self.middleware.call('smb.getparm',
                                                    'passdb backend', 'global')
        if passdb_backend == 'ldapsam':
            return

        if group in SMBBuiltin.unix_groups():
            return await self.add_builtin_group(group)

        disallowed_list = ['USERS', 'ADMINISTRATORS', 'GUESTS']
        existing_groupmap = await self.groupmap_list()

        for g in existing_groupmap.values():
            disallowed_list.append(g['ntgroup'].upper())

        if group.upper() in disallowed_list:
            self.logger.debug('Setting group map for %s is not permitted',
                              group)
            return False
        gm_add = await run([
            SMBCmd.NET.value, '-d', '0', 'groupmap', 'add', 'type=local',
            f'unixgroup={group}', f'ntgroup={group}'
        ],
                           check=False)
        if gm_add.returncode != 0:
            raise CallError(
                f'Failed to generate groupmap for [{group}]: ({gm_add.stderr.decode()})'
            )
Ejemplo n.º 2
0
    async def synchronize_group_mappings(self, job):
        """
        This method does the following:
        1) prepares payload for a batch groupmap operation. These are added to two arrays:
           "to_add" and "to_del". Missing entries are added, invalid entries are deleted.
        2) we synchronize S-1-5-32-544, S-1-5-32-545, and S-1-5-32-546 separately
        3) we add any required group mappings for the SIDs in (2) above.
        4) we flush various caches if required.
        """
        payload = {}
        to_add = []
        to_del = []

        if await self.middleware.call('ldap.get_state') != "DISABLED":
            return

        ha_mode = await self.middleware.call('smb.get_smb_ha_mode')
        if ha_mode == 'CLUSTERED':
            await self.middleware.call('smb.set_cluster_lock_wait')

        groupmap = await self.groupmap_list()
        must_remove_cache = False

        groups = await self.middleware.call('group.query', [('builtin', '=', False), ('smb', '=', True)])
        g_dict = {x["gid"]: x for x in groups}
        g_dict[545] = await self.middleware.call('group.query', [('gid', '=', 545)], {'get': True})

        intersect = set(g_dict.keys()).intersection(set(groupmap["local"].keys()))

        set_to_add = set(g_dict.keys()) - set(groupmap["local"].keys())
        set_to_del = set(groupmap["local"].keys()) - set(g_dict.keys())
        set_to_mod = set([x for x in intersect if groupmap['local'][x]['nt_name'] != g_dict[x]['group']])

        to_add = [{
            "gid": g_dict[x]["gid"],
            "nt_name": g_dict[x]["group"],
            "group_type_str": "local"
        } for x in set_to_add]

        to_mod = [{
            "gid": g_dict[x]["gid"],
            "nt_name": g_dict[x]["group"],
            "sid": groupmap["local"][x]["sid"],
            "group_type_str": "local"
        } for x in set_to_mod]

        to_del = [{
            "sid": groupmap["local"][x]["sid"]
        } for x in set_to_del]

        for sid in groupmap['invalid']:
            to_del.append({"sid": sid})

        for gid in (544, 546):
            if not groupmap["local_builtins"].get(gid):
                builtin = SMBBuiltin.by_rid(gid)
                rid = 512 + (gid - 544)
                sid = f'{groupmap["localsid"]}-{rid}'
                to_add.append({
                    "gid": gid,
                    "nt_name": f"local_{builtin.name.lower()}",
                    "group_type_str": "local",
                    "sid": sid,
                })

        if to_add:
            payload["ADD"] = [{"groupmap": to_add}]

        if to_mod:
            payload["MOD"] = [{"groupmap": to_mod}]

        if to_del:
            payload["DEL"] = [{"groupmap": to_del}]

        await self.middleware.call('smb.fixsid')
        must_remove_cache = await self.sync_builtins(groupmap['builtins'])
        await self.batch_groupmap(payload)
        await self.sync_foreign_groups()

        if ha_mode == "CLUSTERED":
            await self.middleware.call("clustercache.pop", "PASSDB_LOCK")

        if must_remove_cache:
            if os.path.exists(f'{SMBPath.STATEDIR.platform()}/winbindd_cache.tdb'):
                os.remove(f'{SMBPath.STATEDIR.platform()}/winbindd_cache.tdb')
            flush = await run([SMBCmd.NET.value, 'cache', 'flush'], check=False)
            if flush.returncode != 0:
                self.logger.debug('Attempt to flush cache failed: %s', flush.stderr.decode().strip())