Merge pull request #38596 from isbm/isbm-disable-custom-roster-for-api

Disable custom roster for Salt API
This commit is contained in:
Mike Place 2017-01-05 16:20:01 -07:00 committed by GitHub
commit 5b60b04195
4 changed files with 51 additions and 11 deletions

View file

@ -400,6 +400,17 @@
# Pass in an alternative location for the salt-ssh roster file
#roster_file: /etc/salt/roster
# Define a locations for roster files so they can be chosen when using Salt API.
# An administrator can place roster files into these locations. Then when
# calling Salt API, parameter 'roster_file' should contain a relative path to
# these locations. That is, "roster_file=/foo/roster" will be resolved as
# "/etc/salt/roster.d/foo/roster" etc. This feature prevents passing insecure
# custom rosters through the Salt API.
#
#rosters:
# - /etc/salt/roster.d
# - /opt/salt/some/more/rosters
# The log file of the salt-ssh command:
#ssh_log_file: /var/log/salt/ssh

View file

@ -22,7 +22,8 @@ class SSHClient(object):
'''
def __init__(self,
c_path=os.path.join(syspaths.CONFIG_DIR, 'master'),
mopts=None):
mopts=None,
disable_custom_roster=False):
if mopts:
self.opts = mopts
else:
@ -35,6 +36,9 @@ class SSHClient(object):
)
self.opts = salt.config.client_config(c_path)
# Salt API should never offer a custom roster!
self.opts['__disable_custom_roster'] = disable_custom_roster
def _prep_ssh(
self,
tgt,

View file

@ -129,7 +129,8 @@ class NetapiClient(object):
:return: Returns the result from the salt-ssh command
'''
ssh_client = salt.client.ssh.client.SSHClient(mopts=self.opts)
ssh_client = salt.client.ssh.client.SSHClient(mopts=self.opts,
disable_custom_roster=True)
return ssh_client.cmd_sync(kwargs)
def runner(self, fun, timeout=None, **kwargs):

View file

@ -19,19 +19,43 @@ log = logging.getLogger(__name__)
def get_roster_file(options):
if options.get('roster_file'):
template = options.get('roster_file')
elif 'config_dir' in options.get('__master_opts__', {}):
template = os.path.join(options['__master_opts__']['config_dir'],
'roster')
elif 'config_dir' in options:
template = os.path.join(options['config_dir'], 'roster')
else:
template = os.path.join(salt.syspaths.CONFIG_DIR, 'roster')
'''
Find respective roster file.
:param options:
:return:
'''
template = None
# The __disable_custom_roster is always True if Salt SSH Client comes
# from Salt API. In that case no way to define own 'roster_file', instead
# this file needs to be chosen from already validated rosters
# (see /etc/salt/master config).
if options.get('__disable_custom_roster') and options.get('roster_file'):
roster = options.get('roster_file').strip('/')
for roster_location in options.get('rosters'):
r_file = os.path.join(roster_location, roster)
if os.path.isfile(r_file):
template = r_file
break
del options['roster_file']
if not template:
if options.get('roster_file'):
template = options.get('roster_file')
elif 'config_dir' in options.get('__master_opts__', {}):
template = os.path.join(options['__master_opts__']['config_dir'],
'roster')
elif 'config_dir' in options:
template = os.path.join(options['config_dir'], 'roster')
else:
template = os.path.join(salt.syspaths.CONFIG_DIR, 'roster')
if not os.path.isfile(template):
raise IOError('No roster file found')
if not os.access(template, os.R_OK):
raise IOError('Access denied to roster "{0}"'.format(template))
return template