use strict;
use vars qw( @ISA $nossh_hack $conf $dir_prefix @shells $usernamemin
- $usernamemax $passwordmin $username_letter $username_letterfirst
- $username_noperiod
+ $usernamemax $passwordmin $passwordmax
+ $username_ampersand $username_letter $username_letterfirst
+ $username_noperiod $username_uppercase
$shellmachine $useradd $usermod $userdel $mydomain
$cyrus_server $cyrus_admin_user $cyrus_admin_pass
+ $dirhash
$icradius_dbh
@saltset @pw_set);
use Carp;
$usernamemin = $conf->config('usernamemin') || 2;
$usernamemax = $conf->config('usernamemax');
$passwordmin = $conf->config('passwordmin') || 6;
+ $passwordmax = $conf->config('passwordmax') || 8;
if ( $shellmachine ) {
if ( $conf->exists('shellmachine-useradd') ) {
$useradd = join("\n", $conf->config('shellmachine-useradd') )
$username_letter = $conf->exists('username-letter');
$username_letterfirst = $conf->exists('username-letterfirst');
$username_noperiod = $conf->exists('username-noperiod');
+ $username_uppercase = $conf->exists('username-uppercase');
+ $username_ampersand = $conf->exists('username-ampersand');
$mydomain = $conf->config('domain');
if ( $conf->exists('cyrus') ) {
($cyrus_server, $cyrus_admin_user, $cyrus_admin_pass) =
} else {
$icradius_dbh = '';
}
+ $dirhash = $conf->config('dirhash') || 0;
};
@saltset = ( 'a'..'z' , 'A'..'Z' , '0'..'9' , '.' , '/' );
#not needed in 5.004 #srand($$|time);
+sub _cache {
+ my $self = shift;
+ my ( $hashref, $cache ) = @_;
+ if ( $hashref->{'svc_acct_svcnum'} ) {
+ $self->{'_domsvc'} = FS::svc_domain->new( {
+ 'svcnum' => $hashref->{'domsvc'},
+ 'domain' => $hashref->{'svc_acct_domain'},
+ 'catchall' => $hashref->{'svc_acct_catchall'},
+ } );
+ }
+}
+
=head1 NAME
FS::svc_acct - Object methods for svc_acct records
return "Username in use"
if $old->username ne $new->username &&
- qsearchs( 'svc_acct', { 'username' => $new->username } );
+ qsearchs( 'svc_acct', { 'username' => $new->username,
+ 'domsvc' => $new->domsvc,
+ } );
return "Can't change uid!" if $old->uid != $new->uid;
return $error if $error;
my $ulen = $usernamemax || $self->dbdef_table->column('username')->length;
- $recref->{username} =~ /^([a-z0-9_\-\.]{$usernamemin,$ulen})$/
- or return "Illegal username";
- $recref->{username} = $1;
+ if ( $username_uppercase ) {
+ $recref->{username} =~ /^([a-z0-9_\-\.\&]{$usernamemin,$ulen})$/i
+ or return "Illegal username: ". $recref->{username};
+ $recref->{username} = $1;
+ } else {
+ $recref->{username} =~ /^([a-z0-9_\-\.\&]{$usernamemin,$ulen})$/
+ or return "Illegal username: ". $recref->{username};
+ $recref->{username} = $1;
+ }
+
if ( $username_letterfirst ) {
$recref->{username} =~ /^[a-z]/ or return "Illegal username";
} elsif ( $username_letter ) {
if ( $username_noperiod ) {
$recref->{username} =~ /\./ and return "Illegal username";
}
+ unless ( $username_ampersand ) {
+ $recref->{username} =~ /\&/ and return "Illegal username";
+ }
$recref->{popnum} =~ /^(\d*)$/ or return "Illegal popnum: ".$recref->{popnum};
$recref->{popnum} = $1;
return "Only root can have uid 0"
if $recref->{uid} == 0 && $recref->{username} ne 'root';
- $error = $self->ut_textn('finger');
- return $error if $error;
+# $error = $self->ut_textn('finger');
+# return $error if $error;
+ $self->getfield('finger') =~
+ /^([\w \t\!\@\#\$\%\&\(\)\-\+\;\:\'\"\,\.\?\/\*\<\>]*)$/
+ or return "Illegal finger: ". $self->getfield('finger');
+ $self->setfield('finger', $1);
- $recref->{dir} =~ /^([\/\w\-]*)$/
+ $recref->{dir} =~ /^([\/\w\-\.\&]*)$/
or return "Illegal directory";
- $recref->{dir} = $1 ||
- $dir_prefix . '/' . $recref->{username}
- #$dir_prefix . '/' . substr($recref->{username},0,1). '/' . $recref->{username}
+ $recref->{dir} = $1;
+ return "Illegal directory"
+ if $recref->{dir} =~ /(^|\/)\.+(\/|$)/; #no .. component
+ return "Illegal directory"
+ if $recref->{dir} =~ /\&/ && ! $username_ampersand;
+ unless ( $recref->{dir} ) {
+ $recref->{dir} = $dir_prefix . '/';
+ if ( $dirhash > 0 ) {
+ for my $h ( 1 .. $dirhash ) {
+ $recref->{dir} .= substr($recref->{username}, $h-1, 1). '/';
+ }
+ } elsif ( $dirhash < 0 ) {
+ for my $h ( reverse $dirhash .. -1 ) {
+ $recref->{dir} .= substr($recref->{username}, $h, 1). '/';
+ }
+ }
+ $recref->{dir} .= $recref->{username};
;
+ }
unless ( $recref->{username} eq 'sync' ) {
if ( grep $_ eq $recref->{shell}, @shells ) {
unless ( $recref->{_password} );
#if ( $recref->{_password} =~ /^((\*SUSPENDED\* )?)([^\t\n]{4,16})$/ ) {
- if ( $recref->{_password} =~ /^((\*SUSPENDED\* )?)([^\t\n]{$passwordmin,8})$/ ) {
+ if ( $recref->{_password} =~ /^((\*SUSPENDED\* )?)([^\t\n]{$passwordmin,$passwordmax})$/ ) {
$recref->{_password} = $1.$3;
#uncomment this to encrypt password immediately upon entry, or run
#bin/crypt_pw in cron to give new users a window during which their
} elsif ( $recref->{_password} eq '!!' ) {
$recref->{_password} = '!!';
} else {
- return "Illegal password";
+ #return "Illegal password";
+ return "Illegal password: ". $recref->{_password};
}
''; #no error
sub domain {
my $self = shift;
if ( $self->domsvc ) {
- my $svc_domain = qsearchs( 'svc_domain', { 'svcnum' => $self->domsvc } )
+ #$self->svc_domain->domain;
+ my $svc_domain = $self->svc_domain
or die "no svc_domain.svcnum for svc_acct.domsvc ". $self->domsvc;
$svc_domain->domain;
} else {
}
}
+=item svc_domain
+
+Returns the FS::svc_domain record for this account's domain (see
+L<FS::svc_domain>.
+
+=cut
+
+sub svc_domain {
+ my $self = shift;
+ $self->{'_domsvc'}
+ ? $self->{'_domsvc'}
+ : qsearchs( 'svc_domain', { 'svcnum' => $self->domsvc } );
+}
+
=item email
Returns an email address associated with the account.
=cut
sub ssh {
- my @args = @_;
- &Net::SSH::ssh(@args,">>/usr/local/etc/freeside/sshoutput 2>&1");
+ my ( $host, @cmd_and_args ) = @_;
+
+ use IO::File;
+ my $reader = IO::File->new();
+ my $writer = IO::File->new();
+ my $error = IO::File->new();
+
+ &Net::SSH::sshopen3( $host, $reader, $writer, $error, @cmd_and_args) or die $!;
+
+ local $/ = undef;
+ my $output_stream = <$writer>;
+ my $error_stream = <$error>;
+ if ( length $error_stream ) {
+ #warn "[FS::svc_acct::ssh] STDERR $error_stream";
+ die "[FS::svc_acct::ssh] STDERR $error_stream";
+ }
+ if ( length $output_stream ) {
+ warn "[FS::svc_acct::ssh] STDOUT $output_stream";
+ }
+
+# &Net::SSH::ssh(@args,">>/usr/local/etc/freeside/sshoutput 2>&1");
}
=back
=head1 VERSION
-$Id: svc_acct.pm,v 1.43 2001-09-19 19:28:17 ivan Exp $
+$Id: svc_acct.pm,v 1.55 2001-11-05 17:00:41 jeff Exp $
=head1 BUGS