mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Require current password when using passwd to change your own password.
Add a new required parameter, current_password. In order to ask this first I added a new parameter option, sortorder. The lower the value the earlier it will be prompted for. I also changed the way autofill works. It will attempt to get the default and if it doesn't get anything will continue prompting interactively. Since current_password is required I'm passing a magic value that means changing someone else's password. We need to pass something since current_password is required. The python-ldap passwd command doesn't seem to use the old password at all so I do a simple bind to validate it. https://fedorahosted.org/freeipa/ticket/1808
This commit is contained in:
committed by
Martin Kosek
parent
28603e0c3a
commit
bd227b3562
@@ -1048,12 +1048,14 @@ class cli(backend.Executioner):
|
||||
for param in cmd.params():
|
||||
if (param.required and param.name not in kw) or \
|
||||
(param.alwaysask and honor_alwaysask) or self.env.prompt_all:
|
||||
if param.autofill:
|
||||
kw[param.name] = param.get_default(**kw)
|
||||
if param.name in kw and kw[param.name] is not None:
|
||||
continue
|
||||
if param.password:
|
||||
kw[param.name] = self.Backend.textui.prompt_password(
|
||||
param.label, param.confirm
|
||||
)
|
||||
elif param.autofill:
|
||||
kw[param.name] = param.get_default(**kw)
|
||||
else:
|
||||
default = param.get_default(**kw)
|
||||
error = None
|
||||
|
||||
@@ -777,6 +777,8 @@ class Command(HasParam):
|
||||
self._create_param_namespace('options')
|
||||
def get_key(p):
|
||||
if p.required:
|
||||
if p.sortorder < 0:
|
||||
return p.sortorder
|
||||
if p.default_from is None:
|
||||
return 0
|
||||
return 1
|
||||
|
||||
@@ -317,6 +317,7 @@ class Param(ReadOnly):
|
||||
('flags', frozenset, frozenset()),
|
||||
('hint', (str, Gettext), None),
|
||||
('alwaysask', bool, False),
|
||||
('sortorder', int, 2), # see finalize()
|
||||
|
||||
# The 'default' kwarg gets appended in Param.__init__():
|
||||
# ('default', self.type, None),
|
||||
|
||||
@@ -23,6 +23,7 @@ from ipalib import Str, Password
|
||||
from ipalib import _
|
||||
from ipalib import output
|
||||
from ipalib.plugins.user import split_principal, validate_principal, normalize_principal
|
||||
from ipalib.request import context
|
||||
|
||||
__doc__ = _("""
|
||||
Set a user's password
|
||||
@@ -43,6 +44,22 @@ EXAMPLES:
|
||||
ipa passwd tuser1
|
||||
""")
|
||||
|
||||
# We only need to prompt for the current password when changing a password
|
||||
# for yourself, but the parameter is still required
|
||||
MAGIC_VALUE = u'CHANGING_PASSWORD_FOR_ANOTHER_USER'
|
||||
|
||||
def get_current_password(principal):
|
||||
"""
|
||||
If the user is changing their own password then return None so the
|
||||
current password is prompted for, otherwise return a fixed value to
|
||||
be ignored later.
|
||||
"""
|
||||
current_principal = util.get_current_principal()
|
||||
if current_principal == normalize_principal(principal):
|
||||
return None
|
||||
else:
|
||||
return MAGIC_VALUE
|
||||
|
||||
class passwd(Command):
|
||||
__doc__ = _("Set a user's password.")
|
||||
|
||||
@@ -56,14 +73,21 @@ class passwd(Command):
|
||||
normalizer=lambda value: normalize_principal(value),
|
||||
),
|
||||
Password('password',
|
||||
label=_('Password'),
|
||||
label=_('New Password'),
|
||||
),
|
||||
Password('current_password',
|
||||
label=_('Current Password'),
|
||||
confirm=False,
|
||||
default_from=lambda principal: get_current_password(principal),
|
||||
autofill=True,
|
||||
sortorder=-1,
|
||||
),
|
||||
)
|
||||
|
||||
has_output = output.standard_value
|
||||
msg_summary = _('Changed password for "%(value)s"')
|
||||
|
||||
def execute(self, principal, password):
|
||||
def execute(self, principal, password, current_password):
|
||||
"""
|
||||
Execute the passwd operation.
|
||||
|
||||
@@ -74,6 +98,7 @@ class passwd(Command):
|
||||
|
||||
:param principal: The login name or principal of the user
|
||||
:param password: the new password
|
||||
:param current_password: the existing password, if applicable
|
||||
"""
|
||||
ldap = self.api.Backend.ldap2
|
||||
|
||||
@@ -82,7 +107,16 @@ class passwd(Command):
|
||||
",".join([api.env.container_user, api.env.basedn])
|
||||
)
|
||||
|
||||
ldap.modify_password(dn, password)
|
||||
if principal == getattr(context, 'principal') and \
|
||||
current_password == MAGIC_VALUE:
|
||||
# No cheating
|
||||
self.log.warn('User attempted to change password using magic value')
|
||||
raise errors.ACIError(info='Invalid credentials')
|
||||
|
||||
if current_password == MAGIC_VALUE:
|
||||
ldap.modify_password(dn, password)
|
||||
else:
|
||||
ldap.modify_password(dn, password, current_password)
|
||||
|
||||
return dict(
|
||||
result=True,
|
||||
|
||||
Reference in New Issue
Block a user