📄 save_user.cgi
字号:
#!/usr/local/bin/perl# save_user.cgi# Saves or creates a new user. If the changes require moving of the user's# home directory or changing file ownerships, do that as wellrequire './user-lib.pl';require 'timelocal.pl';&error_setup($text{'usave_err'});&ReadParse;%access = &get_module_acl();@ulist = &list_users();@glist = &list_groups();if ($in{'num'} ne "") { # Get old user info %ouser = %{$ulist[$in{'num'}]}; $user{'user'} = $ouser{'user'}; &can_edit_user(\%access, \%ouser) || &error($text{'usave_eedit'}); }else { # check new user details $access{'ucreate'} || &error($text{'usave_ecreate'}); $in{'user'} =~ /^[^: \t]+$/ || &error(&text('usave_ebadname', $in{'user'})); foreach $ou (@ulist) { &error(&text('usave_einuse', $in{'user'})) if ($ou->{'user'} eq $in{'user'}); } $user{'user'} = $in{'user'}; if ($config{'new_user_group'}) { foreach $og (@glist) { &error(&text('usave_einuseg', $in{'user'})) if ($og->{'group'} eq $in{'user'}); } } }# Validate and store basic inputs$in{'uid'} =~ /^[0-9]+$/ || &error(&text('usave_euid', $in{'uid'}));!$access{'lowuid'} || $in{'uid'} >= $access{'lowuid'} || &error(&text('usave_elowuid', $access{'lowuid'}));!$access{'hiuid'} || $in{'uid'} <= $access{'hiuid'} || &error(&text('usave_ehiuid', $access{'hiuid'}));if (!$access{'umultiple'}) { foreach $ou (@ulist) { if ($ou->{'uid'} == $in{'uid'} && $ou->{'user'} ne $ouser{'user'}) { &error(&text('usave_euidused', $ou->{'user'}, $in{'uid'})); } } }$in{'real'} =~ /^[^:]*$/ || &error(&text('usave_ereal', $in{'real'}));if (!$access{'autohome'}) { $in{'home'} =~ /^\// || &error(&text('usave_ehome', $in{'home'})); $al = length($access{'home'}); if (length($in{'home'}) < $al || substr($in{'home'}, 0, $al) ne $access{'home'}) { &error(&text('usave_ehomepath', $in{'home'})); } }if ($in{'shell'} eq "*") { $in{'shell'} = $in{'othersh'}; }if ($access{'shells'} ne "*") { if (&indexof($in{'shell'}, split(/\s+/, $access{'shells'})) < 0 && (!%ouser || $in{'shell'} ne $ouser{'shell'})) { &error(&text('usave_eshell', $in{'shell'})); } }$user{'uid'} = $in{'uid'};if ($in{'num'} ne "" || !$config{'new_user_group'}) { $user{'gid'} = getgrnam($in{'gid'}); if ($user{'gid'} eq "") { &error(&text('usave_egid', $in{'gid'})); } }elsif (!$access{'gcreate'}) { &error($text{'usave_egcreate'}); }$user{'real'} = $in{'real'};$user{'home'} = !$access{'autohome'} ? $in{'home'} : %ouser ? $ouser{'home'} : $access{'home'}."/".$in{'user'};$user{'shell'} = $in{'shell'};foreach $gid (split(/\0/, $in{'sgid'})) { $ingroup{$gid}++; }if ($access{'ugroups'} ne "*") { local %g; map { $g{$_}++ } split(/\s+/, $access{'ugroups'}); if ($in{'num'} ne "") { # existing users can only be added to or removed from # allowed groups if ($ouser{'gid'} != $user{'gid'}) { $g{$in{'gid'}} || &error(&text('usave_eprimary', $in{'gid'})); local $og = getgrgid($ouser{'gid'}); $g{$og} || &error(&text('usave_eprimaryr', $og)); } foreach $g (@glist) { local @mems = split(/,/ , $g->{'members'}); local $idx = &indexof($user{'user'}, @mems); if ($ingroup{$g->{'gid'}} && $idx<0 && !$g{$g->{'group'}}) { &error(&text('usave_esecondary', $g->{'group'})); } elsif (!$ingroup{$g->{'gid'}} && $idx>=0 && !$g{$g->{'group'}}) { &error(&text('usave_esecondaryr', $g->{'group'})); } } } elsif (!$config{'new_user_group'}) { # new users can only be added to allowed groups # This is skipped if we are creating a new group for # new users $g{$in{'gid'}} || &error(&text('usave_eprimary', $in{'gid'})); foreach $gid (split(/\0/, $in{'sgid'})) { local $group = getgrgid($gid); $g{$group} || &error(&text('usave_esecondary', $group)); } } }# Store password input$salt = chr(int(rand(26))+65) . chr(int(rand(26))+65);if ($in{'passmode'} == 0) { $user{'pass'} = ""; }elsif ($in{'passmode'} == 1) { $user{'pass'} = $config{'lock_string'}; }elsif ($in{'passmode'} == 2) { $user{'pass'} = $in{'encpass'}; }elsif ($in{'passmode'} == 3) { $user{'pass'} = &encrypt_password($in{'pass'}); }if (&passfiles_type() == 2) { # Validate shadow-password inputs if ($in{'expired'} ne "" && $in{'expirem'} ne "" && $in{'expirey'} ne "") { eval { $expire = timelocal(0, 0, 12, $in{'expired'}, $in{'expirem'}-1, $in{'expirey'}-1900); }; if ($@) { &error("invalid expiry date"); } $expire = int($expire / (60*60*24)); } else { $expire = ""; } $in{'min'} =~ /^[0-9]*$/ || &error(&text('usave_emin', $in{'min'})); $in{'max'} =~ /^[0-9]*$/ || &error(&text('usave_emax', $in{'max'})); $in{'warn'} =~ /^[0-9]*$/ || &error(&text('usave_ewarn', $in{'warn'})); $in{'inactive'} =~ /^[0-9]*$/ || &error(&text('usave_einactive', $in{'inactive'})); $user{'expire'} = $expire; $user{'min'} = $in{'min'}; $user{'max'} = $in{'max'}; $user{'warn'} = $in{'warn'}; $user{'inactive'} = $in{'inactive'}; $daynow = int(time() / (60*60*24)); $user{'change'} = !%ouser ? $daynow : $in{'passmode'} == 3 ? $daynow : $in{'passmode'} == 2 && $user{'pass'} ne $ouser{'pass'} ? $daynow : $ouser{'change'}; }elsif (&passfiles_type() == 1) { # Validate BSD-password inputs if ($in{'expired'} ne "" && $in{'expirem'} ne "" && $in{'expirey'} ne "") { eval { $expire = timelocal(59, $in{'expiremi'}, $in{'expireh'}, $in{'expired'}, $in{'expirem'}-1, $in{'expirey'}-1900); }; if ($@) { &error($text{'usave_eexpire'}); } } else { $expire = ""; } if ($in{'changed'} ne "" && $in{'changem'} ne "" && $in{'changey'} ne "") { eval { $change = timelocal(59, $in{'changemi'}, $in{'changeh'}, $in{'changed'}, $in{'changem'}-1, $in{'changey'}-1900); }; if ($@) { &error($text{'usave_echange'}); } } else { $change = ""; } $in{'class'} =~ /^([^: ]*)$/ || &error(&text('usave_eclass', $in{'class'})); $user{'expire'} = $expire; $user{'change'} = $change; $user{'class'} = $in{'class'}; }if (%ouser) { # We are changing an existing user if ($ouser{'uid'} != $user{'uid'}) { $changing_uid = 1; } if ($ouser{'gid'} != $user{'gid'}) { $changing_gid = 1; } if ($ouser{'home'} ne $user{'home'}) { $changing_homedir = 1; } # Move the home directory if needed if ($changing_homedir && $in{'movehome'}) { $out = `mv $ouser{'home'} $user{'home'} 2>&1`; if ($?) { &error(&text('usave_emove', $1)); } } # Change GID on files if needed if ($changing_gid && $in{'chgid'}) { if ($in{'chgid'} == 1) { &recursive_change($user{'home'}, $ouser{'uid'}, $ouser{'gid'}, -1, $user{'gid'}); } else { &recursive_change("/", $ouser{'uid'}, $ouser{'gid'}, -1, $user{'gid'}); } } # Change UID on files if needed if ($changing_uid && $in{'chuid'}) { if ($in{'chuid'} == 1) { &recursive_change($user{'home'}, $ouser{'uid'}, -1, $user{'uid'}, -1); } else { &recursive_change("/", $ouser{'uid'}, -1, $user{'uid'}, -1); } } # Update user details $ENV{'USERADMIN_USER'} = $user{'user'}; $ENV{'USERADMIN_ACTION'} = 'MODIFY_USER'; &making_changes(); &modify_user(\%ouser, \%user); $user{'passmode'} = $in{'passmode'}; if ($in{'passmode'} == 2 && $user{'pass'} eq $ouser{'pass'}) { # not changing password $user{'passmode'} = 4; } $user{'plainpass'} = $in{'pass'} if ($in{'passmode'} == 3); &other_modules("useradmin_modify_user", \%user); }else { # Create the home directory if ($in{'makehome'}) { mkdir($user{'home'}, oct($config{'homedir_perms'})); $e = $!; (-d $user{'home'}) || &error(&text('usave_emkdir', $e)); chmod(oct($config{'homedir_perms'}), $user{'home'}) || &error(&text('usave_echmod', $!)); $made_home = 1; } $ENV{'USERADMIN_USER'} = $user{'user'}; $ENV{'USERADMIN_ACTION'} = 'CREATE_USER'; &making_changes(); if ($config{'new_user_group'}) { # Find the first free GID above the base setgrent(); while(@tmp = getgrent()) { $used{$tmp[2]}++; } endgrent(); $newgid = int($config{'base_gid'} > $access{'lowgid'} ? $config{'base_gid'} : $access{'lowgid'}); while($used{$newgid}) { $newgid++; } # create a new group for this user $group{'group'} = $in{'user'}; $user{'gid'} = $group{'gid'} = $newgid; &create_group(\%group); } if ($made_home) { chown($user{'uid'}, $user{'gid'}, $user{'home'}) || &error(&text('usave_echown', $!)); } # Save user details &create_user(\%user); $user{'passmode'} = $in{'passmode'}; $user{'plainpass'} = $in{'pass'} if ($in{'passmode'} == 3); &other_modules("useradmin_create_user", \%user); # Copy files into user's directory if ($in{'copy_files'} && $in{'makehome'}) { local $uf = $config{'user_files'}; $uf =~ s/\$group/$in{'gid'}/g; $uf =~ s/\$gid/$user{'gid'}/g; foreach $f (split(/\s+/, $uf)) { if (-d $f) { # copy all files in a directory opendir(DIR, $f); foreach $df (readdir(DIR)) { if ($df eq "." || $df eq "..") { next; } ©_file("$f/$df", $user{'home'}, $user{'uid'}, $user{'gid'}); } closedir(DIR); } elsif (-r $f) { # copy just one file ©_file($f, $user{'home'}, $user{'uid'}, $user{'gid'}); } } } }# Update groupsforeach $g (@glist) { @mems = split(/,/ , $g->{'members'}); $idx = &indexof($user{'user'}, @mems); if ($ingroup{$g->{'gid'}} && $idx<0) { # Need to add to the group push(@mems, $user{'user'}); } elsif (!$ingroup{$g->{'gid'}} && $idx>=0) { # Need to remove from the group splice(@mems, $idx, 1); } else { next; } %newg = %$g; $newg{'members'} = join(',', @mems); &modify_group($g, \%newg); }&made_changes();# Bounce back to the list&redirect("");# copy_file(file, destdir, uid, gid)# Copy a file or directory and chown itsub copy_file{local($base, $subs);$_[0] =~ /\/([^\/]+)$/; $base = $1;$subs = $config{'files_remove'};$base =~ s/$subs//g;system("cp -r $_[0] $_[1]/$base >/dev/null 2>/dev/null");system("chown -R $_[2]:$_[3] $_[1]/$base >/dev/null 2>/dev/null");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -