1
0
mirror of https://github.com/altlinux/gpupdate.git synced 2025-03-21 18:50:38 +03:00

environment variables applier

This commit is contained in:
Rustem Bapin 2020-09-29 16:54:46 +04:00
parent bb54d3e01e
commit 590fd8c464
6 changed files with 264 additions and 5 deletions

View File

@ -0,0 +1,104 @@
#
# 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/>.
from os.path import isfile
from util.logging import slogm
import logging
from gpt.envvars import (
FileAction
, action_letter2enum
)
from util.windows import expand_windows_var
from util.util import (
get_homedir,
homedir_exists
)
class Envvar:
def __init__(self, envvars, username=''):
self.username = username
self.envvars = envvars
if self.username == 'root':
self.envvar_file_path = '/etc/gpupdate/environment'
else:
self.envvar_file_path = get_homedir(self.username) + '/.gpupdate_environment'
def _open_envvar_file(self):
fd = None
if isfile(self.envvar_file_path):
fd = open(self.envvar_file_path, 'r+')
else:
fd = open(self.envvar_file_path, 'w')
fd.close()
fd = open(self.envvar_file_path, 'r+')
return fd
def _create_action(self, create_dict, envvar_file):
lines_old = envvar_file.readlines()
lines_new = list()
for name in create_dict:
exist = False
for line in lines_old:
if line.startswith(name + '='):
exist = True
break
if not exist:
lines_new.append(name + '=' + create_dict[name] + '\n')
if len(lines_new) > 0:
envvar_file.writelines(lines_new)
def _delete_action(self, delete_dict, envvar_file):
lines = envvar_file.readlines()
deleted = False
for name in delete_dict:
for line in lines:
if line.startswith(name + '='):
lines.remove(line)
deleted = True
break
if deleted:
envvar_file.writelines(lines)
def act(self):
envvar_file = self._open_envvar_file()
ev_create = dict()
ev_update = dict()
ev_delete = dict()
ev_replace = dict()
for envvar_object in self.envvars:
action = action_letter2enum(envvar_object.action)
name = envvar_object.name
value = expand_windows_var(envvar_object.value, self.username).replace('\\', '/')
if action == FileAction.CREATE:
ev_create[name]=value
if action == FileAction.UPDATE:
ev_update[name]=value
if action == FileAction.DELETE:
ev_delete[name]=value
if action == FileAction.REPLACE:
ev_replace[name]=value
self._create_action(ev_create, envvar_file)
#self._update_action(ev_update, envvar_file)
self._delete_action(ev_delete, envvar_file)
#self._replace_action(ev_replace, envvar_file)
envvar_file.close()

View File

@ -0,0 +1,69 @@
#
# 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/>.
from .applier_frontend import (
applier_frontend
, check_enabled
)
from .appliers.envvar import Envvar
from util.logging import slogm
import logging
class envvar_applier(applier_frontend):
__module_name = 'EnvvarsApplier'
__module_experimental = False
__module_enabled = True
def __init__(self, storage, sid):
self.storage = storage
self.sid = sid
self.envvars = self.storage.get_envvars(self.sid)
#self.__module_enabled = check_enabled(self.storage, self.__module_name, self.__module_enabled)
def apply(self):
if self.__module_enabled:
logging.debug(slogm('Running Envvar applier for machine'))
ev = Envvar(self.envvars, 'root')
ev.act()
else:
logging.debug(slogm('Envvar applier for machine will not be started'))
class envvar_applier_user(applier_frontend):
__module_name = 'EnvvarsApplierUser'
__module_experimental = False
__module_enabled = True
def __init__(self, storage, sid, username):
self.storage = storage
self.sid = sid
self.username = username
self.envvars = self.storage.get_envvars(self.sid)
#self.__module_enabled = check_enabled(self.storage, self.__module_name, self.__module_experimental)
def admin_context_apply(self):
pass
def user_context_apply(self):
if self.__module_enabled:
logging.debug(slogm('Running Envvar applier for user in user context'))
ev = Envvar(self.envvars, self.username)
ev.act()
else:
logging.debug(slogm('Envvar applier for user in user context will not be started'))

View File

@ -46,6 +46,10 @@ from .folder_applier import (
)
from .cifs_applier import cifs_applier_user
from .ntp_applier import ntp_applier
from .envvar_applier import (
envvar_applier
, envvar_applier_user
)
from util.windows import get_sid
from util.users import (
is_root,
@ -105,6 +109,7 @@ class frontend_manager:
self.machine_appliers['folders'] = folder_applier(self.storage, self.sid)
self.machine_appliers['package'] = package_applier(self.storage)
self.machine_appliers['ntp'] = ntp_applier(self.storage)
self.machine_appliers['envvar'] = envvar_applier(self.storage, self.sid)
# User appliers are expected to work with user-writable
# files and settings, mostly in $HOME.
@ -121,6 +126,7 @@ class frontend_manager:
log('E25', logdata)
self.user_appliers['package'] = package_applier_user(self.storage, self.sid, self.username)
self.user_appliers['polkit'] = polkit_applier_user(self.storage, self.sid, self.username)
self.user_appliers['envvar'] = envvar_applier_user(self.storage, self.sid, self.username)
def machine_apply(self):
'''

View File

@ -18,21 +18,48 @@
from util.xml import get_xml_root
from enum import Enum
class FileAction(Enum):
CREATE = 'C'
REPLACE = 'R'
UPDATE = 'U'
DELETE = 'D'
def action_letter2enum(letter):
if letter in ['C', 'R', 'U', 'D']:
if letter == 'C': return FileAction.CREATE
if letter == 'R': return FileAction.REPLACE
if letter == 'U': return FileAction.UPDATE
if letter == 'D': return FileAction.DELETE
return FileAction.CREATE
def read_envvars(envvars_file):
variables = list()
for var in get_xml_root(envvars_file):
var_obj = envvar()
props = var.find('Properties')
name = props.get('name')
value = props.get('value')
var_obj = envvar(name, value)
var_obj.set_action(action_letter2enum(props.get('action', default='C')))
variables.append(var_obj)
return variables
def merge_envvars(storage, sid, envvars_objects, policy_name):
def merge_envvars(storage, sid, envvar_objects, policy_name):
for envvar in envvar_objects:
pass
storage.add_envvar(sid, envvar, policy_name)
class envvar:
def __init__(self):
pass
def __init__(self, name, value):
self.name = name
self.value = value
self.action = FileAction.CREATE
def set_action(self, action):
self.action = action

View File

@ -148,3 +148,25 @@ class folder_entry(object):
return fields
class envvar_entry(object):
'''
Object mapping representing environment variables
'''
def __init__(self, sid, evobj, policy_name):
self.sid = sid
self.policy_name = policy_name
self.name = evobj.name
self.value = evobj.value
self.action = evobj.action.value
def update_fields(self):
'''
Return list of fields to update
'''
fields = dict()
fields['policy_name'] = self.policy_name
fields['action'] = self.action
fields['value'] = self.value
return fields

View File

@ -43,6 +43,7 @@ from .record_types import (
, printer_entry
, drive_entry
, folder_entry
, envvar_entry
)
class sqlite_registry(registry):
@ -126,6 +127,17 @@ class sqlite_registry(registry):
, Column('delete_files', String)
, UniqueConstraint('sid', 'path')
)
self.__envvars = Table(
'Envvars'
, self.__metadata
, Column('id', Integer, primary_key=True)
, Column('sid', String)
, Column('name', String)
, Column('policy_name', String)
, Column('action', String)
, Column('value', String)
, UniqueConstraint('sid', 'name')
)
self.__metadata.create_all(self.db_cnt)
Session = sessionmaker(bind=self.db_cnt)
self.db_session = Session()
@ -137,6 +149,7 @@ class sqlite_registry(registry):
mapper(printer_entry, self.__printers)
mapper(drive_entry, self.__drives)
mapper(folder_entry, self.__folders)
mapper(envvar_entry, self.__envvars)
except:
pass
#logging.error('Error creating mapper')
@ -294,6 +307,21 @@ class sqlite_registry(registry):
.update(fld_entry.update_fields()))
self.db_session.commit()
def add_envvar(self, sid, evobj, policy_name):
ev_entry = envvar_entry(sid, evobj, policy_name)
logdata = dict()
logdata['envvar'] = ev_entry.name
logdata['sid'] = sid
log('D420', logdata)
try:
self._add(ev_entry)
except Exception as exc:
(self
._filter_sid_obj(envvar_entry, sid)
.filter(envvar_entry.name == ev_entry.name)
.update(ev_entry.update_fields()))
self.db_session.commit()
def _filter_sid_obj(self, row_object, sid):
res = (self
.db_session
@ -321,6 +349,9 @@ class sqlite_registry(registry):
def get_folders(self, sid):
return self._filter_sid_list(folder_entry, sid)
def get_envvars(self, sid):
return self._filter_sid_list(envvar_entry, sid)
def get_hkcu_entry(self, sid, hive_key):
res = (self
.db_session