Skip to content

Instantly share code, notes, and snippets.

@amis92
Last active January 21, 2016 23:04
Show Gist options
  • Save amis92/f45d5ffb0f891725f517 to your computer and use it in GitHub Desktop.
Save amis92/f45d5ffb0f891725f517 to your computer and use it in GitHub Desktop.
PERL script using Tk - user manager GUI
#!/usr/bin/perl
#
# Command-Line or GUI User Manager script
use strict;
use Tk;
use Tk::BrowseEntry;
my $mw = new MainWindow;
fill_window($mw, 'User Manager');
# create menu
my $menu = $mw->Frame(-relief => 'groove', -borderwidth => 3, -background => 'white')->pack(-side => 'top', -fill => 'x');
my $file_button = $menu->Menubutton(-text => 'File', -background => 'white', -foreground => 'black')->pack(-side => 'left');
my $user_button = $menu->Menubutton(-text => 'User', -background => 'white', -foreground => 'black')->pack(-side => 'left');
my $group_button = $menu->Menubutton(-text => 'Group',-background => 'white', -foreground => 'black')->pack(-side => 'left');
# create options in menu
$user_button ->command(-label => 'Add User', -command => \&add_user);
$user_button ->command(-label => 'Change User', -command => \&modify_user);
$user_button ->command(-label => 'Remove User', -command => \&remove_user);
$group_button ->command(-label => 'View User Group', -command => \&modify_group);
$group_button ->command(-label => 'View Groups', -command => \&view_group_users);
$file_button ->command(-label => 'Exit', -command => \&finito );
# user list
my $frame = $mw->Frame(-background => "blue")->pack();
my $list = $frame->Scrolled('Listbox', -scrollbars => 'osoe', -setgrid => 'yes', -width => 40, -height => 20)->pack();
$list->grid(-row => 2, -column => 1);
sub load_users {
$list->delete(0,'end');
open(OUT, "<", "/etc/passwd") || die("Cannot open /etc/passwd: $!");
while (<OUT>) {
my @line_data = split(/:/, $_);
my $uid = $line_data[2];
if ($uid >= 1000 && $uid < 65534){
$list->insert('end', $line_data[0]);
}
}
close OUT;
}
# do that now
load_users();
# now all the other callbacks
sub is_uid_available {
my ($uid) = @_;
open(OUT, "<", "/etc/passwd") || die("Cannot open /etc/passwd: $!");
while (<OUT>) {
my @line_data = split(/:/, $_);
if($line_data[2] == $uid) {
close OUT;
return '';
}
}
close OUT;
return "true";
}
sub is_login_available {
my ($login) = @_;
open(OUT, "<", "/etc/passwd") || die("Cannot open /etc/passwd: $!");
while (<OUT>) {
my @line_data = split(/:/, $_);
if($line_data[0] eq $login) {
close OUT;
return '';
}
}
close OUT;
return "true";
}
sub get_available_uid {
my $last_valid_uid = 1000;
open(OUT, "<", "/etc/passwd") || die("Cannot open /etc/passwd: $!");
while (<OUT>) {
my @line_data = split(/:/, $_);
my $uid = $line_data[2];
if ($uid >= 1000 &&
$uid <= 6000 &&
$uid >= $last_valid_uid)
{
$last_valid_uid = $uid;
}
}
close OUT;
return $last_UID_value + 1;
}
sub fill_window {
my ($window, $header) = @_;
$window->title($header);
$window->Button(
-text => 'close',
-command => [$window => 'destroy']
)->pack(-side => 'bottom');
}
sub load_user_data {
my ($user_login) = @_;
open(OUT, "<", "/etc/passwd") || die("Cannot open /etc/passwd: $!");
while (<OUT>) {
my @line_data = split(/:/, $_);
if ( $line_data[0] eq $user_login) {
close OUT;
return @line_data;
}
}
close OUT;
return undef;
}
sub get_shells {
my @shells;
open(OUT, "<", "/etc/shells") || die("Cannot open /etc/shells: $!");
while (<OUT>) {
if ($_ !~ /^#/) {
push(@shells, $_);
}
}
close OUT;
return @shells;
}
sub add_user {
my $mwlocal = MainWindow->new();
$mwlocal->title("Add User");
my ($login, $uid, $shell, $home, $gid);
my $label_login = $mwlocal->Label(-text => "Login:");
my $entry_login = $mwlocal->Entry(-textvariable => \$login);
my $label_uid = $mwlocal->Label(-text => "UID:");
my $entry_uid = $mwlocal->Entry(-textvariable => \$uid);
my $label_home = $mwlocal->Label(-text => "Home dir:");
my $entry_home = $mwlocal->Entry(-textvariable => \$home);
my $label_shell = $mwlocal->Label(-text => "Shell:");
my $entry_shell = $mwlocal->Entry(-textvariable => \$shell);
my $label_group = $mwlocal-> Label(-text => "Group:");
my $entry_group = $mwlocal-> Entry(-textvariable => \$gid);
foreach (get_shells()) {
$shell_entry->insert('end', $_);
}
sub show_warn {
my ($warning) = @_;
$mwlocal->messageBox(
-title => 'Error',
-message => $warning,
-type => 'ok',
-icon => 'error',
);
}
my $send_button = $mwlocal->Button(-text => "Create", -command => sub {
my $login = $login_entry->get();
if (!$login){
show_warn "No login entered";
return;
}
if (!is_login_available($login)){
show_warn "Login already taken";
return;
}
my $uid = $uid_entry->get();
if ($uid !~ /^\d+$/){
show_warn "UID not a number";
return;
}
if (!is_uid_available($uid)) {
show_warn "UID already exists";
return;
}
my $genPW = `pwgen -1`;
my $pass = crypt("$genPW","salt");
my $gid_value = $gid ? $gid : "yes";
if (!`useradd -u $uid -d $home -g $gid_value -s $shell -m -p $pass $login`) {
show_warn "Failed to add user $login: $!";
return;
}
# change for production use?
print "$login has password ($genPW)\n";
load_users();
}) -> pack();
my $cancel_btn = $mwlocal->Button(
-text=>'Cancel',
-command=> sub { $mwlocal->destroy; }
) -> pack();
$login_label -> grid(-row => 2, -column => 1);
$login_entry -> grid(-row => 2, -column => 2);
$uid_label -> grid(-row => 3, -column => 1);
$uid_entry -> grid(-row => 3, -column => 2);
$home_label -> grid(-row => 5, -column => 1);
$home_entry -> grid(-row => 5, -column => 2);
$group_label -> grid(-row => 6, -column => 1);
$group_entry -> grid(-row => 6, -column => 2);
$shell_label -> grid(-row => 7, -column => 1);
$shell_entry -> grid(-row => 7, -column => 2);
$send_button -> grid(-row => 9, -column => 1);
$cancel_btn -> grid(-row => 9, -column => 2);
MainLoop;
} # end add_user
sub remove_user {
my $sel = $list->curselection();
if (!$sel) {
$mw->messageBox(
-title => 'Error',
-message => "No user selected. To remove, first select a user.",
-type => 'ok',
-icon => 'error',
);
return;
}
my $login = $list->get($sel);
my $confirmation = $mw->messageBox(
-title => 'Confirm',
-message => "You're about to delete '$login' account. Are you sure?",
-type => 'YesNo',
-icon => 'question',
);
if ( $confirmation eq 'No' ) {
return;
}
if (!`deluser $login --remove-home`) {
$mw->messageBox(
-title => 'Error',
-message => "Failed to remove '$login': $!",
-type => 'Ok',
-icon => 'error'
);
return;
}
load_users();
} # end remove_user
sub modify_user {
my $sel = $list->curselection();
if (!$sel) {
$mw->messageBox(
-title => 'Invalid operation',
-message => "No user selected. To remove, first select a user.",
-type => 'ok',
-icon => 'error',
);
return;
}
my $login = $list->get($sel);
my $old_login = $login;
my @data = load_user_data($login);
my $uid = $data[2];
my $gid = $data[3];
my $home = $data[5];
my $shell = $data[6];
my $mwlocal = MainWindow->new();
$mwlocal->title("Modify User");
my $label_login = $mwlocal->Label(-text => "Login:");
my $entry_login = $mwlocal->Entry(-textvariable => \$login);
my $label_uid = $mwlocal->Label(-text => "UID:");
my $entry_uid = $mwlocal->Entry(-textvariable => \$uid);
my $label_home = $mwlocal->Label(-text => "Home dir:");
my $entry_home = $mwlocal->Entry(-textvariable => \$home);
my $label_shell = $mwlocal->Label(-text => "Shell:");
my $entry_shell = $mwlocal->BrowseEntry(-variable => \$shell);
my $label_group = $mwlocal-> Label(-text => "Group:");
my $entry_group = $mwlocal-> Entry(-textvariable => \$gid);
foreach (get_shells()) {
$shell_entry->insert('end', $_);
}
sub show_warn {
my ($warning) = @_;
$mwlocal->messageBox(
-title => 'Error',
-message => $warning,
-type => 'ok',
-icon => 'error',
);
}
my $send_button = $mwlocal->Button(
-text => "Modify",
-command => sub {
if (!$login){
show_warn "No login entered";
return;
}
if (!is_login_available($login)){
show_warn "Login already taken";
return;
}
my $uid = $uid_entry->get();
if ($uid !~ /^\d+$/){
show_warn "UID not a number";
return;
}
if (!is_uid_available($uid)) {
show_warn "UID already exists";
return;
}
if ($gid < 1000 || $gid >= 65534 ){
show_warn "GID must be in range <1000, 65534>";
return;
}
#modify
$shell =~ s/^\s+//; #remove leading spaces
$shell =~ s/\s+$//; #remove trailing spaces
if (!`usermod -d $home -s $shell --uid $uid --login $login -m $old_login`) {
show_warn "Failed to modify $old_login: $!";
}
load_users();
})->pack();
my $cancel_btn = $mwlocal->Button(
-text => 'Cancel',
-command => sub { $mwlocal->destroy; }
)->pack();
$label_login -> grid(-row => 2, -column => 1);
$entry_login -> grid(-row => 2, -column => 2);
$label_uid -> grid(-row => 3, -column => 1);
$entry_uid -> grid(-row => 3, -column => 2);
$label_home -> grid(-row => 5, -column => 1);
$entry_home -> grid(-row => 5, -column => 2);
$label_group -> grid(-row => 6, -column => 1);
$entry_group -> grid(-row => 6, -column => 2);
$label_shell -> grid(-row => 7, -column => 1);
$entry_shell -> grid(-row => 7, -column => 2);
$send_button -> grid(-row => 9, -column => 1);
$cancel_btn -> grid(-row => 9, -column => 2);
MainLoop;
} # end modify_user
sub view_group_users {
my $mwlocal = MainWindow->new();
$mwlocal->Label(-text => "Group Users");
my $label_uid = $mwlocal->Label(-text => "Grupy i Userzy");
my $entry_uid = $mwlocal->Entry();
# gid list
my $gid_list = $mwlocal->Scrolled('Listbox', -scrollbars => 'osoe', -setgrid=> 'yes', -width=>20, -height=>10)->pack();
#user list
my $usr_list = $mwlocal->Scrolled('Listbox', -scrollbars => 'osoe', -setgrid=> 'yes', -width=>20, -height=>10)->pack();
load_groups($gid_list);
my $show_btn = $mwlocal->Button(
-text => 'Show Users',
-command => sub {
my $sel = $gid_list->curselection();
if ($sel eq "") {
my $ftp_warn = $mw->messageBox(
-title => 'NOT RLY',
-message => "Select group first!",
-type => 'ok',
-icon => 'error',
);
return;
}
my $value=$gid_list->get($sel);
$usr_list->delete(0,'end');
group_users("$value",$usr_list);
})->pack();
my $remove_btn = $mwlocal->Button(
-text => 'Remove users with GID',
-command => sub {
my $ftp_warn = $mw->messageBox(
-title => 'SERIOUSLY?',
-message => "Are you sure?",
-type => 'YesNo',
-icon => 'question',
);
if ($ftp_warn eq 'No') {
return;
}
foreach ($usr_list->get(0,'end')) {
print "removing user $_ ...\n";
#UNCOMMENT
#`deluser $_ --remove-home`;
#rem($_);
}
})->pack();
my $cancel_btn = $mwlocal-> Button(
-text=>'Cancel',
-command=> sub { $mwlocal->destroy; }
)->pack();
# set up grid
$label_uid ->grid(-row => 1, -column => 1);
$entry_uid ->grid(-row => 1, -column => 2);
$gid_list ->grid(-row => 2, -column => 1);
$usr_list ->grid(-row => 2, -column => 2);
$show_btn ->grid(-row => 3, -column => 2);
$remove_btn ->grid(-row => 4, -column => 2);
$cancel_btn ->grid(-row => 5, -column => 2);
MainLoop;
}
sub load_groups {
my ($list) = @_;
open(OUT, "<", "/etc/group") || die("Cannot open /etc/group: $!");
while(<OUT>) {
my @line_data = split(/:/, $_);
if($line_data[2] > 1000 && $line_data[2] < 65534) {
$list->insert('end',$line_data[2]);
}
}
close OUT;
}
sub modify_group {
my $sel = $list->curselection();
if ($sel eq "") {
my $ftp_warn = $mw->messageBox(
-title => 'NOT RLY',
-message => "Select user first!",
-type => 'ok',
-icon => 'error',
);
return;
}
my $value = $list->get($sel);
my @data = load_user_data($value);
my $gid_show = $data[3];
# debug info
print "@data\n\n";
my $mwlocal = MainWindow->new();
$mwlocal->Label(-text =>"Add User");
my $label_uid = $mwlocal->Label(-text => "Userzy dla GID = $gid_show");
my $entry_uid = $mwlocal->Entry();
$label_uid->grid(-row => 1, -column => 1);
$entry_uid->grid(-row => 1, -column => 2);
# gid list
my $list2 = $mwlocal->Scrolled('Listbox', -scrollbars=> 'osoe', -setgrid=> 'yes', -width=>20, -height=>10) -> pack();
$list2->grid(-row => 2, -column => 2);
my $rem_button = $mwlocal-> Button(
-text=>'Remove users with GID',
-command=> sub {
my $ftp_warn = $mw->messageBox(
-title => 'SERIOUSLY?',
-message => "Are you sure?",
-type => 'YesNo',
-icon => 'question',
);
if ( $ftp_warn eq 'No' ) {
return;
}
foreach ( $list2->get(0,'end') ) {
my $value=$list->get($sel);
print "removing user $_ ...\n";
#UNCOMMENT
#`deluser $_ --remove-home`;
#rem($_);
}
})->pack();
$rem_button->grid(-row => 3, -column => 2);
my $add_button = $mwlocal->Button(
-text=>'Add user to group',
-command=> sub {
my $myUID=$entry_uid->get();
if ($myUID eq "") {
my $ftp_warn = $mw->messageBox(
-title => 'NOT RLY',
-message => "UID is empty!",
-type => 'ok',
-icon => 'error',
);
return;
}
if ($myUID < 1000 || $myUID > 65533){
my $ftp_warn = $mw->messageBox(
-title => 'NOT RLY',
-message => "Cant use that UID!",
-type => 'ok',
-icon => 'error',
);
return;
}
`usermod -G $myUID $data[0]`;
})->pack();
$add_button->grid(-row => 4, -column => 2);
my $cancel_btn = $mwlocal->Button(
-text=>'Cancel',
-command=> sub { $mwlocal->destroy; }
)->pack();
$cancel_btn->grid(-row => 5, -column => 2);
group_users("$gid_show",$list2);
MainLoop;
}
sub group_users {
my ($gid,$list) = @_;
open(OUT, "<", "/etc/group") || die("Cannot open /etc/group: $!");
while (<OUT>) {
my @line_data = split(/:/, $_);
if($line_data[2] eq $gid) {
my $count = 0;
my @groups = split(/,/, $line_data[3]);
for ( $count ; $count <= @groups - 1 ; $count++) {
chomp($groups[$count]);
if("$groups[$count]" eq "") {
next;
}
$list->insert('end',$groups[$count]);
}
$list->insert('end',$line_data[0]);
last;
}
}
close OUT;
}
sub finito {
exit;
}
# let's start the GUI
MainLoop;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment