From 864d80327378ab11983eb4942904a4d0b9d8a17b Mon Sep 17 00:00:00 2001 From: Bill Nottingham Date: Tue, 25 Jul 2017 12:06:40 -0400 Subject: [PATCH 1/3] Don't hardcode privilege escalation prompts if they're all of the same format. Just create them all from supported privilege escalation types. --- awx/main/constants.py | 9 +++++++++ awx/main/models/credential.py | 11 ++--------- awx/main/tasks.py | 36 +++++++---------------------------- 3 files changed, 18 insertions(+), 38 deletions(-) diff --git a/awx/main/constants.py b/awx/main/constants.py index c68adadcc4..1bbdfe4cfc 100644 --- a/awx/main/constants.py +++ b/awx/main/constants.py @@ -1,5 +1,14 @@ # Copyright (c) 2015 Ansible, Inc. # All Rights Reserved. +from django.utils.translation import ugettext_lazy as _ + CLOUD_PROVIDERS = ('azure', 'azure_rm', 'ec2', 'gce', 'rax', 'vmware', 'openstack', 'satellite6', 'cloudforms') SCHEDULEABLE_PROVIDERS = CLOUD_PROVIDERS + ('custom', 'scm',) +PRIVILEGE_ESCALATION_METHODS = [ + ('sudo', _('Sudo')), + ('su', _('Su')), + ('pbrun', _('Pbrun')), + ('pfexec', _('Pfexec')), + ('dzdo', _('DZDO')), + ('pmrun', _('Pmrun'))] diff --git a/awx/main/models/credential.py b/awx/main/models/credential.py index 938d119faf..53d5cfccb7 100644 --- a/awx/main/models/credential.py +++ b/awx/main/models/credential.py @@ -19,6 +19,7 @@ from django.utils.encoding import force_text # AWX from awx.api.versioning import reverse +from awx.main.constants import PRIVILEGE_ESCALATION_METHODS from awx.main.fields import (ImplicitRoleField, CredentialInputField, CredentialTypeInputField, CredentialTypeInjectorField) @@ -135,15 +136,7 @@ class V1Credential(object): max_length=32, blank=True, default='', - choices=[ - ('', _('None')), - ('sudo', _('Sudo')), - ('su', _('Su')), - ('pbrun', _('Pbrun')), - ('pfexec', _('Pfexec')), - ('dzdo', _('DZDO')), - ('pmrun', _('Pmrun')), - ], + choices=[('', _('None'))] + PRIVILEGE_ESCALATION_METHODS, help_text=_('Privilege escalation method.') ), 'become_username': models.CharField( diff --git a/awx/main/tasks.py b/awx/main/tasks.py index 1172027653..f335bae53e 100644 --- a/awx/main/tasks.py +++ b/awx/main/tasks.py @@ -44,7 +44,7 @@ from django.core.exceptions import ObjectDoesNotExist # AWX from awx import __version__ as tower_application_version -from awx.main.constants import CLOUD_PROVIDERS +from awx.main.constants import CLOUD_PROVIDERS, PRIVILEGE_ESCALATION_METHODS from awx.main.models import * # noqa from awx.main.models.unified_jobs import ACTIVE_STATES from awx.main.queue import CallbackQueueDispatcher @@ -1115,20 +1115,9 @@ class RunJob(BaseTask): d = super(RunJob, self).get_password_prompts() d[re.compile(r'Enter passphrase for .*:\s*?$', re.M)] = 'ssh_key_unlock' d[re.compile(r'Bad passphrase, try again for .*:\s*?$', re.M)] = '' - d[re.compile(r'sudo password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'SUDO password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'su password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'SU password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'PBRUN password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'pbrun password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'PMRUN password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'pmrun password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'PFEXEC password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'pfexec password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'RUNAS password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'runas password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'DZDO password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'dzdo password.*:\s*?$', re.M)] = 'become_password' + for method in PRIVILEGE_ESCALATION_METHODS: + d[re.compile(r'%s password.*:\s*?$' % (method[0]), re.M)] = 'become_password' + d[re.compile(r'%s password.*:\s*?$' % (method[0].upper()), re.M)] = 'become_password' d[re.compile(r'SSH password:\s*?$', re.M)] = 'ssh_password' d[re.compile(r'Password:\s*?$', re.M)] = 'ssh_password' d[re.compile(r'Vault password:\s*?$', re.M)] = 'vault_password' @@ -2068,20 +2057,9 @@ class RunAdHocCommand(BaseTask): d = super(RunAdHocCommand, self).get_password_prompts() d[re.compile(r'Enter passphrase for .*:\s*?$', re.M)] = 'ssh_key_unlock' d[re.compile(r'Bad passphrase, try again for .*:\s*?$', re.M)] = '' - d[re.compile(r'sudo password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'SUDO password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'su password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'SU password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'PBRUN password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'pbrun password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'PMRUN password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'pmrun password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'PFEXEC password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'pfexec password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'RUNAS password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'runas password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'DZDO password.*:\s*?$', re.M)] = 'become_password' - d[re.compile(r'dzdo password.*:\s*?$', re.M)] = 'become_password' + for method in PRIVILEGE_ESCALATION_METHODS: + d[re.compile(r'%s password.*:\s*?$' % (method[0]), re.M)] = 'become_password' + d[re.compile(r'%s password.*:\s*?$' % (method[0].upper()), re.M)] = 'become_password' d[re.compile(r'SSH password:\s*?$', re.M)] = 'ssh_password' d[re.compile(r'Password:\s*?$', re.M)] = 'ssh_password' return d From 7077271299b378ac8f166dfaa14d2ce024b28c4e Mon Sep 17 00:00:00 2001 From: Bill Nottingham Date: Tue, 25 Jul 2017 14:19:52 -0400 Subject: [PATCH 2/3] Fixup flake8 --- awx/main/constants.py | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/awx/main/constants.py b/awx/main/constants.py index 1bbdfe4cfc..20cad97538 100644 --- a/awx/main/constants.py +++ b/awx/main/constants.py @@ -5,10 +5,4 @@ from django.utils.translation import ugettext_lazy as _ CLOUD_PROVIDERS = ('azure', 'azure_rm', 'ec2', 'gce', 'rax', 'vmware', 'openstack', 'satellite6', 'cloudforms') SCHEDULEABLE_PROVIDERS = CLOUD_PROVIDERS + ('custom', 'scm',) -PRIVILEGE_ESCALATION_METHODS = [ - ('sudo', _('Sudo')), - ('su', _('Su')), - ('pbrun', _('Pbrun')), - ('pfexec', _('Pfexec')), - ('dzdo', _('DZDO')), - ('pmrun', _('Pmrun'))] +PRIVILEGE_ESCALATION_METHODS = [ ('sudo', _('Sudo')), ('su', _('Su')), ('pbrun', _('Pbrun')), ('pfexec', _('Pfexec')), ('dzdo', _('DZDO')), ('pmrun', _('Pmrun'))] From 4276959dc2e79ca0f683ff4808068432675db9a2 Mon Sep 17 00:00:00 2001 From: Bill Nottingham Date: Tue, 25 Jul 2017 14:55:47 -0400 Subject: [PATCH 3/3] Add runas to the actual list of privilege escalations (added in 2.3). Migration added by hand from the 3.1 migration. --- awx/main/constants.py | 2 +- awx/main/migrations/0006_v320_release.py | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/awx/main/constants.py b/awx/main/constants.py index 20cad97538..bd00147415 100644 --- a/awx/main/constants.py +++ b/awx/main/constants.py @@ -5,4 +5,4 @@ from django.utils.translation import ugettext_lazy as _ CLOUD_PROVIDERS = ('azure', 'azure_rm', 'ec2', 'gce', 'rax', 'vmware', 'openstack', 'satellite6', 'cloudforms') SCHEDULEABLE_PROVIDERS = CLOUD_PROVIDERS + ('custom', 'scm',) -PRIVILEGE_ESCALATION_METHODS = [ ('sudo', _('Sudo')), ('su', _('Su')), ('pbrun', _('Pbrun')), ('pfexec', _('Pfexec')), ('dzdo', _('DZDO')), ('pmrun', _('Pmrun'))] +PRIVILEGE_ESCALATION_METHODS = [ ('sudo', _('Sudo')), ('su', _('Su')), ('pbrun', _('Pbrun')), ('pfexec', _('Pfexec')), ('dzdo', _('DZDO')), ('pmrun', _('Pmrun')), ('runas', _('Runas'))] diff --git a/awx/main/migrations/0006_v320_release.py b/awx/main/migrations/0006_v320_release.py index 102b3accf2..32fc871bd2 100644 --- a/awx/main/migrations/0006_v320_release.py +++ b/awx/main/migrations/0006_v320_release.py @@ -414,6 +414,12 @@ class Migration(migrations.Migration): unique_together=set([('organization', 'name', 'credential_type')]), ), + migrations.AlterField( + model_name='credential', + name='become_method', + field=models.CharField(default=b'', help_text='Privilege escalation method.', max_length=32, blank=True, choices=[(b'', 'None'), (b'sudo', 'Sudo'), (b'su', 'Su'), (b'pbrun', 'Pbrun'), (b'pfexec', 'Pfexec'), (b'dzdo', 'DZDO'), (b'pmrun', 'Pmrun'), (b'runas', 'Runas')]), + ), + # Connecting activity stream migrations.AddField( model_name='activitystream',