--- /dev/null
+#!/usr/bin/perl
+
+# Copyright (c) 2010 Peter Palfrader
+
+# Resets the password for a kerberos principal given on the command line.
+# If the principal does not exist, try to create them.
+
+use strict;
+use Heimdal::Kadm5;
+use Getopt::Long;
+use English;
+use String::Random;
+
+my $USAGE = "Usage: $PROGRAM_NAME [--admin=<admin>] [--keytab=<file>] <principal>\n";
+
+sub getname() {
+ my $username = getpwuid($UID);
+ die "Cannot get current username\n" unless defined $username;
+ return $username;
+};
+
+my $params;
+Getopt::Long::config('bundling');
+GetOptions (
+ '--help' => \$params->{'help'},
+ '--admin=s' => \$params->{'admin'},
+ '--keytab=s' => \$params->{'keytab'},
+) or die ($USAGE);
+
+if ($params->{'help'}) {
+ print $USAGE;
+ exit (0);
+};
+
+die $USAGE if (scalar @ARGV != 1);
+my $name = shift @ARGV;
+
+unless (defined $params->{'admin'}) {
+ $params->{'admin'} = getname().'/admin';
+};
+unless (defined $params->{'keytab'}) {
+ $params->{'keytab'} = '/etc/userdir-ldap/keytab.'.getname();
+};
+
+my $client = Heimdal::Kadm5::Client->new(
+ Principal => $params->{'admin'},
+ Keytab => $params->{'keytab'}
+ );
+die "Unable to get Heimdal Client object.\n" unless defined $client;
+
+
+my $password = '844u6MrG0gTS';
+
+my $rnd = new String::Random;
+my $password = $rnd->randregex('[a-zA-Z0-9]{16}');
+
+my $principal = $client->getPrincipal($name);
+unless (defined $principal) {
+ print "Principal appears to not exist. Trying to add.\n";
+ $principal = $client->makePrincipal($name);
+ my $ret = $client->createPrincipal($principal, $password, undef);
+ die "Failed to create principal $name.\n" unless ($ret);
+ print "Created principal $name with password '$password'.\n";
+} else {
+ my $ret = $client->changePassword($name, $password);
+ die "Failed to change password for $name.\n" unless ($ret);
+ print "Changed password of principal $name to '$password'.\n";
+};
import userdir_gpg, userdir_ldap, sys, traceback, time, ldap, os, commands
import pwd, tempfile
+import subprocess
from userdir_gpg import *
from userdir_ldap import *
or GetAttr(Attrs[0],"userPassword").startswith("!"):
raise UDNotAllowedError, "This account is locked";
+ return l
+
# Handle an [almost] arbitary change
def HandleChange(Reply,DnRecord,Key):
global PlainText;
return Reply;
+def HandleChKrbPass(Reply,DnRecord,Key):
+ # Connect to the ldap server, will throw an exception if account locked.
+ l = connect_to_ldap_and_check_if_locked(DnRecord)
+
+ user = GetAttr(DnRecord,"uid")
+ krb_proc = subprocess.Popen( ('ud-krb-reset', user), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+ krb_proc.stdin.close()
+ out = krb_proc.stdout.readlines()
+ krb_proc.wait()
+ exitcode = krb_proc.returncode
+
+ # Use GPG to encrypt it
+ m = "Tried to reset your kerberos principal's password.\n"
+ if exitcode == 0:
+ m += "The exitcode of the reset script was zero, indicating that everything\n"
+ m += "worked. However, this being software who knows. Script's output below."
+ else:
+ m += "The exitcode of the reset script was %d, indicating that something\n"%(exitcode)
+ m += "went terribly, terribly wrong. Please consult the script's output below\n"
+ m += "for more information. Contact the admins if you have any questions or\n"
+ m += "require assitance."
+
+ m += "\n"+''.join( map(lambda x: "| "+x, out) )
+
+ Message = GPGEncrypt(m, "0x"+Key[1],Key[4]);
+ if Message == None:
+ raise UDFormatError, "Unable to generate the encrypted reply, gpg failed.";
+
+ Subst = {};
+ Subst["__FROM__"] = ChPassFrom;
+ Subst["__EMAIL__"] = EmailAddress(DnRecord);
+ Subst["__CRYPTTYPE__"] = get_crypttype_preamble(Key)
+ Subst["__PASSWORD__"] = Message;
+ Subst["__ADMIN__"] = ReplyTo;
+ Reply = Reply + TemplateSubst(Subst,open(TemplatesDir+"passwd-changed","r").read());
+
+ return Reply;
+
# Start of main program
# Drop messages from a mailer daemon.
if sys.argv[1] == "ping":
Reply = HandlePing(Reply,Attrs[0],pgp.key_info);
elif sys.argv[1] == "chpass":
- if PlainText.strip().find("Please change my Debian password"):
+ if PlainText.strip().find("Please change my Debian password") >= 0:
Reply = HandleChPass(Reply,Attrs[0],pgp.key_info);
+ elif PlainText.strip().find("Please change my Kerberos password") >= 0:
+ Reply = HandleChKrbPass(Reply,Attrs[0],pgp.key_info);
else:
raise UDFormatError,"Please send a signed message where the first line of text is the string 'Please change my Debian password' or some other string we accept here.";
elif sys.argv[1] == "change":