2020-03-27 21:30:55 +04:00
#! /usr/bin/env python3
2020-03-23 16:07:18 +04:00
#
# GPOA - GPO Applier for Linux
#
# Copyright (C) 2019-2020 BaseALT Ltd.
#
# 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/>.
2020-03-27 21:30:55 +04:00
import os
import sys
import argparse
2020-04-16 04:16:30 +04:00
import subprocess
2020-04-16 06:31:45 +04:00
import re
2020-08-20 15:09:40 +04:00
from util.util import (
runcmd
, get_backends
, get_default_policy_name
, get_policy_entries
, get_policy_variants
)
from util.config import GPConfig
class Runner:
__control_path = '/usr/sbin/control'
__systemctl_path = '/bin/systemctl'
__etc_policy_dir = '/etc/local-policy'
__usr_policy_dir = '/usr/share/local-policy'
def __init__(self):
self.etc_policies = get_policy_entries(self.__etc_policy_dir)
self.usr_policies = get_policy_entries(self.__usr_policy_dir)
self.arguments = parse_arguments()
2020-08-13 08:05:46 +04:00
2020-03-27 21:30:55 +04:00
def parse_arguments():
'''
Parse CLI arguments.
'''
parser = argparse.ArgumentParser(prog='gpupdate-setup')
subparsers = parser.add_subparsers(dest='action',
metavar='action',
2020-04-16 04:15:13 +04:00
help='Group Policy management actions (default action is status)')
2020-03-27 21:30:55 +04:00
parser_list = subparsers.add_parser('list',
help='List avalable types of local policy')
2020-08-13 08:05:46 +04:00
parser_list = subparsers.add_parser('list-backends',
help='Show list of available backends')
2020-03-27 21:30:55 +04:00
parser_status = subparsers.add_parser('status',
help='Show current Group Policy status')
2020-04-16 06:29:41 +04:00
parser_enable = subparsers.add_parser('enable',
help='Enable Group Policy subsystem')
2020-08-19 19:38:46 +04:00
2020-04-16 06:29:41 +04:00
parser_disable = subparsers.add_parser('disable',
help='Disable Group Policy subsystem')
2020-08-19 19:38:46 +04:00
2020-03-27 21:30:55 +04:00
parser_write = subparsers.add_parser('write',
2020-04-16 06:29:41 +04:00
help='Operate on Group Policies (enable or disable)')
2020-04-23 01:19:15 +04:00
parser_default = subparsers.add_parser('default-policy',
help='Show name of default policy')
2020-04-14 16:08:06 +04:00
parser_active = subparsers.add_parser('active-policy',
help='Show name of policy enabled')
2020-03-27 21:30:55 +04:00
parser_write.add_argument('status',
choices=['enable', 'disable'],
help='Enable or disable Group Policies')
parser_write.add_argument('localpolicy',
2020-04-16 06:29:41 +04:00
default=None,
nargs='?',
help='Name of local policy to enable')
2020-08-19 19:38:46 +04:00
parser_write.add_argument('backend',
default='samba',
type=str,
nargs='?',
const='backend',
choices=['local', 'samba'],
help='Backend (source of settings) name')
2020-04-16 06:29:41 +04:00
parser_enable.add_argument('localpolicy',
default=None,
2020-03-27 21:30:55 +04:00
nargs='?',
help='Name of local policy to enable')
2020-08-19 19:38:46 +04:00
parser_enable.add_argument('backend',
default='samba',
type=str,
nargs='?',
const='backend',
choices=['local', 'samba'],
help='Backend (source of settings) name')
2020-03-27 21:30:55 +04:00
return parser.parse_args()
2020-04-16 06:31:45 +04:00
def validate_policy_name(policy_name):
return policy_name in [os.path.basename(d) for d in get_policy_variants()]
2020-08-20 18:28:05 +04:00
def is_unit_enabled(unit_name, unit_global=False):
2020-08-20 15:00:39 +04:00
'''
Check that designated systemd unit is enabled
'''
2020-08-18 16:12:45 +04:00
command = ['/bin/systemctl', 'is-enabled', unit_name]
2020-08-20 18:28:05 +04:00
if unit_global:
command = ['/bin/systemctl', '--global', 'is-enabled', unit_name]
2020-08-18 16:12:45 +04:00
value = runcmd(command)
# If first line of stdout is equal to "enabled" and return code
# is zero then unit is considered enabled.
2020-08-20 15:09:40 +04:00
rc = value[0]
result = []
try:
result = value[1][0]
except IndexError as exc:
return False
if result == 'enabled' and rc == 0:
2020-08-18 16:12:45 +04:00
return True
return False
2020-03-27 21:30:55 +04:00
def get_status():
2020-08-20 15:00:39 +04:00
'''
Check that gpupdate.service and gpupdate-user.service are enabled.
'''
2020-08-18 16:12:45 +04:00
is_gpupdate = is_unit_enabled('gpupdate.service')
is_gpupdate_user = is_unit_enabled('gpupdate-user.service')
2020-03-27 21:30:55 +04:00
2020-08-18 16:12:45 +04:00
if is_gpupdate and is_gpupdate_user:
return True
return False
2020-03-27 21:30:55 +04:00
2020-04-23 01:19:15 +04:00
def get_active_policy_name():
2020-08-20 15:09:40 +04:00
'''
Show the name of an active Local Policy template
'''
config = GPConfig()
return config.get_local_policy_template()
2020-03-27 21:30:55 +04:00
2020-08-17 19:19:22 +04:00
def rollback_on_error(command_name):
2020-08-20 15:09:40 +04:00
'''
Disable group policy services in case command returns error code
'''
2020-08-17 19:19:22 +04:00
if 0 != runcmd(command_name)[0]:
disable_gp()
return False
return True
2020-03-27 21:30:55 +04:00
def disable_gp():
2020-08-20 15:09:40 +04:00
'''
Consistently disable group policy services
'''
2020-08-17 18:47:25 +04:00
cmd_set_global_policy = ['/usr/sbin/control', 'system-policy', 'global']
cmd_set_local_policy = ['/usr/sbin/control', 'system-policy', 'local']
cmd_disable_gpupdate_service = ['/bin/systemctl', 'disable', 'gpupdate.service']
cmd_disable_gpupdate_user_service = ['/bin/systemctl', '--global', 'disable', 'gpupdate-user.service']
2020-08-20 15:09:40 +04:00
cmd_control_system_auth = ['/usr/sbin/control', 'system-auth']
config = GPConfig()
auth_result = 'local'
try:
auth_result = runcmd(cmd_control_system_auth)[1][0]
except Exception as exc:
print(str(exc))
2020-08-17 18:47:25 +04:00
2020-08-20 15:09:40 +04:00
if auth_result != 'local':
2020-08-17 18:47:25 +04:00
runcmd(cmd_set_global_policy)
2020-04-20 02:54:52 +04:00
else:
2020-08-17 18:47:25 +04:00
runcmd(cmd_set_local_policy)
runcmd(cmd_disable_gpupdate_service)
runcmd(cmd_disable_gpupdate_user_service)
2020-03-27 21:30:55 +04:00
2020-08-20 15:09:40 +04:00
def enable_gp(policy_name, backend_type):
'''
Consistently enable group policy services
'''
2020-03-27 21:30:55 +04:00
policy_dir = '/usr/share/local-policy'
etc_policy_dir = '/etc/local-policy'
2020-08-17 18:47:25 +04:00
cmd_set_gpupdate_policy = ['/usr/sbin/control', 'system-policy', 'gpupdate']
cmd_gpoa_nodomain = ['/usr/sbin/gpoa', '--nodomain', '--loglevel 5']
cmd_enable_gpupdate_service = ['/bin/systemctl', 'enable', 'gpupdate.service']
cmd_enable_gpupdate_user_service = ['/bin/systemctl', '--global', 'enable', 'gpupdate-user.service']
2020-08-20 15:09:40 +04:00
config = GPConfig()
2020-04-16 15:56:08 +04:00
target_policy_name = get_default_policy_name()
2020-03-27 21:30:55 +04:00
if policy_name:
2020-04-16 06:31:45 +04:00
if validate_policy_name(policy_name):
target_policy_name = policy_name
2020-04-14 16:08:06 +04:00
2020-04-16 06:31:45 +04:00
print (target_policy_name)
default_policy_name = os.path.join(policy_dir, target_policy_name)
2020-03-27 21:30:55 +04:00
if not os.path.isdir(etc_policy_dir):
os.makedirs(etc_policy_dir)
2020-08-20 15:09:40 +04:00
config.set_local_policy_template(default_policy_name)
2020-03-27 21:30:55 +04:00
# Enable oddjobd_gpupdate in PAM config
2020-08-20 15:09:40 +04:00
if not rollback_on_error(cmd_set_gpupdate_policy):
return
2020-03-27 21:30:55 +04:00
# Bootstrap the Group Policy engine
2020-08-20 15:09:40 +04:00
if not rollback_on_error(cmd_gpoa_nodomain):
return
2020-08-17 18:47:25 +04:00
# Enable gpupdate.service
2020-08-20 15:09:40 +04:00
if not rollback_on_error(cmd_enable_gpupdate_service):
return
2020-08-18 16:12:45 +04:00
if not is_unit_enabled('gpupdate.service'):
disable_gp()
2020-08-20 15:09:40 +04:00
return
2020-03-27 21:30:55 +04:00
# Enable gpupdate-setup.service for all users
2020-08-20 15:09:40 +04:00
if not rollback_on_error(cmd_enable_gpupdate_user_service):
return
2020-08-18 16:12:45 +04:00
if not is_unit_enabled('gpupdate-user.service'):
disable_gp()
2020-08-20 15:09:40 +04:00
return
2020-03-27 21:30:55 +04:00
2020-08-17 19:35:45 +04:00
def act_list():
2020-08-20 15:00:39 +04:00
'''
Show list of available templates of Local Policy
'''
2020-08-17 19:35:45 +04:00
for entry in get_policy_variants():
print(entry.rpartition('/')[2])
def act_list_backends():
2020-08-20 15:00:39 +04:00
'''
List backends supported by GPOA
'''
2020-08-17 19:35:45 +04:00
backends = get_backends()
for backend in backends:
print(backend)
def act_status():
2020-08-20 15:00:39 +04:00
'''
Check that group policy services are enabled
'''
2020-08-17 19:35:45 +04:00
if get_status():
print('enabled')
else:
print('disabled')
2020-03-27 21:30:55 +04:00
2020-08-20 15:09:40 +04:00
def act_write(localpolicy, backend):
'''
Enable or disable group policy services
'''
2020-08-17 19:35:45 +04:00
if arguments.status == 'enable' or arguments.status == '#t':
2020-08-20 15:09:40 +04:00
enable_gp(localpolicy, backend)
2020-08-17 19:35:45 +04:00
if arguments.status == 'disable' or arguments.status == '#f':
2020-04-16 06:29:41 +04:00
disable_gp()
2020-08-20 15:09:40 +04:00
def act_enable(localpolicy, backend):
'''
Enable group policy services
'''
enable_gp(localpolicy, backend)
2020-08-17 19:35:45 +04:00
def act_active_policy():
2020-08-20 15:00:39 +04:00
'''
Print active Local Policy template name to stdout
'''
2020-08-17 19:35:45 +04:00
print(get_active_policy_name())
2020-04-23 01:19:15 +04:00
2020-08-17 19:35:45 +04:00
def act_default_policy():
2020-08-20 15:00:39 +04:00
'''
Print default Local Policy template name to stdout
'''
2020-08-17 19:35:45 +04:00
print(get_default_policy_name())
def main():
arguments = parse_arguments()
action = dict()
action['list'] = act_list
action['list-backends'] = act_list_backends
action['status'] = act_status
action['write'] = act_write
action['enable'] = act_enable
action['disable'] = disable_gp
action['active-policy'] = act_active_policy
action['default-policy'] = act_default_policy
if arguments.action == None:
action['status']()
2020-08-20 15:09:40 +04:00
elif arguments.action == 'enable':
action[arguments.action](arguments.localpolicy, arguments.backend)
elif arguments.action == 'write':
action[arguments.action](arguments.localpolicy)
2020-08-17 19:35:45 +04:00
else:
action[arguments.action]()
2020-04-14 16:08:06 +04:00
2020-03-27 21:30:55 +04:00
if __name__ == '__main__':
main()
2020-03-23 16:07:18 +04:00