371 lines
13 KiB
Plaintext
371 lines
13 KiB
Plaintext
|
#!/usr/bin/perl -w
|
||
|
#==============================================================================
|
||
|
# lat-users
|
||
|
# =========
|
||
|
# 0.9.0 (2004-09-08)
|
||
|
# (c)2003-2004 Altiplano bvba
|
||
|
#==============================================================================
|
||
|
package esmith;
|
||
|
use strict;
|
||
|
use esmith::db;
|
||
|
use esmith::util;
|
||
|
use Getopt::Long;
|
||
|
use Pod::Usage;
|
||
|
my %conf;
|
||
|
tie %conf, 'esmith::config';
|
||
|
my %accounts;
|
||
|
tie %accounts, 'esmith::config', '/home/e-smith/db/accounts';
|
||
|
my ($Hlp, $Cml, $Frc, $Inp);
|
||
|
my $Add =0;
|
||
|
my $Del =0;
|
||
|
|
||
|
#==============================================================================
|
||
|
# Main
|
||
|
#==============================================================================
|
||
|
# Analyze commandline options
|
||
|
GetOptions ("help" => \$Hlp,
|
||
|
"add" => \$Add,
|
||
|
"delete" => \$Del,
|
||
|
"force" => \$Frc,
|
||
|
"command-line=s" => \$Cml,
|
||
|
"input-file=s" => \$Inp);
|
||
|
|
||
|
if ( $Hlp ) { &PrintPod(9); exit; }
|
||
|
|
||
|
# We need one argument or the other, but not both
|
||
|
if ((($Cml && $Inp) || (! $Cml && ! $Inp)) ||
|
||
|
($Add + $Del != 1))
|
||
|
{ &PrintPod(1); exit; }
|
||
|
|
||
|
my @records;
|
||
|
if ($Inp) {
|
||
|
open(LIST,"< $Inp") || die "Can't find $Inp.\n";
|
||
|
@records = grep(!/(^\s*#)|(^\s*$)/,<LIST>);
|
||
|
close(LIST); }
|
||
|
elsif ($Cml) { @records=($Cml); }
|
||
|
else { &PrintPod(1); exit; }
|
||
|
|
||
|
# Add ibays
|
||
|
if ($Add) {
|
||
|
# Process each ibay
|
||
|
foreach my $record (@records)
|
||
|
{
|
||
|
my @fields=split(/\|/,$record);
|
||
|
for (my $cnt=0; $cnt <= $#fields; ++$cnt) { for ($fields[$cnt]) { s/^\s+//; s/\s+$//; }}
|
||
|
my $ibayname = $fields[0];
|
||
|
my $password = ""; if ($fields[5]) { $password = $fields[5] }
|
||
|
|
||
|
my $uid;
|
||
|
if ($fields[7]) { $uid = $fields[7]; }
|
||
|
else { $uid = &FindUid;}
|
||
|
if (&TestUid($uid)) {
|
||
|
my %ibay;
|
||
|
if ( $fields[1] ) { $ibay{'Name'} = $fields[1] } else { $ibay{'Name'} = $ibayname }
|
||
|
if ( $fields[2] ) { $ibay{'Group'} = $fields[2] } else
|
||
|
{die "We need a valid group to create '$ibayname'.\a\n";}
|
||
|
if ( $fields[3] ) { $ibay{'UserAccess'} = $fields[3] } else { $ibay{'UserAccess'} = "wr-admin-rd-group" }
|
||
|
if ( $fields[4] ) { $ibay{'PublicAccess'} = $fields[4] } else { $ibay{'PublicAccess'} = "local-pw" }
|
||
|
if ( $fields[5] ) { $ibay{'PasswordSet'} = "yes" } else { $ibay{'PasswordSet'} = "no" }
|
||
|
if ( $fields[6] ) { $ibay{'CgiBin'} = $fields[6] } else { $ibay{'CgiBin'} = "disabled" }
|
||
|
$ibay{'Uid'} = $uid;
|
||
|
$ibay{'Gid'} = $uid;
|
||
|
|
||
|
if (&ValidArguments(\%ibay, $ibayname, $password)) {
|
||
|
print "Creating ibay '$ibayname' (Uid:$uid).\n";
|
||
|
db_set(\%accounts, $ibayname, 'ibay', \%ibay);
|
||
|
system("/sbin/e-smith/signal-event", "ibay-create", $ibayname) == 0 or
|
||
|
die ("An error occurred while creating ibay '$ibayname'.\n");
|
||
|
# Set password
|
||
|
if ($ibay{'PasswordSet'} eq 'yes') { esmith::util::setIbayPassword($ibayname, $password); }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# Delete ibays
|
||
|
if ($Del) {
|
||
|
&ExpandWildCard; # Check for wildcards and expand if necessary
|
||
|
foreach my $record (@records)
|
||
|
{
|
||
|
my @fields=split(/\|/,$record);
|
||
|
for (my $cnt=0; $cnt <= $#fields; ++$cnt) { for ($fields[$cnt]) { s/^\s+//; s/\s+$//; }}
|
||
|
my $ibayname = $fields[0];
|
||
|
my $password = ""; if ($fields[5]) { $password = $fields[5] }
|
||
|
|
||
|
if ((db_get(\%accounts, $ibayname)) &&
|
||
|
(db_get_type(\%accounts, $ibayname)) eq "ibay") {
|
||
|
my $yn = 'yes';
|
||
|
if (! $Frc) {
|
||
|
print "Do you want to delete ibay '$ibayname'?\n";
|
||
|
print "All files in this ibay will be deleted! [yes/NO/all] ";
|
||
|
$yn = <STDIN>;
|
||
|
if ($yn =~ /^a/i) { $Frc = -1; $yn="yes"; }
|
||
|
}
|
||
|
if ($yn =~ /^y/i) {
|
||
|
print "Deleting ibay '$ibayname'.\n";
|
||
|
db_delete(\%accounts, $ibayname);
|
||
|
system("/sbin/e-smith/signal-event", "ibay-delete", $ibayname) == 0
|
||
|
or die ("An error occurred while deleting ibay '$ibayname'.\n");
|
||
|
}
|
||
|
}
|
||
|
else { print "Can't find ibay '$ibayname'.\n\a";}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#==============================================================================
|
||
|
# Subroutines
|
||
|
#==============================================================================
|
||
|
# Find an unused Uid/Gid
|
||
|
sub FindUid {
|
||
|
open(ACC,"/home/e-smith/db/accounts") || die "Can't find /home/e-smith/db/accounts";
|
||
|
my @recs = grep(/Uid\|\d*/,<ACC>);
|
||
|
close(ACC);
|
||
|
open(PWD,"/etc/passwd") || die "Can't find /etc/passwd";
|
||
|
my @pwds = grep(/\:\d*\:/,<PWD>);
|
||
|
close(PWD);
|
||
|
open(GRP,"/etc/group") || die "Can't find /etc/group";
|
||
|
my @grps = grep(/\:\d*\:/,<GRP>);
|
||
|
close(GRP);
|
||
|
|
||
|
my $newuid=db_get(\%conf, 'MinUid');
|
||
|
do { ++$newuid;} until ((! grep(/Uid\|$newuid\D/,@recs)) &&
|
||
|
(! grep(/\:$newuid\:/,@pwds)) &&
|
||
|
(! grep(/\:$newuid\:/,@grps)));
|
||
|
return $newuid;
|
||
|
}
|
||
|
#==============================================================================
|
||
|
# Test the uid/gid for availability and legality
|
||
|
sub TestUid {
|
||
|
open(ACC,"/home/e-smith/db/accounts") || die "Can't find /home/e-smith/db/accounts";
|
||
|
my @recs = grep(/Uid\|\d*/,<ACC>);
|
||
|
close(ACC);
|
||
|
open(PWD,"/etc/passwd") || die "Can't find /etc/passwd";
|
||
|
my @pwds = grep(/\:\d*\:/,<PWD>);
|
||
|
close(PWD);
|
||
|
open(GRP,"/etc/group") || die "Can't find /etc/group";
|
||
|
my @grps = grep(/\:\d*\:/,<GRP>);
|
||
|
close(GRP);
|
||
|
|
||
|
if (! ($_[0] =~ /^\d*$/)) {
|
||
|
print "Error: A user ID should contain only numbers.\a\n";
|
||
|
return 0;
|
||
|
}
|
||
|
elsif ( $_[0] < db_get(\%conf, 'MinUid')) {
|
||
|
print "Error: The user ID should be greater or equal to ".&FindUid."\a\n";
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
elsif ((grep(/Uid\|$_[0]\D/,@recs)) or
|
||
|
(grep(/\:$_[0]\:/,@pwds)) or
|
||
|
(grep(/\:$_[0]\:/,@grps))) {
|
||
|
print "Error: The uid/gid '$_[0]' is already in use\a\n";
|
||
|
return 0;
|
||
|
}
|
||
|
else { return 1 };
|
||
|
}
|
||
|
#==============================================================================
|
||
|
# Test the various arguments for their validity
|
||
|
sub ValidArguments {
|
||
|
my $href = $_[0];
|
||
|
my $nm =$_[1];
|
||
|
my $pw =$_[2];
|
||
|
my $ret = 1;
|
||
|
|
||
|
if (db_get(\%accounts, $nm)) {
|
||
|
print "An account with the name '$nm' already exists on this server.\n\a";
|
||
|
$ret = 0;
|
||
|
}
|
||
|
if ( ! ( $nm =~ /^[a-z][a-z\-\_\d\.]*$/ )) {
|
||
|
print "Can't create ibay '$nm'. ";
|
||
|
print "The name contains illegal characters.\n";
|
||
|
print "The name should contain only lower-case letters, numbers, hyphens, periods and \n";
|
||
|
print "underscores, and should start with a lower-case letter.\n\a";
|
||
|
$ret = 0;
|
||
|
}
|
||
|
if (not defined(db_get(\%accounts, $href->{'Group'})) &&
|
||
|
(db_get_type(\%accounts, $href->{'Group'} ) ne "ibay" )) {
|
||
|
print "Can't create ibay '$href->{'Name'}'. ";
|
||
|
print "The group '".$href->{'Group'}."' does not exist.\n\a";
|
||
|
$ret = 0;
|
||
|
}
|
||
|
if ( ! ($href->{'UserAccess'} =~ /^wr-admin-rd-group$|^wr-group-rd-everyone$|^wr-group-rd-group$/)) {
|
||
|
print "Can't create ibay '$href->{'Name'}'. ";
|
||
|
print "User access must be either 'wr-admin-rd-group', \n'wr-group-rd-everyone' or 'wr-group-rd-group'.\n\a";
|
||
|
$ret = 0;
|
||
|
}
|
||
|
if ( ! ($href->{'PublicAccess'} =~ /^local$|^local-pw$|^global$|^global-pw$|^global-pw-remote|^none$/)) {
|
||
|
print "Can't create ibay '$href->{'Name'}'.\n";
|
||
|
print "Public access must be either 'local', 'local-pw', 'global', 'global-pw', 'global-pw-remote', or 'none'.\n\a";
|
||
|
$ret = 0;
|
||
|
}
|
||
|
if ( ! ($href->{'CgiBin'} =~ /^(disabled)$|^(enabled)$/)) {
|
||
|
print "Can't create ibay '$href->{'Name'}'. ";
|
||
|
print "The CGI-Bin must be either 'disabled' or 'enabled'.\n\a";
|
||
|
$ret = 0;
|
||
|
}
|
||
|
|
||
|
return $ret;
|
||
|
}
|
||
|
#==============================================================================
|
||
|
# Test for wildcards in the ibayname. If any wildecards are found, the array
|
||
|
# @records is expanded with the ibay names that meet the conditions.
|
||
|
sub ExpandWildCard {
|
||
|
my $ctrec = 0;
|
||
|
foreach my $record (@records)
|
||
|
{
|
||
|
my @fld=split(/\|/,$record);
|
||
|
for (my $cnt=0; $cnt <= $#fld; ++$cnt) { for ($fld[$cnt]) { s/^\s+//; s/\s+$//; }}
|
||
|
|
||
|
if ($fld[0] =~ /\*|\?/) { # Does it contain the wildcards?
|
||
|
$fld[0] =~ s/\*/\.\*/g; # Replace * with .* to allow for grep.
|
||
|
$fld[0] =~ s/\?/\./g; # Replace ? with . to allow for grep.
|
||
|
|
||
|
open USRS, "</home/e-smith/db/accounts" or die "Can't open /home/e-smith/db/accounts: $!";
|
||
|
my @match = grep /^$fld[0]\=ibay\|/i, <USRS>;
|
||
|
close(USRS);
|
||
|
|
||
|
my $cu = 0;
|
||
|
foreach my $tst (@match) {
|
||
|
$tst =~ /\=/; $tst = $`;
|
||
|
for (my $cnt=1; $cnt <= $#fld; ++$cnt) { $tst = $tst." | ".$fld[$cnt]; };
|
||
|
if ($cu == 0 ) {
|
||
|
$records[$ctrec] = $tst;
|
||
|
$cu =1;
|
||
|
}
|
||
|
else {
|
||
|
push(@records, $tst);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
++$ctrec;
|
||
|
}
|
||
|
}
|
||
|
#==============================================================================
|
||
|
# Print the pod text as a help screen
|
||
|
sub PrintPod {
|
||
|
my ($verbose, $message) = @_;
|
||
|
pod2usage(-verbose => $verbose, -message => $message, -exitval => 64);
|
||
|
}
|
||
|
|
||
|
#==============================================================================
|
||
|
|
||
|
=pod
|
||
|
|
||
|
=head1 NAME
|
||
|
|
||
|
B<lat-ibays> - The lazy administrator's tool to create ibays
|
||
|
|
||
|
=head1 DESCRIPTION
|
||
|
|
||
|
Creates or deletes ibays on Mitel's SME servers (5.x/6.x).
|
||
|
This tool is functionally equivalent to the 'Information bays' option in the server-manager, but can be run from the command line or called from an other script.
|
||
|
It allows you, for example, to create an i-bay as part of an installation script, or delete i-bays on a remote machine via an ssh console.
|
||
|
|
||
|
See F</usr/doc/lazy-admin-tools/example.ibays> for the format of the input file.
|
||
|
|
||
|
=head1 SYNOPSIS
|
||
|
|
||
|
B<lat-ibays> -a -c "ibay | descr | group | useraccess | publicaccess | password | cgi-bin | uid"
|
||
|
|
||
|
B<lat-ibays> -a -i /path/to/ibays.list
|
||
|
|
||
|
B<lat-ibays> -d [-f] -c "Ibay"
|
||
|
|
||
|
B<lat-ibays> -d [-f] -i /path/to/ibays.list
|
||
|
|
||
|
=head1 OPTIONS
|
||
|
|
||
|
The following options are supported:
|
||
|
|
||
|
=over 4
|
||
|
|
||
|
=item B<-a>, B<--add>
|
||
|
|
||
|
Add an ibay to the server
|
||
|
|
||
|
=item B<-c 'Arguments'>, B<--command-line='Arguments'>
|
||
|
|
||
|
Take arguments from the command line. See below for the various arguments that are accepted.
|
||
|
|
||
|
=item B<-d>, B<--delete>
|
||
|
|
||
|
Delete an ibay from the server. Wildcards (* and ?) are accepted.
|
||
|
|
||
|
=item B<-f>, B<--force>
|
||
|
|
||
|
Don't prompt before deleting.
|
||
|
|
||
|
=item B<-h>, B<--help>
|
||
|
|
||
|
Extended help for this tool
|
||
|
|
||
|
=item B<-i FILE>, B<--input-file=FILE>
|
||
|
|
||
|
Use the information from FILE to create or delete ibays.
|
||
|
|
||
|
=back
|
||
|
|
||
|
=head2 Arguments:
|
||
|
|
||
|
Ibay* : Must contain only lower-case letters, numbers, hyphens,
|
||
|
periods and underscores, and should start with a lower-
|
||
|
case letter. Wildcards (* and ?) can only be used to
|
||
|
delete ibays!
|
||
|
Descr. : Free text description of the ibay.
|
||
|
Group* : Must be an existing group on the server.
|
||
|
UserAccess : wr-admin-rd-group (default)
|
||
|
wr-group-rd-everyone
|
||
|
wr-group-rd-group
|
||
|
PublicAcc. : local (default)
|
||
|
local-pw
|
||
|
global
|
||
|
global-pw
|
||
|
global-pw-remote
|
||
|
none
|
||
|
Passd : Password for the ibay in clear-text (dangerous!).
|
||
|
CGI : enabled
|
||
|
disabled (default)
|
||
|
uid : User ID. If omitted, the first available uid will used.
|
||
|
|
||
|
* mandatory field
|
||
|
|
||
|
=head1 EXAMPLES
|
||
|
|
||
|
B<lat-ibays -a -c "library | Hogwarts' library | griffindor">
|
||
|
|
||
|
Creates the i-bay 'library' for user group 'griffindor'.
|
||
|
|
||
|
B<lat-ibays -a -i "/root/ibays.list">
|
||
|
|
||
|
Creates the i-bays defined in F</root/ibays.list>.
|
||
|
Please refer to F</usr/doc/lazy-admin-tools/example.users> for an example of an input file.
|
||
|
|
||
|
B<lat-ibays -d -f -c "class*">
|
||
|
|
||
|
Deletes all ibays that start with 'class'. All ibays and their files are deleted without prompting (-f).
|
||
|
|
||
|
B<lat-ibays -a -c "library | Hogwarts' library | griffindor | wr-group-rd-group | local-pw | quidditch | enabled | 8003">
|
||
|
|
||
|
Creates the i-bay 'library' for user group 'griffindor'. Password is 'quiddich', cgi is enabled and the group ID is set to 8003.
|
||
|
|
||
|
=head1 SEE ALSO
|
||
|
|
||
|
lat-group(8), lat-pseudonyms(8), lat-users(8), lat-quota(8), lat-domains(8), lat-hosts(8), lat-procmail(8), lat-pptp(8), lat-dump(8)
|
||
|
|
||
|
=head1 VERSION
|
||
|
|
||
|
Version 0.9.0 (2004-09-08). The latest version is hosted at B<http://www.contribs.org/contribs/mblotwijk/>
|
||
|
|
||
|
=head1 COPYRIGHT
|
||
|
|
||
|
(c)2003-2004, Altiplano bvba (B<http://www.altiplano.be>). Released under the terms of the GNU license.
|
||
|
|
||
|
|
||
|
=head1 BUGS
|
||
|
|
||
|
Please report bugs to <Bugs@Altiplano.Be>
|
||
|
|
||
|
=cut
|
||
|
|
||
|
#==============================================================================
|