#!/usr/local/bin/perl
# edit_user.cgi
# Display a form for editing a user, or creating a new user
require './user-lib.pl';
use Time::Local;
&ReadParse();
# Show header and get the user
@ulist = &list_users();
$n = $in{'user'};
if ($n eq '') {
# Creating a new user
$access{'ucreate'} || &error($text{'uedit_ecreate'});
&ui_print_header(undef, $text{'uedit_title2'}, "", "create_user");
if ($in{'clone'} ne '') {
($clone_hash) = grep { $_->{'user'} eq $in{'clone'} } @ulist;
$clone_hash || &error($text{'uedit_egone'});
%uinfo = %$clone_hash;
&can_edit_user(\%access, \%uinfo) || &error($text{'uedit_eedit'});
$uinfo{'user'} = '';
}
}
else {
# Editing an existing one
($uinfo_hash) = grep { $_->{'user'} eq $n } @ulist;
$uinfo_hash || &error($text{'uedit_egone'});
%uinfo = %$uinfo_hash;
&can_edit_user(\%access, \%uinfo) || &error($text{'uedit_eedit'});
&ui_print_header(undef, $text{'uedit_title'}, "", "edit_user");
}
@tds = ( "width=30%" );
# build list of used shells
%shells = map { $_, 1 } split(/,/, $config{'shells'});
@shlist = ($config{'default_shell'} ? ( $config{'default_shell'} ) : ( ));
push(@shlist, "/bin/sh", "/bin/csh", "/bin/false") if ($shells{'fixed'});
&build_user_used(\%used, $shells{'passwd'} ? \@shlist : undef);
if ($shells{'shells'}) {
open(SHELLS, ") {
s/\r|\n//g;
s/#.*$//;
push(@shlist, $_) if (/\S/);
}
close(SHELLS);
}
# Start of the form
print &ui_form_start("save_user.cgi", "post");
print &ui_hidden("old", $n) if ($n ne "");
print &ui_table_start($text{'uedit_details'}, "width=100%", 2, \@tds);
# Username
if ($n eq "" && $config{'new_user_group'} && $access{'gcreate'}) {
$onch = "newgid.value = user.value";
}
if ($access{'urename'} || $n eq "") {
print &ui_table_row(&hlink($text{'user'}, "user"),
&ui_textbox("user", $uinfo{'user'}, 40, 0, undef,
"onChange='$onch'"));
}
else {
print &ui_table_row(&hlink($text{'user'}, "user"),
"".&html_escape($uinfo{'user'})."");
print &ui_hidden("user", $uinfo{'user'}),"\n";
}
# User ID
if ($n ne "") {
# Existing user, just show field to edit
$uidfield = &ui_textbox("uid", $uinfo{'uid'}, 10);
}
else {
# Work out which UID modes are available
@uidmodes = ( );
$defuid = &allocate_uid(\%used);
if ($access{'autouid'}) {
push(@uidmodes, [ 1, $text{'uedit_uid_def'} ]);
}
if ($access{'calcuid'}) {
push(@uidmodes, [ 2, $text{'uedit_uid_calc'} ]);
}
if ($access{'useruid'}) {
push(@uidmodes, [ 0, &ui_textbox("uid", $defuid, 10) ]);
}
if (@uidmodes == 1) {
$uidfield = &ui_hidden("uid_def", $uidmodes[0]->[0]).
$uidmodes[0]->[1];
}
else {
$uidfield = &ui_radio("uid_def", $config{'uid_mode'},
\@uidmodes);
}
}
print &ui_table_row(&hlink($text{'uid'}, "uid"), $uidfield);
# Real name
if ($config{'extra_real'}) {
# Has separate name, office, work and home phone parts
local @real = split(/,/, $uinfo{'real'}, 5);
print &ui_table_row(&hlink($text{'real'}, "real"),
&ui_textbox("real", $real[0], 40));
print &ui_table_row(&hlink($text{'office'}, "office"),
&ui_textbox("office", $real[1], 20));
print &ui_table_row(&hlink($text{'workph'}, "workph"),
&ui_textbox("workph", $real[2], 20));
print &ui_table_row(&hlink($text{'homeph'}, "homeph"),
&ui_textbox("homeph", $real[3], 20));
print &ui_table_row(&hlink($text{'extra'}, "extra"),
&ui_textbox("extra", $real[4], 20));
}
else {
# Just a name
$uinfo{'real'} =~ s/,*$//; # Strip empty extra fields
print &ui_table_row(&hlink($text{'real'}, "real"),
&ui_textbox("real", $uinfo{'real'}, 40));
}
# Show input for home directory
if ($access{'autohome'}) {
# Automatic, cannot be changed
$homefield = $text{'uedit_auto'}.
($n eq "" ? "" : " ( $uinfo{'home'} )" );
}
else {
if ($config{'home_base'}) {
# Can be automatic
local $grp = &my_getgrgid($uinfo{'gid'});
local $hb = $n eq "" ||
&auto_home_dir($config{'home_base'},
$uinfo{'user'}, $grp) eq $uinfo{'home'};
$homefield = &ui_radio("home_base", $hb ? 1 : 0,
[ [ 1, $text{'uedit_auto'}."
" ],
[ 0, $text{'uedit_manual'}." ".
&ui_filebox("home", $hb ? "" : $uinfo{'home'},
40, 0, undef, undef, 1) ] ]);
}
else {
# Allow any directory
$homefield = &ui_filebox("home", $uinfo{'home'}, 25, 0,
undef, undef, 1);
}
}
print &ui_table_row(&hlink($text{'home'}, "home"),
$homefield);
# Show shell drop-down
push(@shlist, $uinfo{'shell'}) if ($n ne "" && $uinfo{'shell'});
if ($access{'shells'} ne "*") {
# Limit to shells from ACL
@shlist = $n ne "" ? ($uinfo{'shell'}) : ();
push(@shlist, split(/\s+/, $access{'shells'}));
$shells = 1;
}
$shells = 1 if ($access{'noother'});
@shlist = &unique(@shlist);
if ($n ne "" && !$uinfo{'shell'}) {
# No shell!
push(@shlist, [ "", "<None>" ]);
}
push(@shlist, [ "*", $text{'uedit_other'} ]) if (!$shells);
$firstshell = ref($shlist[0]) ? $shlist[0]->[0] : $shlist[0];
print &ui_table_row(&hlink($text{'shell'}, "shell"),
&ui_select("shell", $n eq "" ? $config{'default_shell'} || $firstshell
: $uinfo{'shell'},
\@shlist, 1, 0, 0, 0,
"onChange='form.othersh.disabled = form.shell.value != \"*\"'").
($shells ? "" : &ui_filebox("othersh", undef, 40, 1)));
# Get the password, generate random if needed
$pass = $in{'clone'} ne "" ? $uinfo{'pass'} :
$n ne "" ? $uinfo{'pass'} : $config{'lock_string'};
if ($n eq "" && $config{'random_password'}) {
$random_password = &generate_random_password();
}
# Check if temporary locking is supported
if (&supports_temporary_disable()) {
if ($n ne "" && $pass ne $config{'lock_string'} && $pass ne "") {
# Can disable if not already locked, or if a new account
$can_disable = 1;
if ($pass =~ /^\Q$disable_string\E/) {
$disabled = 1;
$pass =~ s/^\Q$disable_string\E//;
}
}
elsif ($n eq "") {
$can_disable = 1;
}
}
# Show password field
$passmode = $pass eq "" && $random_password eq "" ? 0 :
$pass eq $config{'lock_string'} && $random_password eq "" ? 1 :
$random_password ne "" ? 3 :
$pass && $pass ne $config{'lock_string'} &&
$random_password eq "" ? 2 : -1;
$pffunc = $config{'passwd_stars'} ? \&ui_password : \&ui_textbox;
print &ui_table_row(&hlink($text{'pass'}, "pass"),
&ui_radio_table("passmode", $passmode,
[ [ 0, $config{'empty_mode'} ? $text{'none1'} : $text{'none2'} ],
[ 1, $text{'nologin'} ],
[ 3, $text{'clear'},
&$pffunc("pass", $config{'random_password'} && $n eq "" ?
$random_password : "", 15) ],
$access{'nocrypt'} ?
( [ 2, $text{'nochange'},
&ui_hidden("encpass", $pass) ] ) :
( [ 2, $text{'encrypted'},
&ui_textbox("encpass", $passmode == 2 ? $pass : "", 60) ] )
]).
($can_disable ? " ".&ui_checkbox("disable", 1,
$text{'uedit_disabled'}, $disabled) : "")
);
# Show SSH public key field, for new users
if ($n eq '') {
print &ui_table_row(&hlink($text{'sshkey'}, "sshkey"),
&ui_textarea("sshkey", undef, 3, 60), 3);
}
print &ui_table_end();
$pft = &passfiles_type();
if (($pft == 1 || $pft == 6) && $access{'peopt'}) {
# Additional user fields for BSD users
print &ui_table_start($text{'uedit_passopts'}, "width=100%", 4, \@tds);
# Last change date
if ($uinfo{'change'}) {
@tm = localtime($uinfo{'change'});
$cday = $tm[3];
$cmon = $tm[4]+1;
$cyear = $tm[5]+1900;
$chour = sprintf "%2.2d", $tm[2];
$cmin = sprintf "%2.2d", $tm[1];
}
print "
\n"; } } else { # Creating a user - show options for creating home directory, copying # skel files and creating in other modules if ($access{'makehome'} == 1 || $access{'copy'} == 1 || $access{'cothers'} == 1) { print &ui_table_start($text{'uedit_oncreate'}, "width=100%", 2, \@tds); # Create home dir if ($access{'makehome'} == 1) { print &ui_table_row( &hlink($text{'uedit_makehome'}, "makehome"), &ui_yesno_radio("makehome", 1)); } # Copy skel files if ($config{'user_files'} =~ /\S/ && $access{'copy'} == 1) { print &ui_table_row( &hlink($text{'uedit_copy'}, "copy_files"), &ui_yesno_radio("copy_files", 1)); } # Create in other modules if ($access{'cothers'} == 1) { print &ui_table_row( &hlink($text{'uedit_cothers'},"others"), &ui_yesno_radio("others", $config{'default_other'})); } print &ui_table_end(); } } if ($n ne "") { # Buttons for saving and other actions @buts = ( [ undef, $text{'save'} ] ); # List logins by user push(@buts, [ "list", $text{'uedit_logins'} ]); # Link to the mailboxes module, if installed if (&foreign_available("mailboxes") && &foreign_installed("mailboxes", 1)) { push(@buts, [ "mailboxes", $text{'uedit_mail'} ]); } # Link to Usermin for switching user if (&foreign_available("usermin") && &foreign_installed("usermin", 1) && (%uacl = &get_module_acl("usermin") && $uacl{'sessions'})) { # Link to Usermin module for switching to some user &foreign_require("usermin", "usermin-lib.pl"); local %uminiserv; &usermin::get_usermin_miniserv_config(\%uminiserv); if ($uminiserv{'session'}) { push(@buts, [ "switch", $text{'uedit_swit'}, undef, 0, "onClick='form.target=\"_blank\"'" ]); } } # Clone user if ($access{'ucreate'}) { push(@buts, [ "clone", $text{'uedit_clone'} ]); } # Delete user if ($access{'udelete'}) { push(@buts, [ "delete", $text{'delete'} ]); } print &ui_form_end(\@buts); } else { # Create button print &ui_form_end([ [ undef, $text{'create'} ] ]); } &ui_print_footer("index.cgi?mode=users", $text{'index_return'});