A.8. usermanager3.cgi

Das ist der (neue) Benutzermanager.

Dateiname: /usr/local/httpd/htdocs/admin/usermanager3.cgi.


#!/usr/bin/perl -wT

#   usermanager
#
#   Copyright (c) 2001 Thomas Bleher <ThomasBleher@gmx.de>
#   Copyright (c) 2002,2003 Andreas Dangel <adabolo@adabolo.de>
#
#   This program is free software; you can redistribute it and/or modify
#   it under the terms of the GNU General Public License as published by
#   the Free Software Foundation; either version 2 of the License, or
#   (at your option) any later version.
#
#   This program is distributed in the hope that it will be useful,
#   but WITHOUT ANY WARRANTY; without even the implied warranty of
#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#   GNU General Public License for more details.
#
#   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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#

use strict;
use CGI;
use User::pwent;
use CGI::Carp qw(fatalsToBrowser);

# =============================================================================
#                        KONFIGURATION
# =============================================================================
my $user_status_script = "sudo /usr/local/sbin/user-status3";
$ENV{"PATH"} = "/bin:/usr/bin";

# =============================================================================
#                         GLOBALE VARIABLEN
# =============================================================================
my $q;          # für CGI
my @users;      # speichert die ausgewählten Benutzer (login-names)
my $this_script;
my $now_time_string = localtime;
my $error = "";

# =============================================================================
#                          SUBS
# =============================================================================
sub main;
sub print_header;
sub print_seite0;
sub print_page_end;
sub print_page_data;
sub get_userlist;

######
main;
exit 0;
######

# =============================================================================
#                          MAIN
# =============================================================================
sub main {
  $q = new CGI;

  $this_script = $q->url();

  # wurden Daten gesendet?
  if ($q->param) {
    #&print_header("Parameter vorhanden!");
    #print $q->Dump;
    #&print_page_end;

    if (defined($q->param("user"))) {
      &print_user_data($q->param("user"));
    } elsif ($q->param("seite") == 0) {
      &print_page_data;
    } elsif ($q->param("seite") == 1) {
      if (defined($q->param("action"))) {
        if ($q->param("action") eq "lock") {
          &do_lock_users;
        } elsif ($q->param("action") eq "pw") {
          &ask_pw_users;
        } elsif ($q->param("action") eq "rights") {
          &ask_rights_users;
        } elsif ($q->param("action") eq "delete") {
          &ask_delete_users;
        }
      } else {
        $error = "Falscher Befehl!";
        &print_page_data;
      }
    } elsif ($q->param("seite") == 2) {
      &do_pw_users;
    } elsif ($q->param("seite") == 3) {
      &do_rights_users;
    } elsif ($q->param("seite") == 4) {
      &do_delete_users;
    } elsif ($q->param("seite") == 5) {
      &do_save_user_data;
    }

  } else {
    &print_seite0;
  }

}


# =============================================================================
#                           PRINT_HEADER
# =============================================================================
sub print_header {
  my $title = shift;
  print $q->header;
  print qq(<html>\n);
  print qq(<head>\n);
  print qq(  <title>$title</title>\n);
  print qq(</head>\n);
  print qq(<body>\n);
  print qq(<h1>$title</h1>\n);
}


# =============================================================================
#                             PRINT_SEITE0
# =============================================================================
sub print_seite0 {
  &print_header("Benutzermanager");

  print qq(<form method="post">\n);
  print qq(<h3>Welche Benutzer sollen angezeigt werden?</h3>\n);
  print qq(<input type="radio" name="auswahl" value="alle" checked>Alle<br>\n);
  print qq(<input type="radio" name="auswahl" value="passwort">Nur Benutzer,
                die als Passwort "passwort" haben<br>\n);
  print qq(<input type="radio" name="auswahl" value="gesperrt">Nur gesperrte
                Benutzer<br>\n);
  print qq(<input type="radio" name="auswahl" value="aktiv">Nur aktivierte
                Benutzer<br>\n);
  print qq(<input type="radio" name="auswahl" value="jahrgang">Nur bestimmter
                Abi-Jahrgang (nur Schüler):\n);
  print qq(  <input type="text" name="abijahr" value="" size="2"
                maxlength="2"><br>\n);
  print qq(<input type="radio" name="auswahl" value="gruppen">Nur bestimmte
                Gruppen:\n);
  print qq(  <input type="checkbox" name="gruppe_schueler">Schüler\n);
  print qq(  <input type="checkbox" name="gruppe_lehrer">Lehrer\n);
  print qq(  <input type="checkbox" name="gruppe_internet">Internet\n);
  print qq(  <input type="checkbox" name="gruppe_admin">Administratoren\n);
  print qq(  <input type="checkbox" name="gruppe_homepage">Homepage<br>\n);
  print qq(<input type="radio" name="auswahl" value="name">Bestimmter
                Benutzer:\n);
  print qq(  <input type="text" name="loginname" value="" size="15">\n);
  print qq(<p>\n);
  print qq(<input type="hidden" name="seite" value="0">\n);
  print qq(<input type="submit" value="Anfrage starten..."\n);
  print qq(</form>\n);
  &print_page_end;
}

# =============================================================================
#                           PRINT_PAGE_END
# =============================================================================
sub print_page_end {
  print qq(<hr>\n);
  print qq(<a href="http://server/">zur Startseite</a>\n);
  print qq( - <a href="http://server/admin/">Administration</a>\n);
  print qq( - <a href="$this_script">Benutzermanager</a>\n);
  print qq( - $now_time_string\n);
  #print qq( - <i>&copy; adabolo.de network solutions</i>\n);
  print qq(</body>\n);
  print qq(</html>\n);
}

# =============================================================================
#                             PRINT_PAGE_DATA
# =============================================================================
sub print_page_data {
  &print_header("Benutzermanager");

  if ($error ne "") {
    print qq(<font color="green">$error</font>\n);
  }

  my @userlist = &get_userlist;
  my $anzahl = @userlist;

  # Benutzerliste sortieren...
  my @sorted = sort {
    my $c = $a;
    my $d = $b;

    # Lehrer:
    if ($c =~ m/\A(\w)\.([\w\-]+)\Z/) { $c = "000.$2.$1." };
    if ($d =~ m/\A(\w)\.([\w\-]+)\Z/) { $d = "000.$2.$1." };
    # Sonstige:
    if ($c =~ m/\Abo\.vhs(\d\d)\Z/)   { $c = "EEE.bo.vhs.$1." };
    if ($d =~ m/\Abo\.vhs(\d\d)\Z/)   { $d = "EEE.bo.vhs.$1." };
    if ($c =~ m/\Abl\.vhs(\d+)\Z/)    { $c = "FFF.bl.vhs.$1." };
    if ($d =~ m/\Abl\.vhs(\d+)\Z/)    { $d = "FFF.bl.vhs.$1." };
    if ($c =~ m/\Akghs(\d+)\Z/)       { $c = "GGG.kghs.$1." };
    if ($d =~ m/\Akghs(\d+)\Z/)       { $d = "GGG.kghs.$1." };
    if ($c =~ m/\Abo\.kgrt(\d+)\Z/)   { $c = "HHH.bo.kgrt.$1." };
    if ($d =~ m/\Abo\.kgrt(\d+)\Z/)   { $d = "HHH.bo.kgrt.$1." };
    # Schüler
    if ($c =~ m/\A(\w)(\w+)(\d\d)\Z/) { $c = "AAA.$3.$2.$1." };
    if ($d =~ m/\A(\w)(\w+)(\d\d)\Z/) { $d = "AAA.$3.$2.$1." };

    $c cmp $d;
  } @userlist;

  # JavaScript Programm:
  print qq(\n<script type="text/javascript" language="javascript">\n);
  print qq(function mark_all() {\n);
  print qq(  var b = window.document.forms[0].checker.checked;\n);
  print qq(  var count = 0;\n);
  print qq(  while (count < $anzahl) {\n);
  print qq(    window.document.forms[0].elements[count++].checked = b;\n);
  print qq(  }\n);
  print qq(}\n);
  print qq(</script>\n\n);

  # Formular starten
  print $q->start_form;
  # Tabelle starten
  print qq(<table border="1">\n);
  print qq(<tr><th>Login</th><th>Name</th><th>Gruppen (Rechte)</th>);
  print qq(<th>Quota</th><th>"passwort" (letzte Änderung)</th><th>Status</th>);
  print qq(<th>Auswahl</th></tr>\n);

  foreach (@sorted) {
    my $login = $_;
    my $name = &get_fullname($_);
    my $gruppen = &get_groups($_);
    my $quota = &get_quota($_);
    my $passwort = &get_password($_);
    my $status = &get_status($_);

    my $color = "#FFFFDD";

    if ($passwort =~ m/JA/) {
      $color = "#FF0000";
    }
    if ($status eq "deaktiviert") {
      $color = "#EEEEEE";
    }

    print qq(<tr bgcolor="$color">);
    print qq(<td><a href="$this_script?user=$_">$_</a></td>);
    print qq(<td>$name</td>);
    print qq(<td>$gruppen</td>);
    print qq(<td>$quota</td>);
    print qq(<td>$passwort</td>);
    print qq(<td>$status</td>);
    print qq(<td><input type="checkbox" name="users" value="$_"></td></tr>\n);
  }

  print qq(<tr><td align="right" colspan="6">Alle angezeigten
            Benutzer markieren:</td>);
  print qq(<td><input type="checkbox" name="checker" onclick="mark_all();">
            </td></tr>\n);
  print qq(</table>\n);
  print qq(Angezeigte Benutzer: $anzahl\n);
  print qq(<p>\n);

  print qq(<h2>Aktion</h2>\n);
  print qq(<input type="radio" name="action" value="lock">Benutzer
            sperren/freigeben<br>\n);
  print qq(<input type="radio" name="action" value="pw">Passwort ändern<br>\n);
  print qq(<input type="radio" name="action" value="rights">Rechte
            ändern<br>\n);
  print qq(<input type="radio" name="action" value="delete">Benutzer
            löschen<br>\n);
  print qq(<input type="hidden" name="seite" value="1">\n);

  &print_seite1_values;

  print qq(<input type="submit" value="Ausführen"> <input type="reset"
            value="Abbrechen">\n);

  print qq(</form>\n);

  &print_page_end;
}

# =============================================================================
#                             GET_USERLIST
# =============================================================================
sub get_userlist {
  my @users = split / /, (getgrnam('users'))[3];

  if ($q->param("auswahl") eq "alle") {
    return @users;
  } elsif ($q->param("auswahl") eq "passwort") {
    my @userlist = qw();
    foreach (@users) {
      # für jeden Benutzer prüfen, ob "passwort" das Passwort ist...
      # das Script gibt den Benutzernamen zurück, wenn das Passwort
      # unsicher ist. Es gibt "---secure" zurück, wenn das Passwort
      # sicher ist.
      my $ret = `$user_status_script -passwd $_`;
      if ($ret ne "---secure") {
        push(@userlist, $_);
      }
    }
    return @userlist;
  } elsif ($q->param("auswahl") eq "gesperrt") {
    my @userlist = qw();
    foreach (@users) {
      # für jeden Benutzer prüfen, ob er gesperrt ist...
      my $ret = `$user_status_script -locked $_`;
      if ($ret ne "---unlocked") {
        push(@userlist, $_);
      }
    }
    return @userlist;
  } elsif ($q->param("auswahl") eq "aktiv") {
    my @userlist = qw();
    foreach (@users) {
      # für jeden Benutzer prüfen, ob er "unlocked" ist...
      my $ret = `$user_status_script -locked $_`;
      if ($ret eq "---unlocked") {
        push(@userlist, $_);
      }
    }
    return @userlist;
  } elsif ($q->param("auswahl") eq "jahrgang") {
    # erst Abi-Jahrgang herausfinden
    my $abi = $q->param("abijahr");
    # keine zwei Ziffern?
    if ($abi !~ m/\d\d/) {
      # dann alle Benutzer anzeigen...
      return @users;
    }
    # jeden Benutzer durchgehen und in @userlist speichern
    my @userlist = qw();
    foreach (@users) {
      if ($_ =~ m/\w+$abi/) {
        push(@userlist, $_);
      }
    }
    return @userlist;
  } elsif ($q->param("auswahl") eq "gruppen") {
    # wenn gar nichts gewählt...
    if ($q->param("gruppe_schueler") ne "on" &&
        $q->param("gruppe_lehrer") ne "on" &&
        $q->param("gruppe_internet") ne "on" &&
        $q->param("gruppe_admin") ne "on" &&
        $q->param("gruppe_homepage") ne "on") {
      return @users;
    }
    my %userlist;

    my @group_users;

    if ($q->param("gruppe_schueler") eq "on") {
      @group_users = split / /, (getgrnam('schueler'))[3];
      foreach (@group_users) { $userlist{$_} = 1; }
    }
    if ($q->param("gruppe_lehrer") eq "on") {
      @group_users = split / /, (getgrnam('lehrer'))[3];
      foreach (@group_users) { $userlist{$_} = 1; }
    }
    if ($q->param("gruppe_internet") eq "on") {
      @group_users = split / /, (getgrnam('internet'))[3];
      foreach (@group_users) { $userlist{$_} = 1; }
    }
    if ($q->param("gruppe_admin") eq "on") {
      @group_users = split / /, (getgrnam('admin'))[3];
      foreach (@group_users) { $userlist{$_} = 1; }
    }
    if ($q->param("gruppe_homepage") eq "on") {
      @group_users = split / /, (getgrnam('homepage'))[3];
      foreach (@group_users) { $userlist{$_} = 1; }
    }

    return keys(%userlist);
  } elsif ($q->param("auswahl") eq "name") {
    my $login = $q->param("loginname");
    $login = quotemeta($login);
    return grep(/$login/, @users);
  } else {
    # in sonstigen Fällen, die eigentlich nicht auftreten sollten:
    # Alle Benutzer anzeigen...
    return @users;
  }
}

# =============================================================================
#                      GET_FULLNAME
# =============================================================================
sub get_fullname {
  my $login = shift;
  my $user = getpwnam($login);
  return $user->gecos;
}

# =============================================================================
#                      GET_HOMEDIR
# =============================================================================
sub get_homedir {
  my $login = shift;
  my $user = getpwnam($login);
  return $user->dir;
}

# =============================================================================
#                       GET_SHELL
# =============================================================================
sub get_shell {
  my $login = shift;
  my $user = getpwnam($login);
  return $user->shell;
}

# =============================================================================
#                       GET_GROUPS
# =============================================================================
sub get_groups {
  my $login = shift;

  # untaint
  $login =~ m/([\w\.\-]+)/;
  $login = $1;

  my $groups = `id -nG $login`;
  return $groups;
}

# =============================================================================
#                        GET_PASSWORD
# =============================================================================
sub get_password {
  my $login = shift;
  my $ret = `$user_status_script -passwd $login`;
  my $answer = "";
  if ($ret eq "---secure") {
    $answer .= "nein ";
  } else {
    $answer .= "JA ";
  }

  $answer .= "(" . `$user_status_script -change $login` . ")";

  return $answer;
}

# =============================================================================
#                            GET_STATUS
# =============================================================================
sub get_status {
  my $login = shift;

  # untaint
  $login =~ m/([\w\.\-]+)/;
  $login = $1;

  my $ret = `$user_status_script -locked $login`;
  if ($ret eq "---unlocked") {
    return "aktiviert";
  } else {
    return "deaktiviert";
  }
}

# =============================================================================
#                          GET_QUOTA
# =============================================================================
sub get_quota {
  my $login = shift;

  # untaint
  $login =~ m/([\w\.\-]+)/;
  $login = $1;

  my $ret = `$user_status_script -quota $login`;
  return $ret;
}


# =============================================================================
#                           PRINT_USER_DATA
# =============================================================================
sub print_user_data {
  my $login = shift;

  # untaint
  $login =~ m/([\w\.\-]+)/;
  $login = $1;

  &print_header("Benutzermanager - $login");

  my $fullname = &get_fullname($login);
  my $homedir = &get_homedir($login);
  my $shell = &get_shell($login);
  my $rights = &get_groups($login);
  my $quota = &get_quota($login);
  $quota =~ m/(\d+)\/(\d+)/;
  my $quota_used = $1;
  my $quota_limit = $2;
  my $status = &get_status($login);
  my $change = `$user_status_script -change $login`;



  print $q->start_form;
  print qq(<table border="0">\n);
  print qq(<tr><td><b>Login</b></td><td>$login</td></tr>\n);
  print qq(<tr><td><b>Homeverzeichnis</b></td><td>$homedir</td></tr>\n);
  print qq(<tr><td><b>Shell</b></td><td>$shell</td></tr>\n);
  print qq(<tr><td><b>Name</b></td><td><input type="text" name="fullname"
            value="$fullname"></td></tr>\n);


  print qq(<tr><td><b>Gruppen</b></td><td>);
  print qq(<input type="checkbox" name="rights" value="schueler");
  print qq( checked) if ($rights =~ m/schueler/);
  print qq(>Schüler );
  print qq(<input type="checkbox" name="rights" value="lehrer");
  print qq( checked) if ($rights =~ m/lehrer/);
  print qq(>Lehrer );
  print qq(<input type="checkbox" name="rights" value="internet");
  print qq( checked) if ($rights =~ m/internet/);
  print qq(>Internet );
  print qq(<input type="checkbox" name="rights" value="admin");
  print qq( checked) if ($rights =~ m/admin/);
  print qq(>Administratoren );
  print qq(<input type="checkbox" name="rights" value="homepage");
  print qq( checked) if ($rights =~ m/homepage/);
  print qq(>Homepage );
  print qq(</td></tr>\n);

  print qq(<tr><td><b>Quota</b></td><td>);
  print qq($quota_used / <input type="text" size="4" value="$quota_limit"
            name="quota"> MB);
  print qq(</td></tr>\n);

  print qq(<tr><td><b>Status</b></td><td>);
  print qq(<input type="radio" name="lock" value="gesperrt");
  print qq( checked) if ($status eq "deaktiviert");
  print qq(>gesperrt );
  print qq(<input type="radio" name="lock" value="freigegeben");
  print qq( checked) if ($status eq "aktiviert");
  print qq(>freigegeben );
  print qq(</td></tr>\n);

  print qq(<tr><td><b>Passwort</b></td><td>);
  print qq(<input type="password" name="passwort" value="">);
  print qq( \(Letzte Änderung: $change\));
  print qq(</td></tr>\n);

  print qq(</table>\n);

  print qq(<input type="submit" name="save" value="speichern">\n);
  print qq(<input type="submit" name="abort" value="abbrechen">\n);

  print qq(<input type="hidden" name="edit_user" value="$login">\n);
  print qq(<input type="hidden" name="seite" value="5">\n);
  #&print_seite1_values;
  print qq(<input type="hidden" name="auswahl" value="name">\n);
  print qq(<input type="hidden" name="loginname" value="$login">\n);

  print qq(</form>\n);

  &print_page_end;
}

# =============================================================================
#                         DO_LOCK_USERS
# =============================================================================
sub do_lock_users {
  my @users = qw();
  if (defined($q->param("users"))) {
    @users = $q->param("users");
  } else {
    $error = "<strong>Fehler:</strong> Keine Benutzer ausgewählt!";
    return;
  }

  $error = "Folgende Benutzer wurden gesperrt bzw. freigegeben:<br>\n<b>";

  foreach (@users) {
    my $login = $_;

    # untaint
    $login =~ m/([\w\.\-]+)/;
    $login = $1;

    my $status = &get_status($login);
    if ($status eq "aktiviert") {
      # sperre Benutzer $login
      `sudo /usr/bin/passwd -l $login`;
      fehler("Benutzer sperren (passwd) [$login]") if ($? != 0);
      `sudo /usr/bin/smbpasswd -d $login`;
      fehler("Benutzer sperren (smbpasswd) [$login]") if ($? != 0);
    } else {
      # Gebe Benutzer $login frei
      `sudo /usr/bin/passwd -u $login`;
      fehler("Benutzer freigeben (passwd) [$login]") if ($? != 0);
      `sudo /usr/bin/smbpasswd -e $login`;
      fehler("Benutzer freigeben (smbpasswd) [$login]") if ($? != 0);
    }

    $error .= "$_ ";
  }

  $error .= "</b>";

  `sudo /usr/local/sbin/generate_apache_auth`;


  &print_page_data;
}

# =============================================================================
#                     ASK_PW_USERS
# =============================================================================
sub ask_pw_users {
  my @users = qw();
  if (defined($q->param("users"))) {
    @users = $q->param("users");
  } else {
    $error = "<strong>Fehler:</strong> Keine Benutzer ausgewählt!";
    &print_page_data;
    return;
  }

  &print_header("Benutzermanager - Passwort ändern");

  print qq(Von folgenden Benutzern soll das Passwort geändert werden: <b>);
  print join(" ", @users);
  print qq(</b>\n<p>\n);

  print $q->start_form;
  print qq(Bitte geben Sie das neue Passwort ein:\n);
  print qq(<input type="password" name="password" size="8" maxlength="8"
            value="passwort">\n);

  print qq(<input type="hidden" name="seite" value="2">\n);
  foreach (@users) {
    print qq(<input type="hidden" name="users" value="$_">\n);
  }
  &print_seite1_values;

  print qq(<p>);
  print qq(<input type="submit" name="do_it" value="Passwort ändern">\n);
  print qq(<input type="submit" name="abort" value="Abbrechen">\n);
  print qq(</form>\n);

  &print_page_end;

}

# =============================================================================
#           PRINT_SEITE1_VALUES
# =============================================================================
sub print_seite1_values {
  print qq(<input type="hidden" name="auswahl" value=");
  print $q->param("auswahl");
  print qq(">\n);
  print qq(<input type="hidden" name="loginname" value=");
  print $q->param("loginname");
  print qq(">\n);
  print qq(<input type="hidden" name="abijahr" value=");
  print $q->param("abijahr");
  print qq(">\n);
  print qq(<input type="hidden" name="gruppe_schueler" value=");
  print $q->param("gruppe_schueler");
  print qq(">\n);
  print qq(<input type="hidden" name="gruppe_lehrer" value=");
  print $q->param("gruppe_lehrer");
  print qq(">\n);
  print qq(<input type="hidden" name="gruppe_internet" value=");
  print $q->param("gruppe_internet");
  print qq(">\n);
  print qq(<input type="hidden" name="gruppe_admin" value=");
  print $q->param("gruppe_admin");
  print qq(">\n);
  print qq(<input type="hidden" name="gruppe_homepage" value=");
  print $q->param("gruppe_homepage");
  print qq(">\n);
}

# =============================================================================
#                      DO_PW_USERS
# =============================================================================
sub do_pw_users {
  my @users = $q->param("users");
  my $password = $q->param("password");

  if (defined($q->param("abort"))) {
    &print_page_data;
    return;
  }

  #untaint
  $password =~ m/([-\w#*,;:.+!$%&\/|?{\[()\]}]+)/;
  $password = $1;

  my $enc_pw = crypt($password,
            join("", (".", "/", 0..9, "a".."z", "A".."Z")[rand 64, rand 64]));

  $error = "Von folgenden Benutzern wurde das Passwort geändert:<br>\n<b>";

  foreach (@users) {
    my $login = $_;

    #untaint
    $login =~ m/([\w\.\-]+)/;
    $login = $1;

    `sudo /usr/sbin/usermod -p $enc_pw $login`;
    fehler("Passwortänderung (usermod) [$login]") if ($? != 0);

    open PIPE, "| sudo /usr/bin/smbpasswd -s $login > /dev/null"
        or fehler("Passwortänderung (pipe open) [$login]");
    print PIPE "$password\n$password\n"
        or fehler("Passwortänderung (pipe write) [$login]");
    close PIPE
        or fehler("Passwortänderung (pipe close) [$login]");

    $error .= "$login ";
  }

  $error .= "</b>";

  `sudo /usr/local/sbin/generate_apache_auth`;

  &print_page_data;
}

# =============================================================================
#                     ASK_RIGHTS_USERS
# =============================================================================
sub ask_rights_users {
  my @users = qw();
  if (defined($q->param("users"))) {
    @users = $q->param("users");
  } else {
    $error = "<strong>Fehler:</strong> Keine Benutzer ausgewählt!";
    &print_page_data;
    return;
  }

  &print_header("Benutzermanager - Rechteänderung");

  print qq(Von folgenden Benutzern sollen die Rechte geändert werden: <b>);
  print join(" ", @users);
  print qq(</b>\n<p>\n);

  print $q->start_form;
  print qq(<h2>Rechte</h2>\n);
  print qq(<input type="checkbox" name="rights" value="schueler">Schüler<br>\n);
  print qq(<input type="checkbox" name="rights" value="lehrer">Lehrer<br>\n);
  print qq(<input type="checkbox" name="rights" value="internet">Internet
            <br>\n);
  print qq(<input type="checkbox" name="rights" value="admin">Administratoren
            <br>\n);
  print qq(<input type="checkbox" name="rights" value="homepage">Homepage
            <br>\n);
  print qq(Quota (0 = unbegrenzt): <input type="text" name="quota" value="50"
            size="4">MB<br>\n);

  print qq(<input type="hidden" name="seite" value="3">\n);
  foreach (@users) {
    print qq(<input type="hidden" name="users" value="$_">\n);
  }
  &print_seite1_values;

  print qq(<p>);
  print qq(<input type="submit" name="do_it" value="Rechte ändern">\n);
  print qq(<input type="submit" name="abort" value="Abbrechen">\n);
  print qq(</form>\n);

  &print_page_end;

}

# =============================================================================
#                      DO_RIGHTS_USERS
# =============================================================================
sub do_rights_users {
  my @users = $q->param("users");

  if (defined($q->param("abort"))) {
    $error = "Abbruch!";
    &print_page_data;
    return;
  }

  # Rechte sammeln und überprüfen
  my @new_rights;
  push(@new_rights, "users");

  my @rights = $q->param("rights");
  foreach (@rights) {
    push(@new_rights, "schueler") if ($_ eq "schueler");
    push(@new_rights, "lehrer") if ($_ eq "lehrer");
    push(@new_rights, "internet") if ($_ eq "internet");
    push(@new_rights, "admin") if ($_ eq "admin");
    push(@new_rights, "homepage") if ($_ eq "homepage");
  }

  my $rights_string = join(",", @new_rights);

  # Quota
  $q->param("quota") =~ m/(\d+)/;
  my $quota = $1 * 1024; # Anzahl der KB-Blöcke

  # Shell
  my $shell = "/bin/false";
  if ($rights_string =~ m/admin/) {
    $shell = "/bin/bash";
  }

  $error = "Von folgenden Benutzern wurden die Rechte auf <i>$rights_string</i>
            geändert:<br>\n<b>";

  foreach (@users) {
    my $login = $_;

    #untaint
    $login =~ m/([\w\.\-]+)/;
    $login = $1;

    `sudo /usr/sbin/usermod -s $shell -G $rights_string,$login $login`;
    fehler("Rechteänderung (usermod) [$login]") if ($? != 0);
    `sudo /usr/sbin/setquota $login $quota $quota 0 0 /dev/md0`;
    fehler("Rechteänderung (setquota) [$login]") if ($? != 0);

    $error .= "$login ";
  }

  $error .= "</b>\n";

  `sudo /usr/local/sbin/generate_apache_auth`;

  &print_page_data;
}

# =============================================================================
#                     ASK_DELETE_USERS
# =============================================================================
sub ask_delete_users {
  my @users = qw();
  if (defined($q->param("users"))) {
    @users = $q->param("users");
  } else {
    $error = "<strong>Fehler:</strong> Keine Benutzer ausgewählt!";
    &print_page_data;
    return;
  }

  &print_header("Benutzermanager - Benutzer löschen");

  print qq(<font color="red"><b>ACHTUNG!</b></font> Folgende Benutzer werden
                gelöscht: <b>);
  print join(" ", @users);
  print qq(</b>\n<p>\n);

  print qq(Auch die Homeverzeichnisse und alle persönlichen Daten werden
            gelöscht );
  print qq(und <strong>können nicht wiederhergestellt werden</strong>. Nur
            die );
  print qq(<tt>public_html</tt>-Verzeichnisse bleiben erhalten.<p>\n);

  print qq(Wollen Sie wirklick fortfahren?<p>\n);

  print $q->start_form;
  print qq(<input type="hidden" name="seite" value="4">\n);
  foreach (@users) {
    print qq(<input type="hidden" name="users" value="$_">\n);
  }
  &print_seite1_values;

  print qq(<p>);
  print qq(<input type="submit" name="do_it" value="Benutzer löschen!">\n);
  print qq(<input type="submit" name="abort" value="Abbrechen">\n);
  print qq(</form>\n);

  &print_page_end;

}

# =============================================================================
#                      DO_DELETE_USERS
# =============================================================================
sub do_delete_users {
  my @users = $q->param("users");

  if (defined($q->param("abort"))) {
    $error = "Abbruch!";
    &print_page_data;
    return;
  }


  $error = "Folgende Benutzer wurden gelöscht:<br>\n<b>";

  foreach (@users) {
    my $login = $_;

    #untaint
    $login =~ m/([\w\.\-]+)/;
    $login = $1;

    # Samba-User löschen
    `sudo /usr/bin/smbpasswd -x $login`;
    fehler("Benutzer löschen (smbpasswd) [$login]") if ($? != 0);
    # public_html-Verzeichnis verschieben
    `sudo /bin/mv /home/public_html/$login /usr/local/httpd/htdocs/oldhomes/`;
    fehler("Benutzer löschen (move public_html) [$login]") if ($? != 0);
   `sudo /bin/chown -hfR root:www-data /usr/local/httpd/htdocs/oldhomes/$login`;
    fehler("Benutzer löschen (chown public_html) [$login]") if ($? != 0);
    `sudo /bin/chmod -R 755 /usr/local/httpd/htdocs/oldhomes/$login`;
    fehler("Benutzer löschen (chmod public_html) [$login]") if ($? != 0);
    # Benutzer und Homeverzeichnis löschen
    `sudo /usr/sbin/userdel -r $login`;
    fehler("Benutzer löschen (userdel) [$login]") if ($? != 0);
    `sudo /usr/sbin/groupdel $login`;
    fehler("Benutzer löschen (groupdel) [$login]") if ($? != 0);

    $error .= "$login ";
  }

  $error .= "</b>\n";

  `sudo /usr/local/sbin/generate_apache_auth`;

  &print_page_data;
}

# =============================================================================
#                  FEHLER
# =============================================================================
sub fehler {
  my $text = shift;

  $error .= qq(<p><font color="red"><big><strong>Schwerwiegender Fehler:
                </strong></big> $text</font>);

  `sudo /usr/local/sbin/generate_apache_auth`;

  &print_page_data;
  exit 1;
}

# =============================================================================
#                   DO_SAVE_USER_DATA
# =============================================================================
sub do_save_user_data {
  if (defined($q->param("abort"))) {
    $error = "Abbruch!";
    &print_page_data;
    return;
  }

  my $login = $q->param("edit_user");

  # untaint
  $login =~ m/([\w\.\-]+)/;
  $login = $1;

  my $fullname;
  my $rights;
  my $quota;
  my $status;

  if (defined($q->param("fullname"))) {
    $fullname = $q->param("fullname");

    #untaint
    $fullname =~ m/([\w\.\ ,äöüÄÖÜ\-*#']+)/;
    $fullname = $1;

    `sudo /usr/sbin/usermod -c "$fullname" $login`;
    fehler("Benutzer ändern, Name (usermod) [$login]") if ($? != 0);
  }


  if (defined($q->param("rights"))) {
    # Rechte sammeln und überprüfen
    my @new_rights;
    push(@new_rights, "users");
    my @rights = $q->param("rights");
    foreach (@rights) {
      push(@new_rights, "schueler") if ($_ eq "schueler");
      push(@new_rights, "lehrer") if ($_ eq "lehrer");
      push(@new_rights, "internet") if ($_ eq "internet");
      push(@new_rights, "admin") if ($_ eq "admin");
      push(@new_rights, "homepage") if ($_ eq "homepage");
    }

    my $rights_string = join(",", @new_rights);

    my $shell = "/bin/false";
    if ($rights_string =~ m/admin/) { $shell = "/bin/bash"; }

    `sudo /usr/sbin/usermod -s $shell -G $rights_string,$login $login`;
    fehler("Benutzer ändern, Rechte (usermod) [$login]") if ($? != 0);
  }

  if (defined($q->param("lock"))) {
    $status = $q->param("lock");
    if ($status eq "gesperrt") {
      # sperre Benutzer $login
      `sudo /usr/bin/passwd -l $login`;
      fehler("Benutzer sperren (passwd) [$login]") if ($? != 0);
      `sudo /usr/bin/smbpasswd -d $login`;
      fehler("Benutzer sperren (smbpasswd) [$login]") if ($? != 0);
    } else {
      # Gebe Benutzer $login frei
      `sudo /usr/bin/passwd -u $login`;
      fehler("Benutzer freigeben (passwd) [$login]") if ($? != 0);
      `sudo /usr/bin/smbpasswd -e $login`;
      fehler("Benutzer freigeben (smbpasswd) [$login]") if ($? != 0);
    }
  }

  if (defined($q->param("quota"))) {
    # Quota
    $q->param("quota") =~ m/(\d+)/;
    my $quota = $1 * 1024; # Anzahl der KB-Blöcke


    `sudo /usr/sbin/setquota $login $quota $quota 0 0 /dev/md0`;
    fehler("Benutzer ändern, Quota (setquota) [$login]") if ($? != 0);
  }


  if (defined($q->param("passwort")) && $q->param("passwort") ne "") {
    my $password = $q->param("passwort");
    #untaint
    $password =~ m/([-\w#*,;:.+!$%&\/|?{\[()\]}]+)/;
    $password = $1;

    my $enc_pw = crypt($password,
        join("", (".", "/", 0..9, "a".."z", "A".."Z")[rand 64, rand 64]));

    `sudo /usr/sbin/usermod -p $enc_pw $login`;
    fehler("Benutzer ändern, Passwort (usermod) [$login]") if ($? != 0);

    open PIPE, "| sudo /usr/bin/smbpasswd -s $login > /dev/null"
        or fehler("Benutzer ändern, Passwort (pipe open) [$login]");
    print PIPE "$password\n$password\n"
        or fehler("Benutzer ändern, Passwort (pipe write) [$login]");
    close PIPE
        or fehler("Benutzer ändern, Passwort (pipe close) [$login]");
  }

  `sudo /usr/local/sbin/generate_apache_auth`;

  $error = "Benutzer $login geändert.";

  &print_page_data;
}

A.8.1. Hilfsprogramm user-status3

Dateiname: /usr/local/sbin/user-status3.


#!/usr/bin/perl -wT
use User::pwent;

# Path setzen, wegen Taint-Mode
$ENV{"PATH"} = "/bin:/usr/bin";

# Parameter holen...
my $action = shift;
my $login = shift;

# $login untainten
if (defined($login)) {
  $login =~ m/([\w\.-]+)/;
  $login = $1;
}


if (defined($action) && defined($login)) {
     if ($action eq "-passwd") { &print_passwd(); }
  elsif ($action eq "-locked") { &print_locked(); }
  elsif ($action eq "-groups") { &print_groups(); }
  elsif ($action eq "-change") { &print_change(); }
  elsif ($action eq "-quota")  { &print_quota();  }
}

print "fehlerhafte Argumente...\n";
print "user-status action login\n";
print "action: {-passwd|-locked|-groups|-change|-quota}\n";
exit 1;





sub print_passwd {
  my $user = getpwnam($login);
  if (crypt("passwort", $user->passwd) eq $user->passwd) {
    print $login;
  } else {
    print "---secure";
  }
  exit 0;
}

sub print_locked {
  my $user = getpwnam($login);
  if (substr($user->passwd, 0, 1) eq "!") {
    print $login;
  } else {
    print "---unlocked";
  }
  exit 0;
}

sub print_groups {
  my $groups = `id -nG $login`;
  print $groups;
  exit 0;
}

sub print_change {
  open(SHADOW, "</etc/shadow");
  my @data = <SHADOW>;
  close(SHADOW);
  my @user = grep(/$login/, @data);
  my $line = shift @user;
  my $age = (split(/:/, $line))[2];

  $age = $age * 24 * 60 * 60;
  my $day;
  my $mon;
  my $year;
  (undef, undef, undef, $day, $mon, $year) = localtime($age);
  $mon += 1;
  $year += 1900;

  if ($day < 10) { $day = "0$day"; }
  if ($mon < 10) { $mon = "0$mon"; }

  print "$day.$mon.$year";
  exit 0;
}

sub print_quota {
  my $ret = `quota -v $login`;
  $ret =~ tr/ //s;
  my @zeilen = split /\n/, $ret;
  my @quota = split / /, $zeilen[2];
  $quota[2] =~ m/(\d+)/;
  my $quota_used = $1;
  $quota_used = int($quota_used/1024);
  $quota[3] =~ m/(\d+)/;
  my $quota_limit = $1;
  $quota_limit = int($quota_limit/1024);

  print "$quota_used/$quota_limit MB";
  exit 0;
}