mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Change random passwords behaviour
Improved options checking so that host-mod operation is not changing password for enrolled host when '--random' option is used. Unit tests added. https://fedorahosted.org/freeipa/ticket/2799 Updated set of characters that is used for generating random passwords for ipa hosts. All characters that might need escaping were removed. https://fedorahosted.org/freeipa/ticket/2800
This commit is contained in:
committed by
Martin Kosek
parent
3c36fa8c0d
commit
8ce7330c53
@@ -24,6 +24,7 @@ import sys
|
|||||||
from nss.error import NSPRError
|
from nss.error import NSPRError
|
||||||
import nss.nss as nss
|
import nss.nss as nss
|
||||||
import netaddr
|
import netaddr
|
||||||
|
import string
|
||||||
|
|
||||||
from ipalib import api, errors, util
|
from ipalib import api, errors, util
|
||||||
from ipalib import Str, Flag, Bytes
|
from ipalib import Str, Flag, Bytes
|
||||||
@@ -99,6 +100,10 @@ EXAMPLES:
|
|||||||
ipa host-add-managedby --hosts=test2 test
|
ipa host-add-managedby --hosts=test2 test
|
||||||
""")
|
""")
|
||||||
|
|
||||||
|
# Characters to be used by random password generator
|
||||||
|
# The set was chosen to avoid the need for escaping the characters by user
|
||||||
|
host_pwd_chars=string.digits + string.ascii_letters + '_,.@+-='
|
||||||
|
|
||||||
def remove_fwd_ptr(ipaddr, host, domain, recordtype):
|
def remove_fwd_ptr(ipaddr, host, domain, recordtype):
|
||||||
api.log.debug('deleting ipaddr %s' % ipaddr)
|
api.log.debug('deleting ipaddr %s' % ipaddr)
|
||||||
try:
|
try:
|
||||||
@@ -404,7 +409,7 @@ class host_add(LDAPCreate):
|
|||||||
if 'krbprincipal' in entry_attrs['objectclass']:
|
if 'krbprincipal' in entry_attrs['objectclass']:
|
||||||
entry_attrs['objectclass'].remove('krbprincipal')
|
entry_attrs['objectclass'].remove('krbprincipal')
|
||||||
if options.get('random'):
|
if options.get('random'):
|
||||||
entry_attrs['userpassword'] = ipa_generate_password()
|
entry_attrs['userpassword'] = ipa_generate_password(characters=host_pwd_chars)
|
||||||
# save the password so it can be displayed in post_callback
|
# save the password so it can be displayed in post_callback
|
||||||
setattr(context, 'randompassword', entry_attrs['userpassword'])
|
setattr(context, 'randompassword', entry_attrs['userpassword'])
|
||||||
cert = options.get('usercertificate')
|
cert = options.get('usercertificate')
|
||||||
@@ -596,7 +601,7 @@ class host_mod(LDAPUpdate):
|
|||||||
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
def pre_callback(self, ldap, dn, entry_attrs, attrs_list, *keys, **options):
|
||||||
# Allow an existing OTP to be reset but don't allow a OTP to be
|
# Allow an existing OTP to be reset but don't allow a OTP to be
|
||||||
# added to an enrolled host.
|
# added to an enrolled host.
|
||||||
if 'userpassword' in options:
|
if options.get('userpassword') or options.get('random'):
|
||||||
entry = {}
|
entry = {}
|
||||||
self.obj.get_password_attributes(ldap, dn, entry)
|
self.obj.get_password_attributes(ldap, dn, entry)
|
||||||
if not entry['has_password'] and entry['has_keytab']:
|
if not entry['has_password'] and entry['has_keytab']:
|
||||||
@@ -649,7 +654,7 @@ class host_mod(LDAPUpdate):
|
|||||||
entry_attrs['usercertificate'] = cert
|
entry_attrs['usercertificate'] = cert
|
||||||
|
|
||||||
if options.get('random'):
|
if options.get('random'):
|
||||||
entry_attrs['userpassword'] = ipa_generate_password()
|
entry_attrs['userpassword'] = ipa_generate_password(characters=host_pwd_chars)
|
||||||
setattr(context, 'randompassword', entry_attrs['userpassword'])
|
setattr(context, 'randompassword', entry_attrs['userpassword'])
|
||||||
if 'macaddress' in entry_attrs:
|
if 'macaddress' in entry_attrs:
|
||||||
if 'objectclass' in entry_attrs:
|
if 'objectclass' in entry_attrs:
|
||||||
|
|||||||
@@ -22,11 +22,15 @@
|
|||||||
Test the `ipalib.plugins.host` module.
|
Test the `ipalib.plugins.host` module.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import tempfile
|
||||||
|
from ipapython import ipautil
|
||||||
from ipalib import api, errors, x509
|
from ipalib import api, errors, x509
|
||||||
from ipalib.dn import *
|
from ipalib.dn import *
|
||||||
from tests.test_xmlrpc.xmlrpc_test import Declarative, fuzzy_uuid, fuzzy_digits
|
from nose.tools import raises, assert_raises
|
||||||
from tests.test_xmlrpc.xmlrpc_test import fuzzy_hash, fuzzy_date, fuzzy_issuer
|
from tests.test_xmlrpc.xmlrpc_test import (Declarative, XMLRPC_test,
|
||||||
from tests.test_xmlrpc.xmlrpc_test import fuzzy_hex
|
fuzzy_uuid, fuzzy_digits, fuzzy_hash, fuzzy_date, fuzzy_issuer,
|
||||||
|
fuzzy_hex)
|
||||||
from tests.test_xmlrpc import objectclasses
|
from tests.test_xmlrpc import objectclasses
|
||||||
import base64
|
import base64
|
||||||
|
|
||||||
@@ -740,3 +744,68 @@ class test_host(Declarative):
|
|||||||
),
|
),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
class test_host_false_pwd_change(XMLRPC_test):
|
||||||
|
|
||||||
|
fqdn1 = u'testhost1.%s' % api.env.domain
|
||||||
|
short1 = u'testhost1'
|
||||||
|
new_pass = u'pass_123'
|
||||||
|
|
||||||
|
command = "ipa-client/ipa-join"
|
||||||
|
[keytabfd, keytabname] = tempfile.mkstemp()
|
||||||
|
os.close(keytabfd)
|
||||||
|
|
||||||
|
# auxiliary function for checking whether the join operation has set
|
||||||
|
# correct attributes
|
||||||
|
def host_joined(self):
|
||||||
|
ret = api.Command['host_show'](self.fqdn1, all=True)
|
||||||
|
assert (ret['result']['has_keytab'] == True)
|
||||||
|
assert (ret['result']['has_password'] == False)
|
||||||
|
|
||||||
|
def test_a_join_host(self):
|
||||||
|
"""
|
||||||
|
Create a test host and join him into IPA.
|
||||||
|
"""
|
||||||
|
# create a test host with bulk enrollment password
|
||||||
|
random_pass = api.Command['host_add'](self.fqdn1, random=True, force=True)['result']['randompassword']
|
||||||
|
|
||||||
|
# joint the host with the bulk password
|
||||||
|
new_args = [self.command,
|
||||||
|
"-s", api.env.host,
|
||||||
|
"-h", self.fqdn1,
|
||||||
|
"-k", self.keytabname,
|
||||||
|
"-w", random_pass,
|
||||||
|
"-q",
|
||||||
|
]
|
||||||
|
try:
|
||||||
|
# join operation may fail on 'adding key into keytab', but
|
||||||
|
# the keytab is not necessary for further tests
|
||||||
|
(out, err, rc) = ipautil.run(new_args, None)
|
||||||
|
except ipautil.CalledProcessError, e:
|
||||||
|
pass
|
||||||
|
finally:
|
||||||
|
self.host_joined()
|
||||||
|
|
||||||
|
@raises(errors.ValidationError)
|
||||||
|
def test_b_try_password(self):
|
||||||
|
"""
|
||||||
|
Try to change the password of enrolled host with specified password
|
||||||
|
"""
|
||||||
|
api.Command['host_mod'](self.fqdn1, userpassword=self.new_pass)
|
||||||
|
|
||||||
|
@raises(errors.ValidationError)
|
||||||
|
def test_c_try_random(self):
|
||||||
|
"""
|
||||||
|
Try to change the password of enrolled host with random password
|
||||||
|
"""
|
||||||
|
api.Command['host_mod'](self.fqdn1, random=True)
|
||||||
|
|
||||||
|
def test_d_cleanup(self):
|
||||||
|
"""
|
||||||
|
Clean up test data
|
||||||
|
"""
|
||||||
|
os.unlink(self.keytabname)
|
||||||
|
api.Command['host_del'](self.fqdn1)
|
||||||
|
# verify that it's gone
|
||||||
|
with assert_raises(errors.NotFound):
|
||||||
|
api.Command['host_show'](self.fqdn1)
|
||||||
|
|||||||
Reference in New Issue
Block a user