Use lastlog command to get last logins
authorJamie Cameron <jcameron@webmin.com>
Fri, 22 Jul 2011 17:31:24 +0000 (10:31 -0700)
committerJamie Cameron <jcameron@webmin.com>
Fri, 22 Jul 2011 17:31:24 +0000 (10:31 -0700)
useradmin/CHANGELOG
useradmin/linux-lib.pl
useradmin/user-lib.pl

index deec8b5..a6045f7 100644 (file)
@@ -68,3 +68,4 @@ Added support for SHA512 format passwords.
 Fixed an XSS vulnerability that can be triggered if an attacker has the ability to change the real name of a Unix user.
 ---- Changes since 1.550 ----
 Updated all links to users and groups to be by name instead of by index, to avoid incorrect links if the passwd or group files are changed manually or by another Webmin session.
+The faster lastlog command is now used to get the most recent login time on Linux, for display in the user list.
index 4fef69c..fa79561 100755 (executable)
@@ -43,6 +43,29 @@ while(1) {
        }
 }
 
+# os_most_recent_logins()
+# Returns hash ref from username to the most recent login as time string
+sub os_most_recent_logins
+{
+my %rv;
+open(LASTLOG, "LANG=C lastlog |");
+while(<LASTLOG>) {
+       s/\r|\n//g;
+       if (/^(\S+)/) {
+               my $user = $1;
+               if (/((\S+)\s+(\S+)\s+\d+\s+(\d+):(\d+):(\d+)\s+([\-\+]\d+)\s+(\d+))/) {
+                       # Have a date to parse
+                       $rv{$user} = $1;
+                       }
+               else {
+                       $rv{$user} = undef;
+                       }
+               }
+       }
+close(LASTLOG);
+return \%rv;
+}
+
 # logged_in_users()
 # Returns a list of hashes containing details of logged-in users
 sub logged_in_users
index b5e1ee9..f97d8e6 100755 (executable)
@@ -2301,11 +2301,11 @@ print &ui_columns_start([
        $text{'shell'},
        $lshow ? ( $text{'lastlogin'} ) : ( )
        ], 100, 0, \@tds);
-local %llogin;
+local $llogin;
 if ($lshow) {
-       local $l;
-       foreach $l (&list_last_logins()) {
-               $llogin{$l->[0]} ||= $l->[3];
+       $llogin = &get_recent_logins();
+       if (&foreign_check("mailboxes")) {
+               &foreign_require("mailboxes");
                }
        }
 local $u;
@@ -2320,7 +2320,17 @@ foreach $u (@$users) {
        push(@cols, &html_escape($u->{'real'}));
        push(@cols, &html_escape($u->{'home'}));
        push(@cols, &html_escape($u->{'shell'}));
-       push(@cols, &html_escape($llogin{$u->{'user'}})) if ($lshow);
+       if ($lshow) {
+               # Show last login, in local format after Unix time conversion
+               my $ll = $llogin->{$u->{'user'}};
+               if (defined(&mailboxes::parse_mail_date)) {
+                       my $tm = &mailboxes::parse_mail_date($ll);
+                       if ($tm) {
+                               $ll = &make_date($tm);
+                               }
+                       }
+               push(@cols, &html_escape($ll));
+               }
        if ($u->{'noedit'}) {
                print &ui_columns_row(\@cols, \@tds);
                }
@@ -2442,6 +2452,25 @@ close(LAST);
 return @rv;
 }
 
+=head2 get_recent_logins()
+
+Returns a hash ref from username to most recent login time/date
+
+=cut
+sub get_recent_logins
+{
+if (defined(&os_most_recent_logins)) {
+       return &os_most_recent_logins();
+       }
+else {
+       my %rv;
+       foreach my $l (&list_last_logins()) {
+               $rv{$l->[0]} ||= $l->[3];
+               }
+       return \%rv;
+       }
+}
+
 =head2 user_link(&user)
 
 Returns a link to a user editing form. Mainly for internal use.