scripts/func-change-password | 178 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 178 insertions(+) New commits: commit 931c9106cdf1fb75423d405544d129b524752dd3 Author: Seth Vidal <skvidal@xxxxxxxxxxxxxxxxx> Date: Wed Jun 1 21:38:16 2011 -0400 add func-change-password to scripts diff --git a/scripts/func-change-password b/scripts/func-change-password new file mode 100755 index 0000000..87f33a4 --- /dev/null +++ b/scripts/func-change-password @@ -0,0 +1,178 @@ +#!/usr/bin/python -tt +# seth vidal +# Copyright 2011, Red Hat, Inc +## +## This software may be freely redistributed under the terms of the GNU +## general public license. +## +## You should have received a copy of the GNU General Public License +## along with this program; if not, write to the Free Software +## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +import sys +import func.overlord.client +from func.overlord.scripts import errorprint + +from optparse import OptionParser +from func.utils import is_error +import crypt +import getpass +import tempfile +import os +import time + +def parse_args(args): + parser = OptionParser(version = "1.0") + parser.set_usage("func-change-password username") + parser.add_option('--host', default=[], action='append', + help="hosts to act on, defaults to ALL") + parser.add_option('--timeout', default=300, type='int', + help='set the wait timeout for func commands') + parser.add_option('--forks', default=40, type='int', + help='set the number of forks to start up') + parser.add_option('--grep-options', default='-n', dest='grep_options', + help='set options to pass to grep "-r -i" for example') + parser.add_option('--hosts-from-file', default=None, dest="hostfile", + help="read list of hosts from this file, if '-' read from stdin") + (opts, args) = parser.parse_args(args) + + + if opts.hostfile: + hosts = [] + if opts.hostfile == '-': + hosts = sys.stdin.readlines() + else: + hosts = open(opts.hostfile, 'r').readlines() + + for hn in hosts: + hn = hn.strip() + if hn.startswith('#'): + continue + hn = hn.replace('\n', '') + opts.host.append(hn) + + + return opts, args, parser + +def main(): + opts, args, parser = parse_args(sys.argv[1:]) + + if len(args) < 1: + print parser.format_help() + sys.exit(1) + + + hosts ='*' + if opts.host: + hosts = ';'.join(opts.host) + + username = args[0] + + print "Changing password on hosts for %s" % username + password = 'new' + password_re = 'new1' + while password != password_re: + # take the password for the user + password = getpass.getpass() + password_re = getpass.getpass("Confirm Password: ") + if password != password_re: + print "Passwords do not match!" + print "Trying again" + if password == '' or password_re == '': + print "Empty, aborting" + sys.exit(1) + + # generate salt + salt = '$6$' + ''.join(map(lambda x:'./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'[ord(x)%64], os.urandom(16))) + + # generate crypt + crypted = crypt.crypt(password, salt) + # write to tempfile + (pw_fd, pw_tmp) = tempfile.mkstemp(prefix='fcp', text=True) + pw_fo = os.fdopen(pw_fd, 'w') + pw_str = '%s:%s\n' % (username, crypted) + pw_fo.write(pw_str) + pw_fo.flush() + pw_fo.close() + + # send to hosts to specific location + fc = func.overlord.client.Client(hosts, timeout=opts.timeout, nforks=opts.forks) + source = pw_tmp + dest = "/root/fcp-%s" % time.strftime("%s") + print 'Sending changes to hosts' + results = fc.local.copyfile.send(source, dest) + # check results # copyfile fucking sucks - this needs something USEFUL + # any failures - take those out of the hosts and make a new fc connection + + # run chpasswd on the hosts sending that file to it + print "Changing passwords" + results = fc.command.run('cat %s | /usr/sbin/chpasswd -e' % dest) + # check results # + changed_on = [] + errors = {} + for (hn, output) in results.items(): + if is_error(output) or output[0] == 127: + + msg = 'Error: ' + for item in output[1:3]: + if type(item) == type(''): + msg += ' %s' % item + msg += '\n' + errors[hn] = msg + continue + + if output[0] != 0: + msg = 'Error: %s %s\n' % (output[0], output[1]) + errors[hn] = msg + continue + + changed_on.append(hn) + + # clean up + # rm the file from the hosts and rm it locally + print "Cleaning up" + + os.unlink(pw_tmp) + results = fc.command.run('/bin/rm -f %s' % dest) + for (hn, output) in results.items(): + if is_error(output) or output[0] == 127: + msg = 'Error: ' + for item in output[1:3]: + if type(item) == type(''): + msg += ' %s' % item + msg += '\n' + if msg == errors[hn]: + continue + else: + errors[hn] += msg + continue + + if output[0] != 0: + msg = 'Error: %s %s\n' % (output[0], output[1]) + if msg == errors[hn]: + continue + else: + errors[hn] += msg + continue + + + print "Password for %s changed on:" % username + for hn in sorted(changed_on): + print ' %s' % hn + + print "\n\nErrors from: " + for hn in errors: + print ' %s' % hn + print ' %s' % errors[hn] + + +if __name__ == "__main__": + try: + main() + except KeyboardInterrupt, e: + print "Exiting on user interrupt" + sys.exit(1) + + + + _______________________________________________ Func-list mailing list Func-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/func-list