]> eyrie.org Git - kerberos/kadmin-remctl.git/commitdiff
Added more support for account and password expiration
authorJon Robertson <jonrober@stanford.edu>
Wed, 26 May 2010 18:14:08 +0000 (11:14 -0700)
committerJon Robertson <jonrober@stanford.edu>
Wed, 26 May 2010 18:18:14 +0000 (11:18 -0700)
* Fixed bugs in the existing expiration command for Heimdal, and added
  it to the help command for both MIT and Heimdal.
* Added pwexpiration command that works like the expiration command, but
  for password expiration.
* Added check_expire command that will return expiration times in GMT
  for either account or password expiration.

The commands have been tested against Heimdal, though not yet against MIT.

kadmin-backend
kadmin-backend-heim

index 4bc9f74fd28ec5dd8c3e5b5a23589661bc17b67c..be0aac9b57feccac1b7dfe1edbad093ecf163b3a 100755 (executable)
@@ -28,6 +28,8 @@
 use strict;
 
 use Expect ();
+use POSIX;
+use Date::Parse;
 
 # Disable sending of kadmin's output to our standard output.
 $Expect::Log_Stdout = 0;
@@ -98,6 +100,9 @@ Kerberos administrative remctl help:
   kadmin disable <user>                         Disable <user> account
   kadmin enable <user>                          Enable <user> account
   kadmin examine <user>                         Show information for <user>
+  kadmin expiration <user> <date>               Set expiration for <user>
+  kadmin pwexpiration <user> <date>             Set expiration for <user>
+  kadmin check_expire <user> expire|pwexpire    Get account or pwd expire time
   kadmin instance check <user> <inst>           Whether <user>/<inst> exists
   kadmin instance create <user> <inst> <pass>   Create <user>/<inst> account
   kadmin instance delete <user> <inst>          Delete <user>/<inst> account
@@ -393,6 +398,67 @@ sub kadmin_expiration {
     }
 }
 
+# Change a principal's password expiration date using kadmin.
+sub kadmin_pwexpiration {
+    my ($principal, $instance, $expire) = @_;
+    check_principal ($principal, $instance);
+    kadmin_config ($instance) or return;
+    $principal = "$principal/$instance" if $instance;
+    my ($status, $output)
+        = run_k5admin ($instance,
+                       "modprinc -pwexpire \"$expire\" $principal");
+    if ($status != 0 || $output =~ /^modify_principal: /) {
+        $output =~ s/^modify_principal: //;
+        $output =~ s/\r?\n.*//;
+        warn "error: $output\n";
+        print "retstr: $output\n";
+        exit 1;
+    }
+}
+
+# Get a principal's expiration date or password expiration date using kadmin,
+# as a UTC date in the format: YYYY-MM-DD HH:MM:SSZ (with Z a literal Z).
+# Return '' if there is no expiration date set of the requested type.
+sub kadmin_expiration_check {
+    my ($principal, $instance, $type) = @_;
+    check_principal ($principal, $instance);
+    kadmin_config ($instance) or return;
+    $principal = "$principal/$instance" if $instance;
+    my ($status, $output)
+        = run_k5admin ($instance, "getprinc $principal");
+
+    # Parse out the two possible expire times.  We exit if we cannot find
+    # either, not checking to see if it the requested time -- that's
+    # potentially overkill, but does indicate that something's wrong.
+    my ($pwexpire, $expire) = (0, 0);
+    if ($output =~ /Password expiration date: (.*)/) {
+        $pwexpire = str2time ($1) unless $1 eq '[none]';
+    } else {
+        warn "error: could not find password expiration date\n";
+        exit 1;
+    }
+    if ($output =~ /Expiration date: (.*)/) {
+        $expire = str2time ($1) unless $1 eq '[never]';
+    } else {
+        warn "error: could not find expiration date\n";
+        exit 1;
+    }
+
+    # If no type was requested, return the soonest of the two dates.
+    if (!$type) {
+        $type = 'expire';
+        $type = 'pwexpire' if $pwexpire > $expire;
+    }
+
+    if ($type eq 'pwexpire' && $pwexpire > 0) {
+        return strftime ("%F %TZ", gmtime (str2time ($pwexpire)));
+    } elsif ($type eq 'expire' && $expire > 0) {
+        return strftime ("%F %TZ", gmtime (str2time ($expire)));
+    }
+
+    return '';
+}
+
 # The K5 kadmin interface doesn't support checking the strength of a password
 # without trying to change a password.  We therefore test the strength of a
 # password by changing the password of a designated special account (which is
@@ -1145,6 +1211,21 @@ if ($cmd eq 'change_passwd') {
 
     kadmin_expiration ($princ, '', $expiration);
 
+} elsif ($cmd eq 'pwexpiration') {
+
+    my $princ = shift or die "error: missing principal\n";
+    my $expiration = shift or die "error: missing expiration date\n";
+
+    kadmin_pwexpiration ($princ, '', $expiration);
+
+} elsif ($cmd eq 'check_expire') {
+
+    my $princ = shift or die "error: missing principal\n";
+    my $type = shift;
+
+    my $expire = kadmin_expiration_check ($princ, '', $type);
+    print $expire, "\n";
+
 } elsif ($cmd eq 'examine') {
 
     my $princ = shift or die "error: missing principal\n";
index 217bce7d42ebcc6b8d1603573cefbd3d632f1082..6ee17e60fa65a3f0a450ca4f0dd4021b4009c5cf 100755 (executable)
@@ -106,6 +106,8 @@ Kerberos administrative remctl help:
   kadmin enable <user>                          Enable <user> account
   kadmin examine <user>                         Show information for <user>
   kadmin expiration <user> <date>               Set expiration for <user>
+  kadmin pwexpiration <user> <date>             Set expiration for <user>
+  kadmin check_expire <user> expire|pwexpire    Get account or pwd expire time
   kadmin instance check <user> <inst>           Whether <user>/<inst> exists
   kadmin instance create <user> <inst> <pass>   Create <user>/<inst> account
   kadmin instance delete <user> <inst>          Delete <user>/<inst> account
@@ -324,7 +326,7 @@ sub kadmin_enable {
 sub kadmin_expiration {
     my ($principal, $instance, $expiration) = @_;
     check_principal ($principal, $instance);
-    kadmiN_config ($instance) or return;
+    kadmin_config ($instance) or return;
     $principal = "$principal/$instance" if $instance;
     my $expires = str2time ($expiration);
     unless (defined $expires) {
@@ -333,7 +335,7 @@ sub kadmin_expiration {
     }
 
     my $kadmin = kadmin_handle ($instance);
-    my $data = { $kadmin->getPrincipal ($principal) };
+    my $data = eval { $kadmin->getPrincipal ($principal) };
     if ($@) {
         warn "error: $@\n";
         exit 1;
@@ -351,6 +353,72 @@ sub kadmin_expiration {
     }
 }
 
+# Change a principal's password expiration date using kadmin.
+sub kadmin_pwexpiration {
+    my ($principal, $instance, $expiration) = @_;
+    check_principal ($principal, $instance);
+    kadmin_config ($instance) or return;
+    $principal = "$principal/$instance" if $instance;
+    my $expires = str2time ($expiration);
+    unless (defined $expires) {
+        warn "error: invalid expiration date $expiration\n";
+        exit 1;
+    }
+
+    my $kadmin = kadmin_handle ($instance);
+    my $data = eval { $kadmin->getPrincipal ($principal) };
+    if ($@) {
+        warn "error: $@\n";
+        exit 1;
+    } elsif (!defined $data) {
+        warn "error: principal $principal does not exist\n";
+        exit 1;
+    }
+    eval {
+        $data->setPwExpiration ($expires);
+        $kadmin->modifyPrincipal ($data);
+    };
+    if ($@) {
+        warn "error: $@\n";
+        exit 1;
+    }
+}
+
+# Get a principal's expiration date or password expiration date using kadmin,
+# as a UTC date in the format: YYYY-MM-DD HH:MM:SSZ (with Z a literal Z).
+# Return '' if there is no expiration date set of the requested type.
+sub kadmin_expiration_check {
+    my ($principal, $instance, $type) = @_;
+    $principal = "$principal/$instance" if $instance;
+
+    my $kadmin = kadmin_handle ($instance);
+    my $data = eval { $kadmin->getPrincipal ($principal) };
+    if ($@) {
+        warn "error: $@\n";
+        exit 1;
+    } elsif (!defined $data) {
+        warn "error: principal $principal does not exist\n";
+        exit 1;
+    }
+
+    my $expire = $data->getPrincExpireTime ();
+    my $pwexpire = $data->getPwExpiration ();
+
+    # If no type was requested, return the soonest of the two dates.
+    if (!$type) {
+        $type = 'expire';
+        $type = 'pwexpire' if $pwexpire < $expire;
+    }
+
+    if ($type eq 'pwexpire' && $pwexpire) {
+        return strftime ("%F %TZ", gmtime ($pwexpire));
+    } elsif ($type eq 'expire' && $expire) {
+        return strftime ("%F %TZ", gmtime ($expire));
+    }
+
+    return '';
+}
+
 # Reset a password via kadmin.
 sub kadmin_reset {
     my ($principal, $instance, $password) = @_;
@@ -1238,6 +1306,21 @@ if ($cmd eq 'change_passwd') {
 
     kadmin_expiration ($princ, '', $expiration);
 
+} elsif ($cmd eq 'pwexpiration') {
+
+    my $princ = shift or die "error: missing principal\n";
+    my $expiration = shift or die "error: missing expiration date\n";
+
+    kadmin_pwexpiration ($princ, '', $expiration);
+
+} elsif ($cmd eq 'check_expire') {
+
+    my $princ = shift or die "error: missing principal\n";
+    my $type = shift;
+
+    my $expire = kadmin_expiration_check ($princ, '', $type);
+    print $expire, "\n";
+
 } elsif ($cmd eq 'help') {
 
     print $HELP;