Merge "Audit local sysadmin user password periodically"
This commit is contained in:
commit
9eb224b0a9
@ -93,7 +93,8 @@ agent_opts = [
|
||||
audit_intervals_opts = [
|
||||
cfg.IntOpt('default', default=60),
|
||||
cfg.IntOpt('inventory_audit', default=60),
|
||||
cfg.IntOpt('lldp_audit', default=300)
|
||||
cfg.IntOpt('lldp_audit', default=300),
|
||||
cfg.IntOpt('security_audit', default=900),
|
||||
]
|
||||
|
||||
dpdk_opts = [
|
||||
@ -1313,6 +1314,51 @@ class AgentManager(service.PeriodicService):
|
||||
else:
|
||||
self._lldp_enable_and_report(icontext, rpcapi, self._ihost_uuid)
|
||||
|
||||
@periodic_task.periodic_task(spacing=CONF.agent_periodic_task_intervals.security_audit)
|
||||
def _security_audit(self, context):
|
||||
if not self._ihost_uuid:
|
||||
return
|
||||
|
||||
LOG.debug("Sysinv Agent Security Audit running.")
|
||||
|
||||
# get sysadmin password locally
|
||||
with open("/etc/shadow", "r") as f:
|
||||
user_attrs = []
|
||||
lines = f.readlines()
|
||||
for line in lines:
|
||||
if "sysadmin" in line:
|
||||
user_attrs = line.split(":")
|
||||
break
|
||||
if not user_attrs:
|
||||
LOG.warn("No shadow entry found for 'sysadmin' user.")
|
||||
return
|
||||
|
||||
icontext = mycontext.get_admin_context()
|
||||
rpcapi = conductor_rpcapi.ConductorAPI(topic=conductor_rpcapi.MANAGER_TOPIC)
|
||||
|
||||
# get user information from the database
|
||||
try:
|
||||
iuser = rpcapi.get_iuser(icontext)
|
||||
except RemoteError as e:
|
||||
# ignore because active controller is not yet upgraded,
|
||||
# so it's current load may not implement this RPC call
|
||||
if "AttributeError" in str(e):
|
||||
LOG.warn("Skip security audit. Upgrade in progress.")
|
||||
else:
|
||||
LOG.error("Failed to get user configuration via RPC.")
|
||||
return
|
||||
if not iuser.passwd_hash:
|
||||
LOG.warn("No password configured for 'sysadmin' in the database.")
|
||||
return
|
||||
|
||||
# compare sysadmin password hash with the value retrieved from the
|
||||
# database and trigger user config manifest reapply if values differ
|
||||
if iuser.passwd_hash != user_attrs[1]:
|
||||
LOG.info("Configuration mismatch for 'sysadmin' user, attempting to reconfigure...")
|
||||
rpcapi.update_user_config(icontext, [self._ihost_uuid])
|
||||
else:
|
||||
LOG.debug("No divergence found within 'sysadmin' user configuration.")
|
||||
|
||||
@utils.synchronized(LOCK_AGENT_ACTION, external=False)
|
||||
def agent_audit(self, context, host_uuid, force_updates, cinder_device=None):
|
||||
# perform inventory audit
|
||||
|
@ -5797,6 +5797,16 @@ class ConductorManager(service.PeriodicService):
|
||||
system = self.dbapi.isystem_get_one()
|
||||
return system
|
||||
|
||||
def get_iuser(self, context):
|
||||
"""Return iuser object
|
||||
|
||||
This method returns an iuser object
|
||||
|
||||
:returns: iuser object, including all field
|
||||
"""
|
||||
user = self.dbapi.iuser_get_one()
|
||||
return user
|
||||
|
||||
def get_ihost_by_macs(self, context, ihost_macs):
|
||||
"""Finds ihost db entry based upon the mac list
|
||||
|
||||
@ -8144,7 +8154,7 @@ class ConductorManager(service.PeriodicService):
|
||||
cutils.touch(
|
||||
self._get_oam_runtime_apply_file(standby_controller=True))
|
||||
|
||||
def update_user_config(self, context):
|
||||
def update_user_config(self, context, hosts_uuid=None):
|
||||
"""Update the user configuration"""
|
||||
LOG.info("update_user_config")
|
||||
|
||||
@ -8157,6 +8167,9 @@ class ConductorManager(service.PeriodicService):
|
||||
"personalities": personalities,
|
||||
"classes": ['platform::users::runtime']
|
||||
}
|
||||
if hosts_uuid:
|
||||
config_dict.update({"hosts_uuid": hosts_uuid})
|
||||
|
||||
self._config_apply_runtime_manifest(context, config_uuid, config_dict)
|
||||
|
||||
def update_controller_rollback_flag(self, context):
|
||||
|
@ -190,6 +190,15 @@ class ConductorAPI(sysinv.openstack.common.rpc.proxy.RpcProxy):
|
||||
"""
|
||||
return self.call(context, self.make_msg('get_isystem',))
|
||||
|
||||
def get_iuser(self, context):
|
||||
"""Return iuser object
|
||||
|
||||
This method returns an iuser object
|
||||
|
||||
:returns: iuser object, including all field
|
||||
"""
|
||||
return self.call(context, self.make_msg('get_iuser',))
|
||||
|
||||
def get_ihost_by_macs(self, context, ihost_macs):
|
||||
"""Finds ihost db entry based upon the mac list
|
||||
|
||||
@ -752,12 +761,16 @@ class ConductorAPI(sysinv.openstack.common.rpc.proxy.RpcProxy):
|
||||
"""
|
||||
return self.call(context, self.make_msg('update_oam_config'))
|
||||
|
||||
def update_user_config(self, context):
|
||||
def update_user_config(self, context, hosts_uuid=None):
|
||||
"""Synchronously, have the conductor update the user configuration.
|
||||
|
||||
:param context: request context.
|
||||
:param hosts_uuid: list of host_uuids to run user puppet manifest
|
||||
"""
|
||||
return self.call(context, self.make_msg('update_user_config'))
|
||||
return self.call(
|
||||
context,
|
||||
self.make_msg('update_user_config', hosts_uuid=hosts_uuid)
|
||||
)
|
||||
|
||||
def update_controller_rollback_flag(self, context):
|
||||
"""Synchronously, have a conductor update controller rollback flag
|
||||
|
Loading…
Reference in New Issue
Block a user