mirror of
https://github.com/altlinux/gpupdate.git
synced 2025-01-05 05:17:52 +03:00
375 lines
12 KiB
Python
Executable File
375 lines
12 KiB
Python
Executable File
#! /usr/bin/env python3
|
|
#
|
|
# GPOA - GPO Applier for Linux
|
|
#
|
|
# Copyright (C) 2019-2024 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/>.
|
|
|
|
|
|
import os
|
|
import argparse
|
|
|
|
from util.util import (
|
|
runcmd
|
|
, get_backends
|
|
, get_default_policy_name
|
|
, get_policy_entries
|
|
, get_policy_variants
|
|
)
|
|
from util.config import GPConfig
|
|
from util.paths import get_custom_policy_dir
|
|
|
|
|
|
class Runner:
|
|
__control_path = '/usr/sbin/control'
|
|
__systemctl_path = '/bin/systemctl'
|
|
|
|
def __init__(self):
|
|
self.arguments = parse_arguments()
|
|
|
|
def parse_arguments():
|
|
'''
|
|
Parse CLI arguments.
|
|
'''
|
|
parser = argparse.ArgumentParser(prog='gpupdate-setup')
|
|
subparsers = parser.add_subparsers(dest='action',
|
|
metavar='action',
|
|
help='Group Policy management actions (default action is status)')
|
|
|
|
parser_list = subparsers.add_parser('list',
|
|
help='List avalable types of local policy')
|
|
parser_list = subparsers.add_parser('list-backends',
|
|
help='Show list of available backends')
|
|
parser_status = subparsers.add_parser('status',
|
|
help='Show current Group Policy status')
|
|
parser_enable = subparsers.add_parser('enable',
|
|
help='Enable Group Policy subsystem')
|
|
|
|
parser_disable = subparsers.add_parser('disable',
|
|
help='Disable Group Policy subsystem')
|
|
parser_update = subparsers.add_parser('update',
|
|
help='Update state')
|
|
parser_write = subparsers.add_parser('write',
|
|
help='Operate on Group Policies (enable or disable)')
|
|
parser_set_backend = subparsers.add_parser('set-backend',
|
|
help='Set or change currently active backend')
|
|
parser_default = subparsers.add_parser('default-policy',
|
|
help='Show name of default policy')
|
|
parser_active = subparsers.add_parser('active-policy',
|
|
help='Show name of policy enabled')
|
|
parser_active_backend = subparsers.add_parser('active-backend',
|
|
help='Show currently configured backend')
|
|
|
|
parser_set_backend.add_argument('backend',
|
|
default='samba',
|
|
type=str,
|
|
nargs='?',
|
|
const='backend',
|
|
choices=['local', 'samba'],
|
|
help='Backend (source of settings) name')
|
|
|
|
parser_write.add_argument('status',
|
|
choices=['enable', 'disable'],
|
|
help='Enable or disable Group Policies')
|
|
parser_write.add_argument('localpolicy',
|
|
default=None,
|
|
nargs='?',
|
|
help='Name of local policy to enable')
|
|
parser_write.add_argument('backend',
|
|
default='samba',
|
|
type=str,
|
|
nargs='?',
|
|
const='backend',
|
|
choices=['local', 'samba'],
|
|
help='Backend (source of settings) name')
|
|
|
|
parser_enable.add_argument('--local-policy',
|
|
default=None,
|
|
help='Name of local policy to enable')
|
|
parser_enable.add_argument('--backend',
|
|
default='samba',
|
|
type=str,
|
|
choices=['local', 'samba'],
|
|
help='Backend (source of settings) name')
|
|
|
|
parser_update.add_argument('--local-policy',
|
|
default=None,
|
|
help='Name of local policy to enable')
|
|
parser_update.add_argument('--backend',
|
|
default='samba',
|
|
type=str,
|
|
choices=['local', 'samba'],
|
|
help='Backend (source of settings) name')
|
|
|
|
|
|
return parser.parse_args()
|
|
|
|
def validate_policy_name(policy_name):
|
|
return policy_name in [os.path.basename(d) for d in get_policy_variants()]
|
|
|
|
def is_unit_enabled(unit_name, unit_global=False):
|
|
'''
|
|
Check that designated systemd unit is enabled
|
|
'''
|
|
command = ['/bin/systemctl', 'is-enabled', unit_name]
|
|
if unit_global:
|
|
command = ['/bin/systemctl', '--global', 'is-enabled', unit_name]
|
|
value = runcmd(command)
|
|
|
|
# If first line of stdout is equal to "enabled" and return code
|
|
# is zero then unit is considered enabled.
|
|
rc = value[0]
|
|
result = []
|
|
try:
|
|
result = value[1].replace('\n', '')
|
|
except IndexError as exc:
|
|
return False
|
|
|
|
if result == 'enabled' and rc == 0:
|
|
return True
|
|
|
|
return False
|
|
|
|
def get_status():
|
|
'''
|
|
Check that gpupdate.timer and gpupdate-user.timer are enabled.
|
|
'''
|
|
is_gpupdate = is_unit_enabled('gpupdate.timer')
|
|
is_gpupdate_user = is_unit_enabled('gpupdate-user.timer', unit_global=True)
|
|
|
|
if is_gpupdate and is_gpupdate_user:
|
|
return True
|
|
|
|
return False
|
|
|
|
def get_active_policy_name():
|
|
'''
|
|
Show the name of an active Local Policy template
|
|
'''
|
|
config = GPConfig()
|
|
return os.path.basename(config.get_local_policy_template())
|
|
|
|
def get_active_backend():
|
|
config = GPConfig()
|
|
return config.get_backend()
|
|
|
|
def rollback_on_error(command_name):
|
|
'''
|
|
Disable group policy services in case command returns error code
|
|
'''
|
|
if 0 != runcmd(command_name)[0]:
|
|
disable_gp()
|
|
return False
|
|
return True
|
|
|
|
def disable_gp():
|
|
'''
|
|
Consistently disable group policy services
|
|
'''
|
|
cmd_set_global_policy = ['/usr/sbin/control', 'system-policy', 'remote']
|
|
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']
|
|
cmd_disable_gpupdate_timer = ['/bin/systemctl', 'disable', 'gpupdate.timer']
|
|
cmd_disable_gpupdate_user_timer = ['/bin/systemctl', '--global', 'disable', 'gpupdate-user.timer']
|
|
cmd_control_system_auth = ['/usr/sbin/control', 'system-auth']
|
|
cmd_disable_gpupdate_scripts_service = ['/bin/systemctl', 'disable', 'gpupdate-scripts-run.service']
|
|
cmd_disable_gpupdate_scripts_user_service = ['/bin/systemctl', '--global', 'disable', 'gpupdate-scripts-run-user.service']
|
|
|
|
config = GPConfig()
|
|
|
|
auth_result = 'local'
|
|
try:
|
|
auth_result = runcmd(cmd_control_system_auth)[1][0]
|
|
except Exception as exc:
|
|
print(str(exc))
|
|
|
|
if auth_result != 'local':
|
|
runcmd(cmd_set_global_policy)
|
|
else:
|
|
runcmd(cmd_set_local_policy)
|
|
runcmd(cmd_disable_gpupdate_service)
|
|
runcmd(cmd_disable_gpupdate_user_service)
|
|
runcmd(cmd_disable_gpupdate_timer)
|
|
runcmd(cmd_disable_gpupdate_user_timer)
|
|
runcmd(cmd_disable_gpupdate_scripts_service)
|
|
runcmd(cmd_disable_gpupdate_scripts_user_service)
|
|
config.set_local_policy_template()
|
|
config.set_backend()
|
|
|
|
def enable_gp(policy_name, backend_type):
|
|
'''
|
|
Consistently enable group policy services
|
|
'''
|
|
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', 'disable', 'gpupdate-user.service']
|
|
cmd_enable_gpupdate_timer = ['/bin/systemctl', 'enable', 'gpupdate.timer']
|
|
cmd_enable_gpupdate_user_timer = ['/bin/systemctl', '--global', 'enable', 'gpupdate-user.timer']
|
|
cmd_enable_gpupdate_scripts_service = ['/bin/systemctl', 'enable', 'gpupdate-scripts-run.service']
|
|
cmd_enable_gpupdate_user_scripts_service = ['/bin/systemctl', '--global', 'enable', 'gpupdate-scripts-run-user.service']
|
|
|
|
config = GPConfig()
|
|
|
|
custom_policy_dir = get_custom_policy_dir()
|
|
if not os.path.isdir(custom_policy_dir):
|
|
os.makedirs(custom_policy_dir)
|
|
|
|
target_policy_name = get_default_policy_name()
|
|
if policy_name:
|
|
if validate_policy_name(policy_name):
|
|
target_policy_name = policy_name
|
|
print (target_policy_name)
|
|
|
|
config.set_local_policy_template(target_policy_name)
|
|
config.set_backend(backend_type)
|
|
|
|
# Enable oddjobd_gpupdate in PAM config
|
|
if not rollback_on_error(cmd_set_gpupdate_policy):
|
|
return
|
|
# Bootstrap the Group Policy engine
|
|
if not rollback_on_error(cmd_gpoa_nodomain):
|
|
return
|
|
# Enable gpupdate.service
|
|
if not rollback_on_error(cmd_enable_gpupdate_service):
|
|
return
|
|
if not is_unit_enabled('gpupdate.service'):
|
|
disable_gp()
|
|
return
|
|
# Enable gpupdate-setup.service for all users
|
|
if not rollback_on_error(cmd_enable_gpupdate_user_service):
|
|
return
|
|
# Enable gpupdate-scripts-run.service
|
|
if not rollback_on_error(cmd_enable_gpupdate_scripts_service):
|
|
return
|
|
if not is_unit_enabled('gpupdate-scripts-run.service'):
|
|
disable_gp()
|
|
return
|
|
# Enable gpupdate-scripts-run-user.service for all users
|
|
if not rollback_on_error(cmd_enable_gpupdate_user_scripts_service):
|
|
return
|
|
if not is_unit_enabled('gpupdate-scripts-run-user.service', unit_global=True):
|
|
disable_gp()
|
|
return
|
|
|
|
# Enable gpupdate.timer
|
|
if not rollback_on_error(cmd_enable_gpupdate_timer):
|
|
return
|
|
if not is_unit_enabled('gpupdate.timer'):
|
|
disable_gp()
|
|
return
|
|
# Enable gpupdate-setup.timer for all users
|
|
if not rollback_on_error(cmd_enable_gpupdate_user_timer):
|
|
return
|
|
if not is_unit_enabled('gpupdate-user.timer', unit_global=True):
|
|
disable_gp()
|
|
return
|
|
|
|
def act_list():
|
|
'''
|
|
Show list of available templates of Local Policy
|
|
'''
|
|
for entry in get_policy_variants():
|
|
print(entry.rpartition('/')[2])
|
|
|
|
def act_list_backends():
|
|
'''
|
|
List backends supported by GPOA
|
|
'''
|
|
backends = get_backends()
|
|
for backend in backends:
|
|
print(backend)
|
|
|
|
def act_status():
|
|
'''
|
|
Check that group policy services are enabled
|
|
'''
|
|
if get_status():
|
|
print('enabled')
|
|
else:
|
|
print('disabled')
|
|
|
|
def act_set_backend(backend_name):
|
|
config = GPConfig()
|
|
config.set_backend(backend_name)
|
|
|
|
def act_write(status, localpolicy, backend):
|
|
'''
|
|
Enable or disable group policy services
|
|
'''
|
|
if status == 'enable' or status == '#t':
|
|
enable_gp(localpolicy, backend)
|
|
if status == 'disable' or status == '#f':
|
|
disable_gp()
|
|
|
|
def act_enable(localpolicy, backend):
|
|
'''
|
|
Enable group policy services
|
|
'''
|
|
enable_gp(localpolicy, backend)
|
|
|
|
def act_active_policy():
|
|
'''
|
|
Print active Local Policy template name to stdout
|
|
'''
|
|
print(get_active_policy_name())
|
|
|
|
def act_active_backend():
|
|
'''
|
|
Print currently configured backend.
|
|
'''
|
|
print(get_active_backend())
|
|
|
|
def act_default_policy():
|
|
'''
|
|
Print default Local Policy template name to stdout
|
|
'''
|
|
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['set-backend'] = act_set_backend
|
|
action['write'] = act_write
|
|
action['enable'] = act_enable
|
|
action['update'] = act_enable
|
|
action['disable'] = disable_gp
|
|
action['active-policy'] = act_active_policy
|
|
action['active-backend'] = act_active_backend
|
|
action['default-policy'] = act_default_policy
|
|
|
|
if arguments.action == None:
|
|
action['status']()
|
|
elif arguments.action == 'update':
|
|
if get_status():
|
|
action[arguments.action](arguments.local_policy, arguments.backend)
|
|
elif arguments.action == 'enable':
|
|
action[arguments.action](arguments.local_policy, arguments.backend)
|
|
elif arguments.action == 'write':
|
|
action[arguments.action](arguments.status, arguments.localpolicy, arguments.backend)
|
|
elif arguments.action == 'set-backend':
|
|
action[arguments.action](arguments.backend)
|
|
else:
|
|
action[arguments.action]()
|
|
|
|
if __name__ == '__main__':
|
|
main()
|
|
|