Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ACL limit args #29153

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions salt/auth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,7 @@ def rights_check(self, form, sub_auth, name, load, eauth=None):
form,
sub_auth[name] if name in sub_auth else sub_auth['*'],
load.get('fun', None),
load.get('arg', None),
load.get('tgt', None),
load.get('tgt_type', 'glob'))
if not good:
Expand Down
4 changes: 4 additions & 0 deletions salt/daemons/masterapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,7 @@ def __verify_minion_publish(self, load):
good = self.ckminions.auth_check(
perms,
load['fun'],
load['arg'],
load['tgt'],
load.get('tgt_type', 'glob'),
publish_validate=True)
Expand Down Expand Up @@ -1409,6 +1410,7 @@ def publish(self, load):
if token['name'] in self.opts['external_auth'][token['eauth']]
else self.opts['external_auth'][token['eauth']]['*'],
load['fun'],
load['arg'],
load['tgt'],
load.get('tgt_type', 'glob'))
if not good:
Expand Down Expand Up @@ -1450,6 +1452,7 @@ def publish(self, load):
if name in self.opts['external_auth'][extra['eauth']]
else self.opts['external_auth'][extra['eauth']]['*'],
load['fun'],
load['arg'],
load['tgt'],
load.get('tgt_type', 'glob'))
if not good:
Expand Down Expand Up @@ -1506,6 +1509,7 @@ def publish(self, load):
good = self.ckminions.auth_check(
acl[load['user']],
load['fun'],
load['arg'],
load['tgt'],
load.get('tgt_type', 'glob'))
if not good:
Expand Down
5 changes: 5 additions & 0 deletions salt/master.py
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,7 @@ def __verify_minion_publish(self, clear_load):
return self.ckminions.auth_check(
perms,
clear_load['fun'],
clear_load['arg'],
clear_load['tgt'],
clear_load.get('tgt_type', 'glob'),
publish_validate=True)
Expand Down Expand Up @@ -1867,6 +1868,7 @@ def publish(self, clear_load):
good = self.ckminions.auth_check(
auth_list,
clear_load['fun'],
clear_load['arg'],
clear_load['tgt'],
clear_load.get('tgt_type', 'glob'))
if not good:
Expand Down Expand Up @@ -1954,6 +1956,7 @@ def publish(self, clear_load):
good = self.ckminions.auth_check(
auth_list,
clear_load['fun'],
clear_load['arg'],
clear_load['tgt'],
clear_load.get('tgt_type', 'glob')
)
Expand Down Expand Up @@ -1982,6 +1985,7 @@ def publish(self, clear_load):
good = self.ckminions.auth_check(
publisher_acl.get(clear_load['user'].split('_', 1)[-1]),
clear_load['fun'],
clear_load['arg'],
clear_load['tgt'],
clear_load.get('tgt_type', 'glob'))
if not good:
Expand Down Expand Up @@ -2023,6 +2027,7 @@ def publish(self, clear_load):
good = self.ckminions.auth_check(
acl[clear_load['user']],
clear_load['fun'],
clear_load['arg'],
clear_load['tgt'],
clear_load.get('tgt_type', 'glob'))
if not good:
Expand Down
71 changes: 65 additions & 6 deletions salt/utils/minions.py
Original file line number Diff line number Diff line change
Expand Up @@ -690,16 +690,17 @@ def match_check(self, regex, fun):
vals.append(False)
except Exception:
log.error('Invalid regular expression: {0}'.format(regex))
return all(vals)
return vals and all(vals)

def any_auth(self, form, auth_list, fun, tgt=None, tgt_type='glob'):
def any_auth(self, form, auth_list, fun, arg, tgt=None, tgt_type='glob'):
'''
Read in the form and determine which auth check routine to execute
'''
if form == 'publish':
return self.auth_check(
auth_list,
fun,
arg,
tgt,
tgt_type)
return self.spec_check(
Expand All @@ -710,6 +711,7 @@ def any_auth(self, form, auth_list, fun, tgt=None, tgt_type='glob'):
def auth_check(self,
auth_list,
funs,
args,
tgt,
tgt_type='glob',
groups=None,
Expand All @@ -736,8 +738,9 @@ def auth_check(self,
# compound commands will come in a list so treat everything as a list
if not isinstance(funs, list):
funs = [funs]
args = [args]
try:
for fun in funs:
for num, fun in enumerate(funs):
for ind in auth_list:
if isinstance(ind, six.string_types):
# Allowed for all minions
Expand All @@ -758,9 +761,65 @@ def auth_check(self,
if self.match_check(ind[valid], fun):
return True
elif isinstance(ind[valid], list):
for regex in ind[valid]:
if self.match_check(regex, fun):
return True
for cond in ind[valid]:
# Function name match
if isinstance(cond, six.string_types):
if self.match_check(cond, fun):
return True
# Function and args match
elif isinstance(cond, dict):
if len(cond) != 1:
# Invalid argument
continue
fcond = next(six.iterkeys(cond))
# cond: {
# 'mod.func': {
# 'args': [
# 'one.*', 'two\\|three'],
# 'kwargs': {
# 'functioin': 'teach\\|feed',
# 'user': 'mother\\|father'
# }
# }
# }
if self.match_check(fcond, fun): # check key that is function name match
acond = cond[fcond]
if not isinstance(acond, dict):
# Invalid argument
continue
# whitelist args, kwargs
arg_list = args[num]
cond_args = acond.get('args', [])
good = True
for i, cond_arg in enumerate(cond_args):
if len(arg_list) <= i:
good = False
break
if cond_arg is None: # None == '.*' i.e. allow any
continue
if not self.match_check(cond_arg, arg_list[i]):
good = False
break
if not good:
continue
# Check kwargs
cond_kwargs = acond.get('kwargs', {})
arg_kwargs = {}
for a in arg_list:
if isinstance(a, dict) and '__kwarg__' in a:
arg_kwargs = a
break
for k, v in six.iteritems(cond_kwargs):
if k not in arg_kwargs:
good = False
break
if v is None: # None == '.*' i.e. allow any
continue
if not self.match_check(v, arg_kwargs[k]):
good = False
break
if good:
return True
except TypeError:
return False
return False
Expand Down
Loading