[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[cobalt-users] Auto provisioning services using shell-tools-1.1-1 - Scripting help
- Subject: [cobalt-users] Auto provisioning services using shell-tools-1.1-1 - Scripting help
- From: "John Cordeiro" <jcordeiro@xxxxxxxx>
- Date: Mon Oct 9 14:07:22 2000
- List-id: Mailing list for users to share thoughts on Cobalt products. <cobalt-users.list.cobalt.com>
Hey guys here is something I hope you find Useful! But I need help
customizing. I'm a Perl Novice. The script is run using perl -w
ISPPower_Linux.pl which calls 4 pm files for the sub routines. I have
changed the following in ISPPower_Shared_Linux.pm. But when I try to create
an account it returns "error creating password" I don't know where its
getting this. I can create a user fine using the shell-tools using the
Format command from the prompt using the exact format shown (filling in the
$ for values). The scripts are called from a Signup server using an
encryption key. Very nice feature. I'm sure someone can figure this one out.
If you need all the files I can tar or zip them for you to try out.
any help would be greatly.... need I say more.
Johnc
my($USERADD) = "/usr/sbin/useradd"; to my($USERADD) =
"/usr/sbin/cobalt/adduser";
my($USERDEL) = "/usr/sbin/userdel"; to my($USERDEL) =
"/usr/sbin/cobalt/deluser";
# Format command
$Command = "$USERADD -c \"$Name\" -d $Home -g $Gid -s $Shell -u $Uid
$Login"; to # Format command
$Command = "$USERADD -f \"$Name\" -u $Login -p $Password -x";
Ok here is ISPPower_Shared_Linux.pm
#================================================================
# ISP Power Server Control Add-On
# Shared Linux Routines, Version 9809, December 17, 1998
# Copyright (c) 1997 ISP Power Corporation
# All rights reserved
#================================================================
# This software is licensed for use only as an integral part
# of the ISP Power Server Control Add-On. All other uses are
# prohibited. This software may be modified by a licensed
# end-user for their own internal use however all changes shall
# still be restricted by the original license.
#================================================================
use strict;
package ISPPower_Shared_Linux;
use ISPPower_Interface;
use Exporter ();
@ISPPower_Shared_Linux::ISA = qw(Exporter);
@ISPPower_Shared_Linux::EXPORT = qw(
ForkChild
AddUser ModifyUser DeleteUser SuspendUser UnsuspendUser
GetNextUid CheckLogin LoginExists CheckName CheckUid UidExists
CheckPassword
GetPasswordField EncryptPassword GetPassword ChangePassword
GroupExists CheckGid GidExists
LoadShell ShellExists
CheckDirectory CheckFile CopyDirectory CopyFile BackupDirectory
BackupFile
CreateFile DeleteFile GetFileMode
LoadParmSettings SaveParmSettings
);
$ISPPower_Shared_Linux::VERSION = "9809";
#================================================================
#=======================THIS SCRIPT SHOULD=======================
#======================NOT NEED TO BE EDITED=====================
#================================================================
# THIS SCRIPT SHOULD ONLY BE USED IF USING THE SHADOW PASSWORD
# IF SCRIPT MANIPULATIONS NEED TO BE MADE, YOU MUST HAVE ROOT ACCESS
# DAEMONS MUST BE LAUNCHED WITH ROOT ACCESS
# Location of Shadow File
my($SHADOW) = "/etc/shadow";
# Location of Password File
my($PASSWD) = "/usr/bin/passwd";
my($SUSPEND) = "$PASSWD -l";
my($UNSUSPEND) = "$PASSWD -u";
my($USERADD) = "/usr/sbin/cobalt/adduser";
my($USERMOD) = "/usr/sbin/usermod";
my($USERDEL) = "/usr/sbin/cobalt/deluser";
my($CHPASSWD) = "/usr/sbin/chpasswd -e";
my($MKPASSWD) = "";
# Location of valid Shells files
my($SHELLS) = "/etc/shells";
# Location of directory containing shell executables
my($SHELL_DIR) = "/bin";
# This is for when there are no shells used, such as when using Telnet
my($NO_SHELL) = "/bin/false";
# Location of valid Shells files
## my($SHELLS) = "/etc/shells";
# Location of directory containing shell executables
## my($SHELL_DIR) = "/bin";
# Location of tty file
my($TTY) = "/dev/tty";
# Prefix appended to backed up files and directories for
# closed services
my($BACKUP_PREFIX) = ".d.";
# Location of parameter file
my($PARM_FILE) = "ISPPower_Server.ini";
# Location of last uid paramenter name
my($PARM_LAST_UID) = "last_uid";
# Maximum length of logins
my($LOGIN_MAX_LENGTH) = 16;
# Maximum length of password
my($PASSWORD_MAX_LENGTH) = 8;
# Minimum and Maximum uid to use
my($UID_MIN) = 10;
my($UID_MAX) = 32760;
# Minimum and Maximum gid to use
my($GID_MIN) = 10;
my($GID_MAX) = 32760;
# The following constant is defined in sys/ioctl.h and may
# vary by UNIX version. The value shown is known to be valid
# for Linux.
sub TIOCNOTTY { return 0x5422 }
#================================================================
#=====================CONFIGURABLE SETTINGS======================
#============================END HERE============================
#================================================================
# Mask to check validity of logins (PERL REGULAR EXPRESSION)
my($LOGIN_MASK) = '^[a-zA-Z][a-zA-Z0-9]*$';
# Mask to check validity of user names (PERL REGULAR EXPRESSION)
my($NAME_MASK) = '^[^:]*$';
# Mask to check validity of uids (PERL REGULAR EXPRESSION)
my($UID_MASK) = '^[0-9]+$';
# Mask to check validity of gids (PERL REGULAR EXPRESSION)
my($GID_MASK) = '^[0-9]+$';
# Mask to check validity of directory names (PERL REGULAR EXPRESSION)
my($DIR_MASK) = '^\/[^:]+$';
# Mask to check validity of file names (PERL REGULAR EXPRESSION)
my($FILE_MASK) = '^\/[^:]+$';
my($ShellsTime) = 0;
my(%Shells);
# File locking constants
my($LOCK_SH) = 1;
my($LOCK_EX) = 2;
my($LOCK_NB) = 4;
my($LOCK_UN) = 8;
#================================================================
# Execution Control Routines
#================================================================
#----------------------------------------------------------------
# Purpose: Fork a child process to act as the server.
# Returns: Returns 1 from the child process and 0 from the
# parent process.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub ForkChild {
my($pid);
# Is program not running as root?
if ($> != 0) {
print "Program must be run as root\n";
return 0;
}
# Fork child
if (not defined($pid = fork())) {
print "Unable to fork child process\n";
return 0;
}
# Is this the parent process?
if ($pid > 0) {
return 0;
}
# Become process group leader to avoid propagated signals
setpgrp();
# Close open filehandles to free resources
close(STDIN);
close(STDOUT);
close(STDERR);
# Detach from controlling terminal
open(TTY, "<$TTY");
ioctl(TTY, TIOCNOTTY, 0);
close(TTY);
# Set umask
umask(077);
# Change name of process
$0 = "ISPPower";
return 1;
}
#================================================================
# Password Info Routines
#================================================================
#----------------------------------------------------------------
# Purpose: Add a user.
# Returns: Returns a null string if the operation is
# successful or an error message otherwise.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub AddUser {
my($Login, $Password, $Name, $Uid, $Gid, $Home, $Shell) = @_;
my($Note, $Command);
# Check fields
if ($Note = &CheckLogin($Login)) {
return $Note;
}
if (&LoginExists($Login)) {
return "Login is already in use";
}
if ($Note = &CheckPassword($Password)) {
return $Note;
}
if ($Note = &CheckName($Name)) {
return $Note;
}
if ($Note = &CheckUid($Uid)) {
return $Note;
}
if (&UidExists($Uid)) {
return "User ID is already in use";
}
if ($Note = &CheckGid($Gid)) {
return $Note;
}
if (not &GidExists($Gid)) {
return "Group ID does not exist";
}
if (not &CheckDirectory($Home)) {
return "Home directory $Home is invalid";
}
if (-e $Home) {
return "Home directory $Home already exists";
}
# Is shell missing directory?
if ($Shell !~ /^\//) {
# Prepend shell directory
$Shell = $SHELL_DIR . "/" . $Shell;
}
# Check shell
if (not &ShellExists($Shell)) {
return "Shell does not exist";
}
# Format command
$Command = "$USERADD -f \"$Name\" -u $Login -p $Password -x";
# Add user
if (system($Command) != 0) {
return "Error adding login";
}
# Set password
if (not &ChangePassword($Login, 1, $Password)) {
return "Error setting password";
}
return "";
}
#----------------------------------------------------------------
# Purpose: Modify a user.
# Returns: Returns a null string if the operation is
# successful or an error message otherwise.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub ModifyUser {
my($OldLogin, $NewLogin, $Password, $Name, $Uid, $Gid, $Home, $Shell) =
@_;
my($Options, $Command, $Note);
# Get old login info
my($OldName, $OldPassword, $OldUid, $OldGid, $OldQuota, $OldComment,
$OldGecos, $OldHome, $OldShell) = getpwnam($OldLogin);
# Clear options
$Options = "";
# Check fields
if ($OldName eq "") {
return "Old login does not exist";
}
if (($NewLogin ne "") && ($NewLogin ne $OldLogin)) {
if ($Note = &CheckLogin($NewLogin)) {
return $Note;
}
if (&LoginExists($NewLogin)) {
return "Login is already in use";
}
}
if (defined($Password)) {
if ($Note = &CheckPassword($Password)) {
return $Note;
}
}
if (defined($Name)) {
if ($Note = &CheckName($Name)) {
return $Note;
}
$Options = $Options . " -c \"$Name\"";
}
if (($Uid ne "") && ($Uid != $OldUid)) {
return "Cannot change User ID";
}
if (($Gid ne "") && ($Gid != $OldGid)) {
return "Cannot change Group ID";
}
if ($Home ne "") {
if (not &CheckDirectory($Home)) {
return "Home directory $Home is invalid";
}
$Options = $Options . " -d $Home";
}
# Was shell specified?
if ($Shell ne "") {
# Is shell missing directory?
if ($Shell !~ /^\//) {
# Prepend shell directory
$Shell = $SHELL_DIR . "/" . $Shell;
}
# Check shell
if (not &ShellExists($Shell)) {
return "Shell does not exist";
}
$Options = $Options . " -s $Shell";
}
# Has login changed?
if (($NewLogin ne "") && ($NewLogin ne $OldLogin)) {
# Get current login info
if (not defined($Password)) {
if (not defined($Password = &GetPassword($OldLogin))) {
return "Unable to get current password";
}
} else {
$Password = &EncryptPassword($Password);
}
if (not defined($Name)) {
$Name = $OldComment;
}
$Uid = $OldUid;
$Gid = $OldGid;
if ($Home eq "") {
$Home = $OldHome;
}
if ($Shell eq "") {
$Shell = $OldShell;
}
# Format command
$Command = "$USERADD -c \"$Name\" -d $Home -g $Gid -s $Shell -u
$Uid -o $NewLogin";
# Create new login
if (system($Command) != 0) {
return "Error creating new login";
}
# Set password
if (not &ChangePassword($NewLogin, 0, $Password)) {
return "Error setting password";
}
# Delete old login
if (system("$USERDEL $OldLogin") != 0) {
return "Error deleting login";
}
} else {
# Change specified fields
if ($Options ne "") {
if (system("$USERMOD $Options $OldLogin") != 0) {
return "Error modifying login";
}
}
# Change password
if (defined($Password)) {
if (not &ChangePassword($OldLogin, 1, $Password)) {
return "Error changing password";
}
}
}
return "";
}
#----------------------------------------------------------------
# Purpose: Delete a user.
# Returns: Returns a null string if the operation is
# successful or an error message otherwise.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub DeleteUser {
my($Login) = @_;
# Does login not exist?
if (not &LoginExists($Login)) {
return "Login does not exist";
}
# Delete user
if (system("$USERDEL $Login") != 0) {
return "Error deleting login";
}
return "";
}
#----------------------------------------------------------------
# Purpose: Suspend a user.
# Returns: Returns a null string if the operation is
# successful or an error message otherwise.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub SuspendUser {
my($Login) = @_;
# Does login not exist?
if (not &LoginExists($Login)) {
return "Login does not exist";
}
# Suspend user
if (system("$SUSPEND $Login") != 0) {
return "Error suspending login";
}
return "";
}
#----------------------------------------------------------------
# Purpose: Unsuspend a user.
# Returns: Returns a null string if the operation is
# successful or an error message otherwise.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub UnsuspendUser {
my($Login) = @_;
# Does login not exist?
if (not &LoginExists($Login)) {
return "Login does not exist";
}
# Unsuspend user
if (system("$UNSUSPEND $Login") != 0) {
return "Error unsuspending login";
}
return "";
}
#----------------------------------------------------------------
# Purpose: Get next available user id.
# Returns: Returns the next available user id.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub GetNextUid {
my($LastUid, %Parms);
# Set default uid
$LastUid = $UID_MIN;
# Load parameter file
if (&LoadParmSettings($PARM_FILE, \%Parms)) {
# Get parameter from parameter file
if (exists($Parms{$PARM_LAST_UID})) {
$LastUid = $Parms{$PARM_LAST_UID};
}
}
# Find next available uid
for (;;) {
# Make sure uid is in range
if ($LastUid < $UID_MIN) {
$LastUid = $UID_MIN;
}
if ($LastUid > $UID_MAX) {
$LastUid = $UID_MIN;
}
# Is uid available?
if (not &UidExists($LastUid)) {
last;
}
# Increment uid
$LastUid++;
}
# Update parameter file
$Parms{$PARM_LAST_UID} = $LastUid;
&SaveParmSettings($PARM_FILE, \%Parms);
return $LastUid;
}
#----------------------------------------------------------------
# Purpose: Check a login.
# Returns: Returns an error message if the field is invalid
# otherwise returns a null string.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub CheckLogin {
my($Login) = @_;
# Is login too long?
if (length($Login) > $LOGIN_MAX_LENGTH) {
return "Login is too long";
}
# Is login in an invalid format?
if ($Login !~ /$LOGIN_MASK/o) {
return "Login is in an invalid format";
}
return "";
}
#----------------------------------------------------------------
# Purpose: Check if a login exists.
# Returns: Returns 1 if the login exists or 0 otherwise.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub LoginExists {
my($Login) = @_;
if (getpwnam($Login)) {
return 1;
} else {
return 0;
}
}
#----------------------------------------------------------------
# Purpose: Check a password.
# Returns: Returns an error message if the field is invalid
# otherwise returns a null string.
# History:
# 10/05/97 BMK Released.
#----------------------------------------------------------------
sub CheckPassword {
my($Password) = @_;
# Is password too long?
if (length($Password) > $PASSWORD_MAX_LENGTH) {
return "Password is too long";
}
return "";
}
#----------------------------------------------------------------
# Purpose: Check an account name.
# Returns: Returns an error message if the field is invalid
# otherwise returns a null string.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub CheckName {
my($Name) = @_;
# Is name in an invalid format?
if ($Name !~ /$NAME_MASK/o) {
return "Account name is in an invalid format";
}
return "";
}
#----------------------------------------------------------------
# Purpose: Check a user id.
# Returns: Returns an error message if the field is invalid
# otherwise returns a null string.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub CheckUid {
my($Uid) = @_;
# Is user id out of range?
if (($Uid < $UID_MIN) || ($Uid > $UID_MAX)) {
return "User ID is out of range";
}
# Is user id in an invalid format?
if ($Uid !~ /$UID_MASK/o) {
return "User ID is in an invalid format";
}
return "";
}
#----------------------------------------------------------------
# Purpose: Check if a uid exists.
# Returns: Returns 1 if the uid exists or 0 otherwise.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub UidExists {
my($Uid) = @_;
if (getpwuid($Uid)) {
return 1;
} else {
return 0;
}
}
#----------------------------------------------------------------
# Purpose: Get a password field for a login.
# Returns: Returns the password field value if the login
# exists or undef otherwise.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub GetPasswordField {
my($Login, $Field) = @_;
my($Name, $Password, $Uid, $Gid, $Quota, $Comment, $Gecos, $Home,
$Shell) = getpwnam($Login);
# Format field name
$Field = uc($Field);
# Does login exist?
if (defined($Name)) {
# Return field value
return $Password if ($Field eq "PASSWORD");
return $Uid if ($Field eq "UID");
return $Gid if ($Field eq "GID");
return $Quota if ($Field eq "QUOTA");
return $Comment if ($Field eq "COMMENT");
return $Gecos if ($Field eq "GECOS");
return $Home if ($Field eq "HOME");
return $Shell if ($Field eq "SHELL");
}
return undef;
}
#----------------------------------------------------------------
# Purpose: Encrypt a password.
# Returns: Returns the encrypted password.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub EncryptPassword {
my($Password, $Salt) = @_;
# Was a salt specified?
if (defined($Salt)) {
return crypt($Password, $Salt);
} else {
return crypt($Password, rand 65536);
}
}
#----------------------------------------------------------------
# Purpose: Get the password for a login.
# Returns: Returns the password if the login exists or
# undef otherwise.
# History:
# 06/13/97 BMK Released.
#----------------------------------------------------------------
sub GetPassword {
my($Login) = @_;
my($Line, $ShadowLogin, $ShadowPassword);
# Open shadow password file
if (not open(SHADOW, $SHADOW)) {
&ISPPower_Log("Unable to open shadow password file $SHADOW");
return undef;
}
# Read file
while ($Line = <SHADOW>) {
# Strip end-of-line character(s)
chomp($Line);
# Extract parameter and value
if (($ShadowLogin, $ShadowPassword) = ($Line =~
(/^([^:]*):([^:]*)/))) {
if ($ShadowLogin eq $Login) {
close(SHADOW);
return $ShadowPassword;
}
}
}
# Close file
close(SHADOW);
return undef;
}
#----------------------------------------------------------------
# Purpose: Change the password for a login.
# Returns: Returns 1 if the password is changed or 0
# otherwise.
# History:
# 10/05/97 BMK Released.
#----------------------------------------------------------------
sub ChangePassword {
my($Login, $Encrypt, $Password) = @_;
# Ignore SIGPIPE signal
local $SIG{'PIPE'} = 'IGNORE';
# Open pipe to chpasswd command
if (not open(CHPASSWD, "| $CHPASSWD")) {
&ISPPower_Log("Error opening pipe to $CHPASSWD");
return 0;
}
# Encrypt password if requested
if ($Encrypt) {
$Password = &EncryptPassword($Password);
}
# Send login and password to change
print CHPASSWD "$Login:$Password\n";
# Close pipe
if (not close(CHPASSWD)) {
&ISPPower_Log("Error closing pipe to $CHPASSWD");
return 0;
}
# Do password DBM files need to be updated?
if ($MKPASSWD ne "") {
# Update password DBM files
if (system($MKPASSWD) != 0) {
&ISPPower_Log("Error running $MKPASSWD");
return 0;
}
}
return 1;
}
#================================================================
# Group Info Routines
#================================================================
#----------------------------------------------------------------
# Purpose: Check if a group exists.
# Returns: Returns 1 if the group exists or 0 otherwise.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub GroupExists {
my($Group) = @_;
if (getgrnam($Group)) {
return 1;
} else {
return 0;
}
}
#----------------------------------------------------------------
# Purpose: Check a group id.
# Returns: Returns an error message if the field is invalid
# otherwise returns a null string.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub CheckGid {
my($Gid) = @_;
# Is group id out of range?
if (($Gid < $GID_MIN) || ($Gid > $GID_MAX)) {
return "Group ID is out of range";
}
# Is group id in an invalid format?
if ($Gid !~ /$GID_MASK/o) {
return "Group ID is in an invalid format";
}
return "";
}
#----------------------------------------------------------------
# Purpose: Check if a gid exists.
# Returns: Returns 1 if the gid exists or 0 otherwise.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub GidExists {
my($Gid) = @_;
if (getgrgid($Gid)) {
return 1;
} else {
return 0;
}
}
#================================================================
# Shell File Routines
#================================================================
#----------------------------------------------------------------
# Purpose: Load shell file.
# Returns: Returns 1 if the operation is successful or 0
# otherwise.
# History:
# 06/13/97 BMK Released.
#----------------------------------------------------------------
sub LoadShell {
my($Time) = @_;
# Is shells file already loaded?
if (defined($Time) && ($Time <= $ShellsTime)) {
return 1;
}
# Clear existing info
%Shells = ();
# Was a shell file specified?
if ($SHELLS ne "") {
# Open shells file
if (open(SHELLS, "$SHELLS")) {
# Read file
while (<SHELLS>) {
# Trim end-of-line character
chomp;
# Is line not a comment and not blank?
if (($_ !~ /^#/) && ($_ =~ /\S/)) {
# Save shell
$Shells{$_} = "";
}
}
# Close file
close(SHELLS);
}
}
# Update timestamp
if (defined($Time)) {
$ShellsTime = $Time;
}
return 1;
}
#----------------------------------------------------------------
# Purpose: Check if a shell exists.
# Returns: Returns 1 if the shell exists or 0 otherwise.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub ShellExists {
my($Shell) = @_;
# Is shell array empty?
if (not %Shells) {
return 1;
}
# Is shell missing directory?
if ($Shell !~ /^\//) {
# Prepend shell directory
$Shell = $SHELL_DIR . "/" . $Shell;
}
# Does shell exist?
if (exists($Shells{$Shell})) {
return 1;
} elsif ($Shell eq $NO_SHELL) {
return 1;
} else {
return 0;
}
}
#================================================================
# Directory/File Routines
#================================================================
#----------------------------------------------------------------
# Purpose: Check a directory.
# Returns: Returns 1 if the directory is valid or 0
# otherwise.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub CheckDirectory {
my($Dir) = @_;
# Is directory in a valid format?
if ($Dir =~ /$DIR_MASK/o) {
return 1;
} else {
return 0;
}
}
#----------------------------------------------------------------
# Purpose: Check a file.
# Returns: Returns 1 if the file is valid or 0 otherwise.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub CheckFile {
my($File) = @_;
# Is file in a valid format?
if ($File =~ /$FILE_MASK/o) {
return 1;
} else {
return 0;
}
}
#----------------------------------------------------------------
# Purpose: Copy a directory.
# Returns: Returns 1 if the operation is successful or 0
# otherwise.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub CopyDirectory {
my($Uid, $Gid, $Source, $Dest, $Recursive) = @_;
my($Mode, @Files, $File, $DestFile);
# Does source directory not exist?
if (not ((-e $Source) && (-d $Source))) {
&ISPPower_Log("Source directory $Source does not exist");
return 0;
}
# Does destination directory already exist?
if (-e $Dest) {
&ISPPower_Log("Destination directory $Dest already exists");
return 0;
}
# Get mode of source directory
$Mode = &GetFileMode($Source);
# Make destination directory
if (not mkdir($Dest, $Mode)) {
&ISPPower_Log("Unable to make destination directory $Dest");
return 0;
}
# Change mode of destination directory
if (not chmod($Mode, $Dest)) {
&ISPPower_Log("Unable to change permissions of destination directory
$Dest");
return 0;
}
# Change ownership of destination directory
if (not chown($Uid, $Gid, $Dest)) {
&ISPPower_Log("Unable to change ownership of destination directory
$Dest");
return 0;
}
# Open source directory
if (not opendir(DIR, $Source)) {
&ISPPower_Log("Unable to open source directory $Source");
return 0;
}
# Get files in directory
@Files = readdir(DIR);
# Close directory
closedir(DIR);
# Copy files in directory
foreach $File (@Files) {
# Is this a file?
if (-f "$Source/$File") {
# Strip any "dot." or "local." prefixes from destination
filename
$DestFile = $File;
$DestFile =~ s/^dot\./\./;
$DestFile =~ s/^local\./\./;
# Copy file to destination directory
if (not &CopyFile("$Source/$File", "$Dest/$DestFile")) {
return 0;
}
# Get mode of source file
$Mode = &GetFileMode("$Source/$File");
# Change mode of destination file
if (not chmod($Mode, "$Dest/$DestFile")) {
&ISPPower_Log("Unable to change permissions of destination
file $Dest/$DestFile");
return 0;
}
# Change ownership of destination file
if (not chown($Uid, $Gid, "$Dest/$DestFile")) {
&ISPPower_Log("Unable to change ownership of destination
file $Dest/$DestFile");
return 0;
}
}
# Is this a subdirectory?
elsif ((-d "$Source/$File") && ($File !~ /^\./)) {
# Should subdirectories be processed?
if ($Recursive) {
# Strip any "dot." prefixes from destination directory name
$DestFile = $File;
$DestFile =~ s/^dot\./\./;
# Copy subdirectory
if (not &CopyDirectory($Uid, $Gid, "$Source/$File",
"$Dest/$DestFile", 1)) {
return 0;
}
}
}
}
return 1;
}
#----------------------------------------------------------------
# Purpose: Copy a file.
# Returns: Returns 1 if the operation is successful or 0
# otherwise.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub CopyFile {
my($Source, $Dest) = @_;
# Open source file
if (not open(SOURCE, $Source)) {
&ISPPower_Log("Unable to open source file $Source");
return 0;
}
# Open destination file
if (not open(DEST, ">$Dest")) {
&ISPPower_Log("Unable to open destination file $Dest");
close(SOURCE);
return 0;
}
# Copy source file to destination file
while (<SOURCE>) {
print DEST;
}
# Close files
close(SOURCE);
close(DEST);
return 1;
}
#----------------------------------------------------------------
# Purpose: Backup a directory.
# Returns: Returns the new directory name if the operation
# is successful or a null string otherwise.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub BackupDirectory {
my($Dir) = @_;
return &BackupFile($Dir);
}
#----------------------------------------------------------------
# Purpose: Backup a file.
# Returns: Returns the new filename if the operation is
# successful or a null string otherwise.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub BackupFile {
my($File) = @_;
my($OldFile, $NewFile, $Dir, $Suffix, $i);
my($Sec, $Min, $Hour, $Day, $Month, $Year) = localtime(time());
# Does file not exist?
if (not (-e $File)) {
return "";
}
# Setup variables
$File =~ /([^\/]*)$/;
$OldFile = $1;
$NewFile = sprintf("%s%s.%04d%02d%02d", $BACKUP_PREFIX, $OldFile,
$Year + 1900, $Month + 1, $Day);
$Dir = substr($File, 0, length($File) - length($OldFile));
$Suffix = "";
$i = 0;
# Find first open backup filename
while (-e $Dir . $NewFile . $Suffix) {
$i++;
$Suffix = "." . $i;
}
# Rename file
if (not rename($Dir . $OldFile, $Dir . $NewFile . $Suffix)) {
return "";
}
return $Dir . $NewFile . $Suffix;
}
#----------------------------------------------------------------
# Purpose: Create a file.
# Returns: Returns 1 if the operation is successful or 0
# otherwise.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub CreateFile {
my($Uid, $Gid, $Mode, $File) = @_;
# Does file already exist?
if (-e $File) {
&ISPPower_Log("File $File already exists");
return 0;
}
# Open file
if (not open(FILE, ">$File")) {
&ISPPower_Log("Unable to open file $File");
return 0;
}
# Close file
close(FILE);
# Change mode of file
if (not chmod($Mode, $File)) {
&ISPPower_Log("Unable to change permissions of file $File");
return 0;
}
# Change ownership of file
if (not chown($Uid, $Gid, $File)) {
&ISPPower_Log("Unable to change ownership of file $File");
return 0;
}
return 1;
}
#----------------------------------------------------------------
# Purpose: Delete a file.
# Returns: Returns 1 if the operation is successful, 0 if
# the file is busy, or -1 if there is an error.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub DeleteFile {
my($File, $Timeout) = @_;
my($EndTime);
# Does file not exist?
if (not (-e $File)) {
return 1;
}
# Open file
if (not open(FILE, $File)) {
&ISPPower_Log("Unable to open file $File");
return -1;
}
# Calculate ending time
$EndTime = time + $Timeout;
# Loop until file is free or ending time reached
for (;;) {
# Lock file
if (flock(FILE, $LOCK_EX | $LOCK_NB)) {
last;
}
# Has ending time been reached?
if (time >= $EndTime) {
close(FILE);
return 0;
}
# Wait and process messages
&ISPPower_Wait(1);
}
# Delete file
if (not unlink($File)) {
&ISPPower_Log("Unable to delete file $File");
close(FILE);
return -1;
}
# Close file
close(FILE);
return 1;
}
#----------------------------------------------------------------
# Purpose: Get the mode of a file.
# Returns: Returns the file mode (permissions).
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub GetFileMode {
my($File) = @_;
return ((stat($File))[2] & 07777);
}
#================================================================
# Parameter File Routines
#================================================================
#----------------------------------------------------------------
# Purpose: Load parameter file settings.
# Returns: Returns 1 if the operation is successful or 0
# otherwise.
# History:
# 06/13/97 BMK Released.
#----------------------------------------------------------------
sub LoadParmSettings {
my($ParmFile, $ParmArray) = @_;
my($Line, $Parm, $Value);
# Was a parameter file not specified?
if ($ParmFile eq "") {
&ISPPower_Log("Parameter file not specified");
return 0;
}
# Does parameter file not exist?
if (not (-e $ParmFile)) {
return 0;
}
# Open parameter file
if (not open(PARM, $ParmFile)) {
&ISPPower_Log("Unable to open parameter file $ParmFile");
return 0;
}
# Read file
while ($Line = <PARM>) {
# Strip end-of-line character(s)
chomp($Line);
# Extract parameter and value
if (($Parm, $Value) = ($Line =~ (/^\s*([^=]+)=\s*(.*)/))) {
# Strip trailing whitespace
$Parm =~ s/\s*$//;
$Value =~ s/\s*$//;
# Add parameter to parameter array
$$ParmArray{$Parm} = $Value;
}
}
# Close file
close(PARM);
return 1;
}
#----------------------------------------------------------------
# Purpose: Save parameter file settings.
# Returns: Returns 1 if the operation is successful or 0
# otherwise.
# History:
# 06/13/97 BMK Released.
#----------------------------------------------------------------
sub SaveParmSettings {
my($ParmFile, $ParmArray) = @_;
my($Parm);
# Was a parameter file not specified?
if ($ParmFile eq "") {
&ISPPower_Log("Parameter file not specified");
return 0;
}
# Open parameter file
if (not open(PARM, ">$ParmFile")) {
&ISPPower_Log("Unable to open parameter file $ParmFile");
return 0;
}
# Output parameter settings
foreach $Parm (sort keys(%$ParmArray)) {
print PARM "$Parm=$$ParmArray{$Parm}\n";
}
# Close file
close(PARM);
return 1;
}
1;
and here is the ISPPower_Shell.pm
#================================================================
# ISP Power Server Control Add-On
# Linux Shell Resource Manager, Version 9809, December 17, 1998
# Copyright (c) 1997, 1998 ISP Power Corporation
# All rights reserved
#================================================================
# This software is licensed for use only as an integral part
# of the ISP Power Server Control Add-On. All other uses are
# prohibited. This software may be modified by a licensed
# end-user for their own internal use however all changes shall
# still be restricted by the original license.
#================================================================
#================================================================
#=======================THIS SCRIPT SHOULD=======================
#======================NOT NEED TO BE EDITED=====================
#================================================================
use strict;
package ISPPower_Shell_Linux;
use ISPPower_Interface;
use ISPPower_Shared_Linux;
# Predefined field names
my($FIELD_SERVICETYPE) = "Service Type";
my($FIELD_LOGIN) = "Login";
my($FIELD_PASSWORD) = "Password";
my($FIELD_NAME) = "Account Name";
# Optionally defined field names
my($FIELD_UID) = "User ID";
my($FIELD_GID) = "Group ID";
my($FIELD_HOME) = "Home Directory";
my($FIELD_SHELL) = "Shell";
my($FIELD_MAIL) = "Mail File";
# Defaults
# Default gid to use for user accounts
my($DEFAULT_GID) = 100;
# Default base directory to use for user home
# directories
my($DEFAULT_HOME_BASE) = "/home";
# Default skeleton directory to use as a model
# for new user home directories
my($DEFAULT_HOME_SKELETON) = "/etc/skel";
# Default shell
my($DEFAULT_SHELL) = "csh";
# Default base directory to use for user mail files
my($DEFAULT_MAIL_BASE) = "/var/spool/mail";
# Default mode for user mail files
my($DEFAULT_MAIL_MODE) = 0600;
# Closed service settings
# Closed service settings
# Uid to use for closed accounts
my($CLOSED_UID) = 65535;
# Gid to use for closed accounts
my($CLOSED_GID) = 100;
# Mode to use for the files and directories owned
# by closed accounts
my($CLOSED_MODE) = 0600;
# PASSWORD TIMEOUT
# Time-out interval in seconds; how long server should
# wait to lock password files before aborting operation
# and returning an error status
my($PASSWORD_TIMEOUT) = 60;
# Time-out interval in seconds; how long the server should
# wait to delete a user POP mail file before aborting
# operation and returning an error status
my($POP_TIMEOUT) = 300;
# Format string to use for creating the pathname to user POP
# mail files
my($POP_FORMAT) = "/var/spool/mail/.%s.pop";
# Rhosts filename
my($RHOSTS_FILE) = ".rhosts";
# Rhosts backup filename
my($RHOSTS_BACKUP) = ".rhosts.bak";
#================================================================
#==================IF MODIFICATIONS MADE, DO NOT=================
#=========================EDIT BELOW THIS========================
#================================================================
#================================================================
# Object Methods
#================================================================
#----------------------------------------------------------------
# Purpose: Create a new object.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub new {
my($Class) = shift;
my($Self) = {};
bless $Self, $Class;
return $Self;
}
#----------------------------------------------------------------
# Purpose: Initialize object.
# Returns: Returns 1 if the operation is successful or 0
# otherwise.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub Initialize {
my($Time) = @_;
# Load shells
if (not &LoadShell($Time)) {
return 0;
}
return 1;
}
#----------------------------------------------------------------
# Purpose: Terminate object.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub Terminate {
}
#----------------------------------------------------------------
# The following object methods all share common inputs, outputs,
# and return values:
#
# Inputs: $EventID - Event ID
# $ServiceArray - Reference to associative array
# for service info
# $ChangesArray - Reference to associative array
# for field changes
# Outputs: $UpdatesArray - Reference to associative array
# for returning updates
# $NoteRef - Reference to note describing
# processing result
# Returns: Returns a status code which may be one of the
# following:
#
# SUCCESS - Message processed successfully
# WARNING - Message processed with warning
# FAIL - Message could not be processed
# IGNORED - Message ignored
#----------------------------------------------------------------
#----------------------------------------------------------------
# Purpose: Open a new service.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub Open {
my($Self) = shift;
my($EventID, $ServiceArray, $UpdatesArray, $NoteRef) = @_;
my($Login, $Password, $Name, $Uid, $Gid, $Home, $Shell, $Mail);
# Is login not specified?
if (($Login = $$ServiceArray{$FIELD_LOGIN}) eq "") {
$$NoteRef = "Login is not specified";
return FAIL;
}
# Is password not specified?
if (($Password = $$ServiceArray{$FIELD_PASSWORD}) eq "") {
$$NoteRef = "Password is not specified";
return FAIL;
}
# Get other fields
$Name = $$ServiceArray{$FIELD_NAME};
$Uid = $$ServiceArray{$FIELD_UID};
$Gid = $$ServiceArray{$FIELD_GID};
$Home = $$ServiceArray{$FIELD_HOME};
$Shell = $$ServiceArray{$FIELD_SHELL};
$Mail = $$ServiceArray{$FIELD_MAIL};
# Use defaults if not specified
if ($Uid eq "") {
$Uid = &GetNextUid();
$$UpdatesArray{$FIELD_UID} = $Uid;
}
if ($Gid eq "") {
$Gid = $DEFAULT_GID;
$$UpdatesArray{$FIELD_GID} = $Gid;
}
if ($Home eq "") {
$Home = "$DEFAULT_HOME_BASE/$Login";
$$UpdatesArray{$FIELD_HOME} = $Home;
}
if ($Shell eq "") {
$Shell = $DEFAULT_SHELL;
$$UpdatesArray{$FIELD_SHELL} = $Shell;
}
if ($Mail eq "") {
$Mail = "$DEFAULT_MAIL_BASE/$Login";
$$UpdatesArray{$FIELD_MAIL} = $Mail;
}
# Check mail file
if (not &CheckFile($Mail)) {
$$NoteRef = "Mail file $Mail is invalid";
return FAIL;
}
if (-e $Mail) {
$$NoteRef = "Mail file $Mail already exists";
return FAIL;
}
# Add user
if ($$NoteRef = &AddUser($Login, $Password, $Name, $Uid, $Gid, $Home,
$Shell)) {
return FAIL;
}
# Create home directory
if (not &CopyDirectory($Uid, $Gid, $DEFAULT_HOME_SKELETON, $Home, 1)) {
$$NoteRef = "Unable to create home directory $Home";
return FAIL;
}
# Create mail file
if (not &CreateFile($Uid, $Gid, $DEFAULT_MAIL_MODE, $Mail)) {
$$NoteRef = "Unable to create mail file $Mail";
return FAIL;
}
return SUCCESS;
}
#----------------------------------------------------------------
# Purpose: Modify an existing service.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub Modify {
my($Self) = shift;
my($EventID, $ServiceArray, $ChangesArray, $UpdatesArray, $NoteRef) =
@_;
my($OldLogin, $NewLogin, $Password, $Status);
# Is old login not specified?
if (($OldLogin = $$ServiceArray{$FIELD_LOGIN}) eq "") {
$$NoteRef = "Old login is not specified";
return FAIL;
}
# Does old login not exist?
if (not &LoginExists($OldLogin)) {
$$NoteRef = "Old login does not exist";
return FAIL;
}
# Perform changes
if (($Status = &PerformChanges($ServiceArray, $ChangesArray,
$UpdatesArray, $NoteRef)) ne SUCCESS) {
return $Status;
}
return SUCCESS;
}
#----------------------------------------------------------------
# Purpose: Close an existing service.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub Close {
my($Self) = shift;
my($EventID, $ServiceArray, $ChangesArray, $UpdatesArray, $NoteRef) =
@_;
my($Login, $Home, $Mail, $POPFile);
# Is login not specified?
if (($Login = $$ServiceArray{$FIELD_LOGIN}) eq "") {
$$NoteRef = "Login is not specified";
return FAIL;
}
# Does login not exist?
if (not &LoginExists($Login)) {
$$NoteRef = "Login does not exist";
return FAIL;
}
# Get home directory and mail file
$Home = &GetPasswordField($Login, "Home");
if (($Mail = $$ServiceArray{$FIELD_MAIL}) eq "") {
$Mail = "$DEFAULT_MAIL_BASE/$Login";
}
# Check home directory and mail file
if (not (-e $Home)) {
$$NoteRef = "Home directory $Home does not exist";
return FAIL;
}
if (not (-e $Mail)) {
$$NoteRef = "Mail file $Mail does not exist";
return FAIL;
}
# Delete user
if ($$NoteRef = &DeleteUser($Login)) {
return FAIL;
}
# Change mode and ownership of home directory
if (not chmod($CLOSED_MODE, $Home)) {
$$NoteRef = "Unable to change permissions of home directory $Home";
return FAIL;
}
if (not chown($CLOSED_UID, $CLOSED_GID, $Home)) {
$$NoteRef = "Unable to change ownership of home directory $Home";
return FAIL;
}
# Backup home directory
if (($Home = &BackupDirectory($Home)) eq "") {
$$NoteRef = "Unable to backup home directory $Home";
return FAIL;
}
# Format POP filename
$POPFile = sprintf($POP_FORMAT, $Login);
# Delete POP file to make sure there is no active POP session
if (&DeleteFile($POPFile, $POP_TIMEOUT) <= 0) {
$$NoteRef = "Unable to delete POP file $POPFile";
return FAIL;
}
# Change mode and ownership of mail file
if (not chmod($CLOSED_MODE, $Mail)) {
$$NoteRef = "Unable to change permissions of mail file $Mail";
return FAIL;
}
if (not chown($CLOSED_UID, $CLOSED_GID, $Mail)) {
$$NoteRef = "Unable to change ownership of mail file $Mail";
return FAIL;
}
# Backup mail file
if (($Mail = &BackupFile($Mail)) eq "") {
$$NoteRef = "Unable to backup mail file $Mail";
return FAIL;
}
# Return updated fields
$$UpdatesArray{$FIELD_HOME} = $Home;
$$UpdatesArray{$FIELD_MAIL} = $Mail;
return SUCCESS;
}
#----------------------------------------------------------------
# Purpose: Suspend an existing service.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub Suspend {
my($Self) = shift;
my($EventID, $ServiceArray, $ChangesArray, $UpdatesArray, $NoteRef) =
@_;
my($Login, $Home, $Status);
# Is login not specified?
if (($Login = $$ServiceArray{$FIELD_LOGIN}) eq "") {
$$NoteRef = "Login is not specified";
return FAIL;
}
# Perform changes
if (($Status = &PerformChanges($ServiceArray, $ChangesArray,
$UpdatesArray, $NoteRef)) ne SUCCESS) {
return $Status;
}
# Suspend user
if ($$NoteRef = &SuspendUser($Login)) {
return FAIL;
}
# Get home directory
$Home = &GetPasswordField($Login, "Home");
# Does rhosts file exist?
if (-e $Home . "/" . $RHOSTS_FILE) {
# Does backup file already exist?
if (-e $Home . "/" . $RHOSTS_BACKUP) {
# Delete file
if (not unlink($Home . "/" . $RHOSTS_BACKUP)) {
$$NoteRef = "Unable to delete rhosts backup file
$RHOSTS_BACKUP";
return FAIL;
}
}
# Rename file to prevent its use
if (not rename($Home . "/" . $RHOSTS_FILE, $Home . "/" .
$RHOSTS_BACKUP)) {
$$NoteRef = "Unable to rename rhosts file $RHOSTS_FILE";
return FAIL;
}
}
return SUCCESS;
}
#----------------------------------------------------------------
# Purpose: Unsuspend an existing service.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub Unsuspend {
my($Self) = shift;
my($EventID, $ServiceArray, $ChangesArray, $UpdatesArray, $NoteRef) =
@_;
my($Login, $Status);
# Is login not specified?
if (($Login = $$ServiceArray{$FIELD_LOGIN}) eq "") {
$$NoteRef = "Login is not specified";
return FAIL;
}
# Unsuspend user
if ($$NoteRef = &UnsuspendUser($Login)) {
return FAIL;
}
# Perform changes
if (($Status = &PerformChanges($ServiceArray, $ChangesArray,
$UpdatesArray, $NoteRef)) ne SUCCESS) {
return $Status;
}
return SUCCESS;
}
#================================================================
# Private Routines
#================================================================
#----------------------------------------------------------------
# Purpose: Perform changes to service.
# History:
# 06/15/97 BMK Released.
#----------------------------------------------------------------
sub PerformChanges {
my($ServiceArray, $ChangesArray, $UpdatesArray, $NoteRef) = @_;
my($OldLogin, $OldHome, $OldMail);
my($NewLogin, $Password, $Name, $Uid, $Gid, $NewHome, $Shell, $NewMail);
my($POPFile);
# Is old login not specified?
if (($OldLogin = $$ServiceArray{$FIELD_LOGIN}) eq "") {
$$NoteRef = "Old login is not specified";
return FAIL;
}
# Get old home directory and mail file
$OldHome = &GetPasswordField($OldLogin, "Home");
if (($OldMail = $$ServiceArray{$FIELD_MAIL}) eq "") {
$OldMail = "$DEFAULT_MAIL_BASE/$OldLogin";
}
# Get other account info
$$UpdatesArray{$FIELD_UID} = &GetPasswordField($OldLogin, "UID");
$$UpdatesArray{$FIELD_GID} = &GetPasswordField($OldLogin, "GID");
$$UpdatesArray{$FIELD_SHELL} = &GetPasswordField($OldLogin, "Shell");
# Get changes
$NewLogin = $$ChangesArray{$FIELD_LOGIN};
$Password = $$ChangesArray{$FIELD_PASSWORD};
$Name = $$ChangesArray{$FIELD_NAME};
$Uid = $$ChangesArray{$FIELD_UID};
$Gid = $$ChangesArray{$FIELD_GID};
$NewHome = $$ChangesArray{$FIELD_HOME};
$Shell = $$ChangesArray{$FIELD_SHELL};
$NewMail = $$ChangesArray{$FIELD_MAIL};
# Has login changed?
if (($NewLogin ne "") && ($NewLogin ne $OldLogin)) {
# Was a new home directory not specified?
if ($NewHome eq "") {
# Set new home directory from old home directory
$NewHome = $OldHome;
$NewHome =~ s#\/$OldLogin$#\/$NewLogin#;
}
# Was new mail file not specified?
if ($NewMail eq "") {
# Set new mail file from old mail file
$NewMail = $OldMail;
$NewMail =~ s#\/$OldLogin$#\/$NewLogin#;
}
}
# Has home directory changed?
if (($NewHome ne "") && ($NewHome ne $OldHome)) {
# Does old home directory not exist?
if (not (-e $OldHome)) {
$$NoteRef = "Old home directory $OldHome does not exist";
return FAIL;
}
# Does new home directory already exist?
if (-e $NewHome) {
$$NoteRef = "New home directory $NewHome already exists";
return FAIL;
}
}
# Has mail file changed?
if (($NewMail ne "") && ($NewMail ne $OldMail)) {
# Does old mail file not exist?
if (not (-e $OldMail)) {
$$NoteRef = "Old mail file $OldMail does not exist";
return FAIL;
}
# Does new mail already exist?
if (-e $NewMail) {
$$NoteRef = "New mail file $NewMail already exists";
return FAIL;
}
}
# Modify user
if ($$NoteRef = &ModifyUser($OldLogin, $NewLogin, $Password, $Name,
$Uid, $Gid, $NewHome, $Shell)) {
return FAIL;
}
# Has home directory changed?
if (($NewHome ne "") && ($NewHome ne $OldHome)) {
# Rename home directory
if (not rename($OldHome, $NewHome)) {
$$NoteRef = "Unable to rename home directory $OldHome to
$NewHome";
return FAIL;
}
# Return new home directory
$$UpdatesArray{$FIELD_HOME} = $NewHome;
} else {
# Return old home directory
$$UpdatesArray{$FIELD_HOME} = $OldHome;
}
# Has mail file changed?
if (($NewMail ne "") && ($NewMail ne $OldMail)) {
# Format POP filename
$POPFile = sprintf($POP_FORMAT, $OldLogin);
# Delete POP file to make sure there is no active POP session
if (&DeleteFile($POPFile, $POP_TIMEOUT) <= 0) {
$$NoteRef = "Unable to delete POP file $POPFile";
return FAIL;
}
# Rename mail file
if (not rename($OldMail, $NewMail)) {
$$NoteRef = "Unable to rename mail file $OldMail to $NewMail";
return FAIL;
}
# Return new mail file
$$UpdatesArray{$FIELD_MAIL} = $NewMail;
} else {
# Return old mail file
$$UpdatesArray{$FIELD_MAIL} = $OldMail;
}
return SUCCESS;
}
1;