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

Merge pull request #99 from altlinux/logging_codes

Logging codes
This commit is contained in:
NIR 2020-07-30 17:12:22 +04:00 committed by GitHub
commit 09553a1c9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 376 additions and 174 deletions

View File

@ -16,11 +16,11 @@
# 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 logging
from util.windows import smbcreds
from .samba_backend import samba_backend
from .nodomain_backend import nodomain_backend
from util.logging import log
def backend_factory(dc, username, is_machine, no_domain = False):
'''
@ -36,17 +36,20 @@ def backend_factory(dc, username, is_machine, no_domain = False):
domain = sc.get_domain()
if domain:
logging.debug('Initialize Samba backend for domain: {}'.format(domain))
ldata = dict({'domain': domain})
log('D9', ldata)
try:
back = samba_backend(sc, username, domain, is_machine)
except Exception as exc:
logging.error('Unable to initialize Samba backend: {}'.format(exc))
logdata = dict({'error': str(exc)})
log('E7', logdata)
else:
logging.debug('Initialize local backend with no domain')
log('D8')
try:
back = nodomain_backend()
except Exception as exc:
logging.error('Unable to initialize no-domain backend: {}'.format(exc))
logdata = dict({'error': str(exc)})
log('E8', logdata)
return back

View File

@ -16,7 +16,6 @@
# 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 logging
import os
# Facility to determine GPTs for user
from samba.gpclass import check_safe_path, check_refresh_gpo_list
@ -30,7 +29,7 @@ from util.util import (
)
from util.windows import get_sid
import util.preg
from util.logging import slogm
from util.logging import log
class samba_backend(applier_backend):
@ -57,7 +56,8 @@ class samba_backend(applier_backend):
self.sambacreds = sambacreds
self.cache_dir = self.sambacreds.get_cache_dir()
logging.debug(slogm('Cache directory is: {}'.format(self.cache_dir)))
logdata = dict({'cachedir': self.cache_dir})
log('D7', logdata)
def retrieve_and_store(self):
'''
@ -86,19 +86,23 @@ class samba_backend(applier_backend):
# GPO named "Local Policy" has no entry by its nature so
# no reason to print warning.
if 'Local Policy' != gpo.name:
logging.warning(slogm('No SYSVOL entry assigned to GPO {}'.format(gpo.name)))
logdata = dict({'gponame': gpo.name})
log('W4', logdata)
return False
return True
def _get_gpts(self, username, sid):
gpts = list()
log('D45')
# util.windows.smbcreds
gpos = self.sambacreds.update_gpos(username)
log('D46')
for gpo in gpos:
if self._check_sysvol_present(gpo):
logging.debug(slogm('Found SYSVOL entry "{}" for GPO "{}"'.format(gpo.file_sys_path, gpo.display_name)))
path = check_safe_path(gpo.file_sys_path).upper()
logging.debug(slogm('Path: {}'.format(path)))
slogdata = dict({'sysvol_path': gpo.file_sys_path, 'gpo_name': gpo.display_name, 'gpo_path': path})
log('D30', slogdata)
gpt_abspath = os.path.join(self.cache_dir, 'gpo_cache', path)
obj = gpt(gpt_abspath, sid)
obj.set_name(gpo.display_name)

View File

@ -53,9 +53,8 @@ from util.users import (
username_match_uid,
with_privileges
)
from util.logging import slogm
from util.logging import log
import logging
def determine_username(username=None):
'''
@ -68,13 +67,15 @@ def determine_username(username=None):
# of process owner.
if not username:
name = get_process_user()
logging.debug(slogm('Username is not specified - will use username of current process'))
logdata = dict({'username': name})
log('D2', logdata)
if not username_match_uid(name):
if not is_root():
raise Exception('Current process UID does not match specified username')
logging.debug(slogm('Username for frontend is set to {}'.format(name)))
logdata = dict({'username': name})
log('D15', logdata)
return name
@ -91,45 +92,52 @@ class frontend_manager:
self.process_uname = get_process_user()
self.sid = get_sid(self.storage.get_info('domain'), self.username, is_machine)
self.machine_appliers = dict({
'control': control_applier(self.storage)
, 'polkit': polkit_applier(self.storage)
, 'systemd': systemd_applier(self.storage)
, 'firefox': firefox_applier(self.storage, self.sid, self.username)
, 'chromium': chromium_applier(self.storage, self.sid, self.username)
, 'shortcuts': shortcut_applier(self.storage)
, 'gsettings': gsettings_applier(self.storage)
, 'cups': cups_applier(self.storage)
, 'firewall': firewall_applier(self.storage)
, 'folders': folder_applier(self.storage, self.sid)
, 'package': package_applier(self.storage)
, 'ntp': ntp_applier(self.storage)
})
self.machine_appliers = dict()
self.machine_appliers['control'] = control_applier(self.storage)
self.machine_appliers['polkit'] = polkit_applier(self.storage)
self.machine_appliers['systemd'] = systemd_applier(self.storage)
self.machine_appliers['firefox'] = firefox_applier(self.storage, self.sid, self.username)
self.machine_appliers['chromium'] = chromium_applier(self.storage, self.sid, self.username)
self.machine_appliers['shortcuts'] = shortcut_applier(self.storage)
self.machine_appliers['gsettings'] = gsettings_applier(self.storage)
self.machine_appliers['cups'] = cups_applier(self.storage)
self.machine_appliers['firewall'] = firewall_applier(self.storage)
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)
# User appliers are expected to work with user-writable
# files and settings, mostly in $HOME.
self.user_appliers = dict({
'shortcuts': shortcut_applier_user(self.storage, self.sid, self.username)
, 'folders': folder_applier_user(self.storage, self.sid, self.username)
, 'gsettings': gsettings_applier_user(self.storage, self.sid, self.username)
, 'cifs': cifs_applier_user(self.storage, self.sid, self.username)
, 'package': package_applier_user(self.storage, self.sid, self.username)
, 'polkit': polkit_applier_user(self.storage, self.sid, self.username)
})
self.user_appliers = dict()
self.user_appliers['shortcuts'] = shortcut_applier_user(self.storage, self.sid, self.username)
self.user_appliers['folders'] = folder_applier_user(self.storage, self.sid, self.username)
self.user_appliers['gsettings'] = gsettings_applier_user(self.storage, self.sid, self.username)
try:
self.user_appliers['cifs'] = cifs_applier_user(self.storage, self.sid, self.username)
except Exception as exc:
logdata = dict()
logdata['applier_name'] = 'cifs'
logdata['msg'] = str(exc)
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)
def machine_apply(self):
'''
Run global appliers with administrator privileges.
'''
if not is_root():
logging.error('Not sufficient privileges to run machine appliers')
log('E13')
return
logging.debug(slogm('Applying computer part of settings'))
log('D16')
for applier_name, applier_object in self.machine_appliers.items():
try:
applier_object.apply()
except Exception as exc:
logging.error('Error occured while running applier {}: {}'.format(applier_name, exc))
logdata = dict()
logdata['applier_name'] = applier_name
logdata['msg'] = str(exc)
log('E24', logdata)
def user_apply(self):
'''
@ -140,18 +148,25 @@ class frontend_manager:
try:
applier_object.admin_context_apply()
except Exception as exc:
logging.error('Error occured while running applier {}: {}'.format(applier_name, exc))
logdata = dict()
logdata['applier'] = applier_name
logdata['exception'] = str(exc)
log('E19', logdata)
try:
with_privileges(self.username, applier_object.user_context_apply)
except Exception as exc:
logging.error('Error occured while running applier {}: {}'.format(applier_name, exc))
logdata = dict()
logdata['applier'] = applier_name
logdata['exception'] = str(exc)
log('E20', logdata)
else:
for applier_name, applier_object in self.user_appliers.items():
try:
applier_object.user_context_apply()
except Exception as exc:
logging.error('Error occured while running applier {}: {}'.format(applier_name, exc))
logdata = dict({'applier_name': applier_name, 'message': str(exc)})
log('E11', logdata)
def apply_parameters(self):
'''

View File

@ -18,13 +18,13 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import argparse
import logging
import os
import signal
from backend import backend_factory
from frontend.frontend_manager import frontend_manager, determine_username
from plugin import plugin_manager
from messages import message_with_code
from util.util import get_machine_name
from util.kerberos import (
@ -38,7 +38,8 @@ from util.users import (
from util.arguments import (
set_loglevel
)
from util.logging import slogm
from util.logging import log
from util.exceptions import geterr
from util.signals import signal_handler
def parse_arguments():
@ -80,7 +81,10 @@ class gpoa_controller:
uname = get_process_user()
uid = os.getuid()
logging.debug(slogm('The process was started for user {} with UID {}'.format(uname, uid), uid=uid))
logdata = dict()
logdata['username'] = uname
logdata['uid'] = uid
log('D1', logdata)
if not is_root():
self.username = uname
@ -94,7 +98,6 @@ class gpoa_controller:
self.__kinit_successful = machine_kinit(self.cache_path)
self.start_plugins()
self.start_backend()
self.start_frontend()
if self.__kinit_successful:
machine_kdestroy()
@ -109,12 +112,31 @@ class gpoa_controller:
if not self.__args.noupdate:
if is_root():
back = backend_factory(dc, self.username, self.is_machine, nodomain)
back = None
try:
back = backend_factory(dc, self.username, self.is_machine, nodomain)
except Exception as exc:
logdata = dict({'msg': str(exc)})
einfo = geterr()
print(einfo)
print(type(einfo))
#logdata.update(einfo)
log('E12', logdata)
if back:
try:
back.retrieve_and_store()
# Start frontend only on successful backend finish
self.start_frontend()
except Exception as exc:
logging.error(slogm('Backend execution error: {}'.format(str(exc))))
logdata = dict({'message': str(exc)})
# In case we're handling "E3" - it means that
# this is a very specific exception that was
# not handled properly on lower levels of
# code so we're also printing file name and
# other information.
einfo = geterr()
logdata.update(einfo)
log('E3', logdata)
def start_frontend(self):
'''
@ -124,7 +146,11 @@ class gpoa_controller:
appl = frontend_manager(self.username, self.is_machine)
appl.apply_parameters()
except Exception as exc:
logging.error(slogm('Error occured while running applier: {}'.format(exc)))
logdata = dict({'message': str(exc)})
einfo = geterr()
#print(einfo)
logdata.update(einfo)
log('E4', logdata)
def start_plugins(self):
'''

View File

@ -16,7 +16,6 @@
# 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 logging
import os
from pathlib import Path
from enum import Enum, unique
@ -73,7 +72,7 @@ from util.paths import (
cache_dir,
local_policy_cache
)
from util.logging import slogm
from util.logging import log
@unique
@ -150,7 +149,6 @@ class gpt:
self.name = ''
self.guid = self.path.rpartition('/')[2]
self.name = ''
if 'default' == self.guid:
self.guid = 'Local Policy'
@ -176,9 +174,11 @@ class gpt:
for setting in self.settings_list:
machine_preffile = find_preffile(self._machine_path, setting)
user_preffile = find_preffile(self._user_path, setting)
logging.debug('Looking for {} in machine part of GPT {}: {}'.format(setting, self.name, machine_preffile))
mlogdata = dict({'setting': setting, 'prefpath': machine_preffile})
log('D24', mlogdata)
self.settings['machine'][setting] = machine_preffile
logging.debug('Looking for {} in user part of GPT {}: {}'.format(setting, self.name, user_preffile))
ulogdata = dict({'setting': setting, 'prefpath': user_preffile})
log('D23', ulogdata)
self.settings['user'][setting] = user_preffile
def set_name(self, name):
@ -211,17 +211,19 @@ class gpt:
for preference_name, preference_path in self.settings['machine'].items():
if preference_path:
preference_type = get_preftype(preference_path)
logstring = 'Reading and merging {} for {}'.format(preference_type.value, self.sid)
logging.debug(logstring)
logdata = dict({'pref': preference_type.value, 'sid': self.sid})
log('D28', logdata)
preference_parser = get_parser(preference_type)
preference_merger = get_merger(preference_type)
preference_objects = preference_parser(preference_path)
preference_merger(self.storage, self.sid, preference_objects, self.name)
if self.settings['user']['regpol']:
logging.debug(slogm('Merging machine(user) settings from {}'.format(self.settings['machine']['regpol'])))
mulogdata = dict({'polfile': self.settings['machine']['regpol']})
log('D35', mulogdata)
util.preg.merge_polfile(self.settings['user']['regpol'], sid=self.sid, policy_name=self.name)
if self.settings['machine']['regpol']:
logging.debug(slogm('Merging machine settings from {}'.format(self.settings['machine']['regpol'])))
mlogdata = dict({'polfile': self.settings['machine']['regpol']})
log('D34', mlogdata)
util.preg.merge_polfile(self.settings['machine']['regpol'], policy_name=self.name)
else:
# Merge user settings if UserPolicyMode set accordingly
@ -231,8 +233,8 @@ class gpt:
for preference_name, preference_path in self.settings['user'].items():
if preference_path:
preference_type = get_preftype(preference_path)
logstring = 'Reading and merging {} for {}'.format(preference_type.value, self.sid)
logging.debug(logstring)
logdata = dict({'pref': preference_type.value, 'sid': self.sid})
log('D29', logdata)
preference_parser = get_parser(preference_type)
preference_merger = get_merger(preference_type)
preference_objects = preference_parser(preference_path)
@ -330,7 +332,7 @@ def get_local_gpt(sid):
'''
Convert default policy to GPT and create object out of it.
'''
logging.debug(slogm('Re-caching Local Policy'))
log('D25')
lp2gpt()
local_policy = gpt(str(local_policy_cache()), sid)
local_policy.set_name('Local Policy')

View File

@ -22,7 +22,6 @@ import argparse
import subprocess
import os
import sys
import logging
import pwd
import signal
@ -31,6 +30,7 @@ from util.users import (
)
from util.arguments import (
process_target,
set_loglevel,
ExitCodeUpdater
)
from util.dbus import (
@ -39,9 +39,9 @@ from util.dbus import (
)
from util.signals import signal_handler
from messages import message_with_code
from util.logging import log
logging.basicConfig(level=logging.DEBUG)
#logging.basicConfig(level=logging.DEBUG)
class file_runner:
_gpoa_exe = '/usr/sbin/gpoa'
@ -91,24 +91,18 @@ def runner_factory(args, target):
target = 'Computer'
except:
username = None
logstring = (
'Unable to perform gpupdate for non-existent user {},'
' will update machine settings'
)
logging.error(logstring.format(args.user))
logdata = dict({'username': args.user})
log('W1', logdata)
else:
# User may only perform gpupdate for machine (None) or
# itself (os.getusername()).
username = pwd.getpwuid(os.getuid()).pw_name
if args.user != username:
logstring = (
'Unable to perform gpupdate for {} with current'
' permissions, will update current user settings'
)
logging.error(logstring.format(args.user))
logdata = dict({'username': args.user})
log('W2', logdata)
if is_oddjobd_gpupdate_accessible():
logging.debug('Starting gpupdate via D-Bus')
log('D13')
computer_runner = None
user_runner = None
if target == 'All' or target == 'Computer':
@ -118,10 +112,10 @@ def runner_factory(args, target):
user_runner = dbus_runner(username)
return (computer_runner, user_runner)
else:
logging.warning('oddjobd is inaccessible')
log('W3')
if is_root():
logging.debug('Starting gpupdate by command invocation')
log('D14')
computer_runner = None
user_runner = None
if target == 'All' or target == 'Computer':
@ -130,12 +124,13 @@ def runner_factory(args, target):
user_runner = file_runner(username)
return (computer_runner, user_runner)
else:
logging.error(message_with_code('E1'))
log('E1')
return None
def main():
args = parse_cli_arguments()
set_loglevel(0)
gpo_appliers = runner_factory(args, process_target(args.target))
if gpo_appliers:
@ -143,17 +138,19 @@ def main():
try:
gpo_appliers[0].run()
except Exception as exc:
logging.error('Error running GPOA for computer: {}'.format(exc))
logdata = dict({'error': str(exc)})
log('E5')
return int(ExitCodeUpdater.FAIL_GPUPDATE_COMPUTER_NOREPLY)
if gpo_appliers[1]:
try:
gpo_appliers[1].run()
except Exception as exc:
logging.error('Error running GPOA for user: {}'.format(exc))
logdata = dict({'error': str(exc)})
log('E6', logdata)
return int(ExitCodeUpdater.FAIL_GPUPDATE_USER_NOREPLY)
else:
logging.error(message_with_code('E2'))
log('E2')
return int(ExitCodeUpdater.FAIL_NO_RUNNER)
return int(ExitCodeUpdater.EXIT_SUCCESS)

View File

@ -18,8 +18,8 @@
def info_code(code):
info_ids = dict()
info_ids[1] = ''
info_ids[2] = ''
info_ids[1] = 'Got GPO list for username'
info_ids[2] = 'Got GPO'
return info_ids.get(code, 'Unknown info code')
@ -27,23 +27,110 @@ def error_code(code):
error_ids = dict()
error_ids[1] = 'Insufficient permissions to run gpupdate'
error_ids[2] = 'gpupdate will not be started'
error_ids[3] = 'Backend execution error'
error_ids[4] = 'Error occurred while running frontend manager'
error_ids[5] = 'Error running GPOA for computer'
error_ids[6] = 'Error running GPOA for user'
error_ids[7] = 'Unable to initialize Samba backend'
error_ids[8] = 'Unable to initialize no-domain backend'
error_ids[9] = 'Error running ADP'
error_ids[10] = 'Unable to determine DC hostname'
error_ids[11] = 'Error occured while running applier with user privileges'
error_ids[12] = 'Unable to initialize backend'
error_ids[13] = 'Not sufficient privileges to run machine appliers'
error_ids[14] = 'Kerberos ticket check failed'
error_ids[15] = 'Unable to retrieve domain name via CLDAP query'
error_ids[16] = 'Error getting SID using wbinfo, will use SID from cache'
error_ids[17] = 'Unable to get GPO list for user from AD DC'
error_ids[18] = 'Error getting XDG_DESKTOP_DIR'
error_ids[19] = 'Error occured while running user applier in administrator context'
error_ids[20] = 'Error occured while running user applier in user context (with dropped privileges)'
error_ids[21] = 'No reply from oddjobd GPOA runner via D-Bus for current user'
error_ids[22] = 'No reply from oddjobd GPOA runner via D-Bus for computer'
error_ids[23] = 'No reply from oddjobd GPOA runner via D-Bus for user'
error_ids[24] = 'Error occured while running machine applier'
error_ids[25] = 'Error occured while initializing user applier'
return error_ids.get(code, 'Unknown error code')
def debug_code(code):
debug_ids = dict()
debug_ids[1] = ''
debug_ids[2] = ''
debug_ids[1] = 'The GPOA process was started for user'
debug_ids[2] = 'Username is not specified - will use username of the current process'
debug_ids[3] = 'Initializing plugin manager'
debug_ids[4] = 'ADP plugin initialized'
debug_ids[5] = 'Running ADP plugin'
debug_ids[6] = 'Starting GPOA for user via D-Bus'
debug_ids[7] = 'Cache directory determined'
debug_ids[8] = 'Initializing local backend without domain'
debug_ids[9] = 'Initializing Samba backend for domain'
debug_ids[10] = 'Group Policy target set for update'
debug_ids[11] = 'Starting GPOA for computer via D-Bus'
debug_ids[12] = 'Got exit code'
debug_ids[13] = 'Starting GPOA via D-Bus'
debug_ids[14] = 'Starting GPOA via command invocation'
debug_ids[15] = 'Username for frontend is determined'
debug_ids[16] = 'Applying computer part of settings'
debug_ids[17] = 'Kerberos ticket check succeed'
debug_ids[18] = 'Found AD domain via CLDAP query'
debug_ids[19] = 'Setting info'
debug_ids[20] = 'Initializing cache'
debug_ids[21] = 'Set operational SID'
debug_ids[22] = 'Got PReg entry'
debug_ids[23] = 'Looking for preference in user part of GPT'
debug_ids[24] = 'Looking for preference in machine part of GPT'
debug_ids[25] = 'Re-caching Local Policy'
debug_ids[26] = 'Adding HKCU entry'
debug_ids[27] = 'Skipping branch deletion key'
debug_ids[28] = 'Reading and merging machine preference'
debug_ids[29] = 'Reading and merging user preference'
debug_ids[30] = 'Found SYSVOL entry'
debug_ids[31] = 'Trying to load PReg from .pol file'
debug_ids[32] = 'Finished reading PReg from .pol file'
debug_ids[33] = 'Determined length of PReg file'
debug_ids[34] = 'Merging machine settings from PReg file'
debug_ids[35] = 'Merging machine (user part) settings from PReg file'
debug_ids[36] = 'Loading PReg from XML'
debug_ids[37] = 'Setting process permissions'
debug_ids[38] = 'Samba DC setting is overriden by user setting'
debug_ids[39] = 'Saving information about drive mapping'
debug_ids[40] = 'Saving information about printer'
debug_ids[41] = 'Saving information about link'
debug_ids[42] = 'Saving information about folder'
debug_ids[43] = 'No value cached for object'
debug_ids[44] = 'Key is already present in cache, will update the value'
debug_ids[45] = 'GPO update started'
debug_ids[46] = 'GPO update finished'
debug_ids[47] = 'Retrieving list of GPOs to replicate from AD DC'
debug_ids[48] = 'Establishing connection with AD DC'
debug_ids[49] = 'Started GPO replication from AD DC'
debug_ids[50] = 'Finished GPO replication from AD DC'
return debug_ids.get(code, 'Unknown debug code')
def warning_code(code):
warning_ids = dict()
warning_ids[1] = ''
warning_ids[2] = ''
warning_ids[1] = (
'Unable to perform gpupdate for non-existent user, '
'will update machine settings'
)
warning_ids[2] = (
'Current permissions does not allow to perform gpupdate for '
'designated user. Will update current user settings'
)
warning_ids[3] = 'oddjobd is inaccessible'
warning_ids[4] = 'No SYSVOL entry assigned to GPO'
warning_ids[5] = 'ADP package is not installed - plugin will not be initialized'
warning_ids[6] = 'Skipping branch deletion key'
return warning_ids.get(code, 'Unknown warning code')
def fatal_code(code):
fatal_ids = dict()
fatal_ids[1] = 'Unable to refresh GPO list'
return fatal_ids.get(code, 'Unknown fatal code')
def get_message(code):
retstr = 'Unknown message type, no message assigned'
@ -55,11 +142,13 @@ def get_message(code):
retstr = debug_code(int(code[1:]))
if code.startswith('W'):
retstr = warning_code(int(code[1:]))
if code.startswith('F'):
retstr = fatal_code(int(code[1:]))
return retstr
def message_with_code(code):
retstr = '[' + code[0:1] + code[1:].rjust(5, '0') + ']: ' + get_message(code)
retstr = '[' + code[0:1] + code[1:].rjust(5, '0') + ']| ' + get_message(code)
return retstr

View File

@ -22,19 +22,20 @@ import subprocess
from util.rpm import is_rpm_installed
from .exceptions import PluginInitError
from util.logging import slogm
from messages import message_with_code
class adp:
def __init__(self):
if not is_rpm_installed('adp'):
raise PluginInitError('adp is not installed - plugin cannot be initialized')
logging.info(slogm('ADP plugin initialized'))
raise PluginInitError(message_with_code('W5'))
logging.info(slogm(message_with_code('D4')))
def run(self):
try:
logging.info('Running ADP plugin')
logging.info(slogm(message_with_code('D5')))
subprocess.call(['/usr/bin/adp', 'fetch'])
subprocess.call(['/usr/bin/adp', 'apply'])
except Exception as exc:
logging.error(slogm('Error running ADP'))
logging.error(slogm(message_with_code('E9')))
raise exc

View File

@ -23,15 +23,16 @@ from .roles import roles
from .exceptions import PluginInitError
from .plugin import plugin
from util.logging import slogm
from messages import message_with_code
class plugin_manager:
def __init__(self):
self.plugins = dict()
logging.info(slogm('Starting plugin manager'))
logging.debug(slogm(message_with_code('D3')))
try:
self.plugins['adp'] = adp()
except PluginInitError as exc:
logging.error(slogm(exc))
logging.warning(slogm(str(exc)))
def run(self):
self.plugins.get('adp', plugin('adp')).run()

View File

@ -18,7 +18,6 @@
from .cache import cache
import logging
import os
from sqlalchemy import (
@ -34,7 +33,7 @@ from sqlalchemy.orm import (
sessionmaker
)
from util.logging import slogm
from util.logging import log
from util.paths import cache_dir
def mapping_factory(mapper_suffix):
@ -53,7 +52,8 @@ class sqlite_cache(cache):
self.cache_name = cache_name
self.mapper_obj = mapping_factory(self.cache_name)
self.storage_uri = os.path.join('sqlite:///{}/{}.sqlite'.format(cache_dir(), self.cache_name))
logging.debug(slogm('Initializing cache {}'.format(self.storage_uri)))
logdata = dict({'cache_file': self.storage_uri})
log('D20', logdata)
self.db_cnt = create_engine(self.storage_uri, echo=False)
self.__metadata = MetaData(self.db_cnt)
self.cache_table = Table(
@ -80,7 +80,9 @@ class sqlite_cache(cache):
def get_default(self, obj_id, default_value):
result = self.get(obj_id)
if result == None:
logging.debug(slogm('No value cached for {}'.format(obj_id)))
logdata = dict()
logdata['object'] = obj_id
log('D43', logdata)
self.store(obj_id, default_value)
return str(default_value)
return result.value
@ -89,9 +91,11 @@ class sqlite_cache(cache):
try:
self.db_session.add(obj)
self.db_session.commit()
except:
except Exception as exc:
self.db_session.rollback()
logging.error(slogm('Error inserting value into cache, will update the value'))
logdata = dict()
logdata['msg'] = str(exc)
log('D44', logdata)
self.db_session.query(self.mapper_obj).filter(self.mapper_obj.str_id == obj.str_id).update({ 'value': obj.value })
self.db_session.commit()

View File

@ -16,7 +16,6 @@
# 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 logging
import os
from sqlalchemy import (
@ -33,7 +32,7 @@ from sqlalchemy.orm import (
sessionmaker
)
from util.logging import slogm
from util.logging import log
from util.paths import cache_dir
from .registry import registry
from .record_types import (
@ -221,7 +220,10 @@ class sqlite_registry(registry):
def set_info(self, name, value):
ientry = info_entry(name, value)
logging.debug(slogm('Setting info {}:{}'.format(name, value)))
logdata = dict()
logdata['varname'] = name
logdata['value'] = value
log('D19', logdata)
self._info_upsert(ientry)
def add_hklm_entry(self, preg_entry, policy_name):
@ -232,25 +234,30 @@ class sqlite_registry(registry):
if not pentry.hive_key.rpartition('\\')[2].startswith('**'):
self._hklm_upsert(pentry)
else:
logging.warning(slogm('Skipping branch deletion key: {}'.format(pentry.hive_key)))
logdata = dict({'key': pentry.hive_key})
log('W6', logdata)
def add_hkcu_entry(self, preg_entry, sid, policy_name):
'''
Write PReg entry to HKEY_CURRENT_USER
'''
hkcu_pentry = samba_hkcu_preg(sid, preg_entry, policy_name)
logdata = dict({'sid': sid, 'policy': policy_name, 'key': hkcu_pentry.hive_key})
if not hkcu_pentry.hive_key.rpartition('\\')[2].startswith('**'):
logging.debug(slogm('Adding HKCU entry for {}'.format(sid)))
log('D26', logdata)
self._hkcu_upsert(hkcu_pentry)
else:
logging.warning(slogm('Skipping branch deletion key: {}'.format(hkcu_pentry.hive_key)))
log('D27', logdata)
def add_shortcut(self, sid, sc_obj, policy_name):
'''
Store shortcut information in the database
'''
sc_entry = ad_shortcut(sid, sc_obj, policy_name)
logging.debug(slogm('Saving info about {} link for {}'.format(sc_entry.path, sid)))
logdata = dict()
logdata['link'] = sc_entry.path
logdata['sid'] = sid
log('D41', logdata)
self._shortcut_upsert(sc_entry)
def add_printer(self, sid, pobj, policy_name):
@ -258,18 +265,26 @@ class sqlite_registry(registry):
Store printer configuration in the database
'''
prn_entry = printer_entry(sid, pobj, policy_name)
logging.debug(slogm('Saving info about printer {} for {}'.format(prn_entry.name, sid)))
logdata = dict()
logdata['printer'] = prn_entry.name
logdata['sid'] = sid
log('D40', logdata)
self._printer_upsert(prn_entry)
def add_drive(self, sid, dobj, policy_name):
drv_entry = drive_entry(sid, dobj, policy_name)
logging.debug(slogm('Saving info about drive mapping {} for {}'.format(drv_entry.path, sid)))
logdata = dict()
logdata['uri'] = drv_entry.path
logdata['sid'] = sid
log('D39', logdata)
self._drive_upsert(drv_entry)
def add_folder(self, sid, fobj, policy_name):
fld_entry = folder_entry(sid, fobj, policy_name)
logstring = 'Saving info about folder {} for {}'.format(fld_entry.path, sid)
logging.debug(logstring)
logdata = dict()
logdata['folder'] = fld_entry.path
logdata['sid'] = sid
log('D42', logdata)
try:
self._add(fld_entry)
except Exception as exc:

View File

@ -20,6 +20,7 @@ import logging
import logging.handlers
from enum import IntEnum
from messages import message_with_code
from .logging import slogm
@ -71,7 +72,8 @@ def process_target(target_name=None):
if target_name == 'User':
target = 'User'
logging.debug(slogm('Target is: {}'.format(target)))
logdata = dict({'target': target})
logging.debug(slogm(message_with_code('D10'), logdata))
return target

View File

@ -16,10 +16,9 @@
# 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 logging
import dbus
from .logging import slogm
from .logging import log
from .users import is_root
@ -41,28 +40,31 @@ class dbus_runner:
def run(self):
#print(obj.Introspect()[0])
if self.username:
logging.info(slogm('Starting GPO applier for user {} via D-Bus'.format(self.username)))
logdata = dict({'username': self.username})
log('D6', logdata)
if is_root():
try:
result = self.interface.gpupdatefor(dbus.String(self.username))
print_dbus_result(result)
except dbus.exceptions.DBusException as exc:
logging.error(slogm('No reply from oddjobd gpoa runner for {}'.format(self.username)))
logdata = dict()
logdata['username'] = self.username
log('E23', logdata)
raise exc
else:
try:
result = self.interface.gpupdate()
print_dbus_result(result)
except dbus.exceptions.DBusException as exc:
logging.error(slogm('No reply from oddjobd gpoa runner for current user'))
log('E21')
raise exc
else:
logging.info(slogm('Starting GPO applier for computer via D-Bus'))
log('D11')
try:
result = self.interface.gpupdate_computer()
print_dbus_result(result)
except dbus.exceptions.DBusException as exc:
logging.error(slogm('No reply from oddjobd gpoa runner for computer'))
log('E22')
raise exc
#self.interface.Quit()
@ -130,7 +132,8 @@ def print_dbus_result(result):
'''
exitcode = result[0]
message = result[1:]
logging.debug(slogm('Exit code is {}'.format(exitcode)))
logdata = dict({'retcode': exitcode})
log('D12', logdata)
for line in message:
print(str(line))

View File

@ -32,7 +32,7 @@ def geterr():
, 'line': etrace.tb_lineno
, 'name': etrace.tb_frame.f_code.co_name
, 'type': etype.__name__
, 'message': evalue.message
, 'message': evalue
})
del(etype, evalue, etrace)

View File

@ -17,11 +17,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import os
import logging
import subprocess
from .util import get_machine_name
from .logging import slogm
from .logging import log
def machine_kinit(cache_name=None):
@ -78,8 +77,8 @@ def check_krb_ticket():
logging.info(output)
result = True
except:
logging.error(slogm('Kerberos ticket check unsuccessful'))
log('E14')
logging.debug(slogm('Ticket check succeed'))
log('D17')
return result

View File

@ -18,11 +18,15 @@
import json
import datetime
import logging
from messages import message_with_code
class encoder(json.JSONEncoder):
def default(self, obj):
result = super(encoder, self).default(obj)
result = super(encoder, self)
result = result.default(obj)
if isinstance(obj, set):
result = tuple(obj)
@ -36,19 +40,42 @@ class slogm(object):
'''
Structured log message class
'''
def __init__(self, message, **kwargs):
def __init__(self, message, kwargs=dict()):
self.message = message
self.kwargs = kwargs
if not self.kwargs:
self.kwargs = dict()
def __str__(self):
now = str(datetime.datetime.now())
now = str(datetime.datetime.now().isoformat(sep=' ', timespec='milliseconds'))
args = dict()
args.update(dict({'timestamp': now, 'message': str(self.message)}))
#args.update(dict({'timestamp': now, 'message': str(self.message)}))
args.update(self.kwargs)
kwa = encoder().encode(args)
result = '{}:{}'.format(now.rpartition('.')[0], self.message)
result = '{}|{}|{}'.format(now, self.message, kwa)
return result
def log(message_code, data=None):
mtype = message_code[0]
if 'I' == mtype:
logging.info(slogm(message_with_code(message_code), data))
return
if 'W' == mtype:
logging.warning(slogm(message_with_code(message_code), data))
return
if 'E' == mtype:
logging.error(slogm(message_with_code(message_code), data))
return
if 'F' == mtype:
logging.fatal(slogm(message_with_code(message_code), data))
return
if 'D' == mtype:
logging.debug(slogm(message_with_code(message_code), data))
return
logging.error(slogm(message_with_code(message_code), data))

View File

@ -16,14 +16,13 @@
# 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 logging
from xml.etree import ElementTree
from storage import registry_factory
from samba.gp_parse.gp_pol import GPPolParser
from .logging import slogm
from .logging import log
def load_preg(file_path):
@ -40,7 +39,8 @@ def load_xml_preg(xml_path):
'''
Parse XML/PReg file and return its preg object
'''
logging.debug('Loading PReg from XML: {}'.format(xml_path))
logdata = dict({'polfile': xml_path})
log('D36', logdata)
gpparser = GPPolParser()
xml_root = ElementTree.parse(xml_path).getroot()
gpparser.load_xml(xml_root)
@ -53,13 +53,15 @@ def load_pol_preg(polfile):
'''
Parse PReg file and return its preg object
'''
logging.debug(slogm('Loading PReg from .pol file: {}'.format(polfile)))
logdata = dict({'polfile': polfile})
log('D31', logdata)
gpparser = GPPolParser()
data = None
with open(polfile, 'rb') as f:
data = f.read()
logging.debug('PReg length: {}'.format(len(data)))
logdata = dict({'polfile': polfile, 'length': len(data)})
log('D33', logdata)
gpparser.parse(data)
#print(gpparser.pol_file.__ndr_print__())
@ -80,7 +82,8 @@ def preg_keymap(preg):
def merge_polfile(preg, sid=None, reg_name='registry', reg_path=None, policy_name='Unknown'):
pregfile = load_preg(preg)
logging.info(slogm('Loaded PReg {}'.format(preg)))
logdata = dict({'pregfile': preg})
log('D32', logdata)
storage = registry_factory(reg_name, reg_path)
for entry in pregfile.entries:
if not sid:
@ -91,14 +94,16 @@ def merge_polfile(preg, sid=None, reg_name='registry', reg_path=None, policy_nam
class entry:
def __init__(self, e_keyname, e_valuename, e_type, e_data):
logging.debug(slogm('Entry init e_keyname {}'.format(e_keyname)))
logging.debug(slogm('Entry init e_valuename {}'.format(e_valuename)))
logging.debug(slogm('Entry init e_type {}'.format(e_type)))
logging.debug(slogm('Entry init e_data {}'.format(e_data)))
self.keyname = e_keyname
self.valuename = e_valuename
self.type = e_type
self.data = e_data
logdata = dict()
logdata['keyname'] = self.keyname
logdata['valuename'] = self.valuename
logdata['type'] = self.type
logdata['data'] = self.data
log('D22', logdata)
class pentries:
def __init__(self):

View File

@ -243,6 +243,3 @@ def sid2descr(sid):
return sids.get(sid, None)
if __name__ == '__main__':
pass

View File

@ -18,9 +18,8 @@
import os
import pwd
import logging
from .logging import slogm
from .logging import log
def is_root():
@ -75,9 +74,11 @@ def set_privileges(username, uid, gid, groups=list()):
#except Exception as exc:
# print('setgroups')
logging.debug(
slogm('Set process permissions to UID {} and GID {} for user {}'.format(
uid, gid, username)))
logdata = dict()
logdata['uid'] = uid
logdata['gid'] = gid
logdata['username'] = username
log('D37', logdata)
def with_privileges(username, func):
@ -103,7 +104,7 @@ def with_privileges(username, func):
try:
out = func()
except Exception as exc:
logging.debug(slogm(exc))
log(str(exc))
# Restore privileges
set_privileges('root', current_uid, 0, current_groups)

View File

@ -17,7 +17,6 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
import os
import pwd
@ -29,11 +28,12 @@ import samba.gpo
import pysss_nss_idmap
from storage import cache_factory
from messages import message_with_code
from .xdg import (
xdg_get_desktop
)
from .util import get_homedir
from .logging import slogm
from .logging import log
from .samba import smbopts
@ -58,16 +58,16 @@ class smbcreds (smbopts):
samba_dc = get_dc_hostname(self.creds, self.lp)
if samba_dc != dc_fqdn and dc_fqdn is not None:
logging.debug(
slogm('Samba DC setting is {} and is overwritten by user setting {}'.format(
samba_dc, dc)))
logdata = dict()
logdata['dc'] = samba_dc
logdata['user_dc'] = dc
log('D38', logdata)
self.selected_dc = dc_fqdn
else:
self.selected_dc = samba_dc
except Exception as exc:
logging.error(slogm('Unable to determine DC hostname'))
log('E10')
raise exc
return self.selected_dc
@ -82,9 +82,10 @@ class smbcreds (smbopts):
# Look and python/samba/netcmd/domain.py for more examples
res = netcmd_get_domain_infos_via_cldap(self.lp, None, self.selected_dc)
dns_domainname = res.dns_domain
logging.info(slogm('Found domain via CLDAP: {}'.format(dns_domainname)))
logdata = dict({'domain': dns_domainname})
log('D18', logdata)
except Exception as exc:
logging.error(slogm('Unable to retrieve domain name via CLDAP query'))
log('E15')
raise exc
return dns_domainname
@ -97,19 +98,22 @@ class smbcreds (smbopts):
gpos = list()
try:
log('D48')
ads = samba.gpo.ADS_STRUCT(self.selected_dc, self.lp, self.creds)
if ads.connect():
log('D47')
gpos = ads.get_gpo_list(username)
logging.info(slogm('Got GPO list for {}:'.format(username)))
logdata = dict({'username': username})
log('I1', logdata)
for gpo in gpos:
# These setters are taken from libgpo/pygpo.c
# print(gpo.ds_path) # LDAP entry
logging.info(slogm('GPO: {} ({})'.format(gpo.display_name, gpo.name)))
ldata = dict({'gpo_name': gpo.display_name, 'gpo_uuid': gpo.name})
log('I2', ldata)
except Exception as exc:
logging.error(
slogm('Unable to get GPO list for {} from {}'.format(
username, self.selected_dc)))
logdata = dict({'username': username, 'dc': self.selected_dc})
log('E17', logdata)
return gpos
@ -117,11 +121,15 @@ class smbcreds (smbopts):
gpos = self.get_gpos(username)
try:
log('D49')
check_refresh_gpo_list(self.selected_dc, self.lp, self.creds, gpos)
log('D50')
except Exception as exc:
logging.error(
slogm('Unable to refresh GPO list for {} from {}'.format(
username, self.selected_dc)))
logdata = dict()
logdata['username'] = username
logdata['dc'] = self.selected_dc
logdata['err'] = str(exc)
log('F1')
raise exc
return gpos
@ -166,10 +174,11 @@ def get_sid(domain, username, is_machine = False):
try:
sid = wbinfo_getsid(domain, username)
except:
logging.warning(
slogm('Error getting SID using wbinfo, will use cached SID: {}'.format(sid)))
logdata = dict({'sid': sid})
log('E16', logdata)
logging.debug(slogm('Working with SID: {}'.format(sid)))
logdata = dict({'sid': sid})
log('D21', logdata)
return sid

View File

@ -20,15 +20,17 @@
import os
from .util import get_homedir
from .logging import slogm
from .logging import log
def xdg_get_desktop(username, homedir = None):
if username:
homedir = get_homedir(username)
if not homedir:
logging.warning(
slogm('Error for get XDG_DESKTOP_DIR for unknown user with unknown homedir'))
raise "Error for get XDG_DESKTOP_DIR for unknown user with unknown homedir"
msgtext = message_with_code('E18')
logdata = dict()
logdata['username'] = username
log('E18', logdata)
raise Exception(msgtext)
stream = os.popen('export HOME={}; xdg-user-dir DESKTOP'.format(homedir))
output = stream.read()[:-1]