MOON
Server: Apache/2.2.31 (Unix) mod_ssl/2.2.31 OpenSSL/0.9.8e-fips-rhel5 mod_bwlimited/1.4
System: Linux csr818.wilogic.com 2.6.18-419.el5xen #1 SMP Fri Feb 24 22:50:37 UTC 2017 x86_64
User: digitals (531)
PHP: 5.4.45
Disabled: NONE
Upload Files
File: //scripts.20110531.215904.25158/realadduser
#!/usr/bin/perl
# cpanel - realadduser                            Copyright(c) 2010 cPanel, Inc.
#                                                           All rights Reserved.
# copyright@cpanel.net                                         http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited

BEGIN {
    $ENV{'LANG'} = 'C';
    unshift @INC, '/usr/local/cpanel';
}

use strict;
use Cpanel::OSSys;
use Fcntl              ();
use Cpanel::RcsRecord  ();
use Cpanel::SafeFile   ();
use AcctLock           ();
use Cpanel::Logger     ();
use Cpanel::NSCD       ();
use Cpanel::SafetyBits ();
use Cpanel::Logger     ();

my $logger = Cpanel::Logger->new();

my $mailgid = ( getgrnam('mail') )[2];

my $hasmd5auth = 0;
if ( open my $sysauth_fh, '<', '/etc/pam.d/system-auth' ) {
    while ( my $line = readline $sysauth_fh ) {
        if ( $line =~ m/^password.*md5/ ) {
            $hasmd5auth = 1;
            last;
        }
    }
    close $sysauth_fh;
}

my $system   = ( Cpanel::OSSys::uname() )[0];
my $nochecks = 0;
my $shell    = 0;
my $debug    = 0;

if (@ARGV) {
    while ( my $arg = shift @ARGV ) {
        last if !$arg;
        if ( $arg =~ m/^-+(\S+)/ ) {
            my $flag = $1;
            if ( $flag eq 'nochecks' ) {
                $nochecks = 1;
            }
            elsif ( $flag =~ m/^(no)?shell$/ ) {
                if ($1) {
                    $shell = 'noshell';
                }
                else {
                    $shell = shift @ARGV;
                }
            }
            elsif ( $flag =~ m/debug/i ) {
                $debug = 1;
            }
        }
        else {
            unshift @ARGV, $arg;
            last;
        }
    }
}

my $pwd_mkdb = 'pwd_mkdb';
my $username = $ARGV[0];
my $homeroot = $ARGV[1];
my $pass     = $ARGV[2];
my $myuid      = $ARGV[3];
my $mygid      = $ARGV[4];

if ( !$ARGV[0] ) {
    my $up;
    chomp( $up = <STDIN> );
    my @UP = split( / /, $up );
    $username = $UP[0];
    $homeroot = $UP[1];
    $pass     = $UP[2];
}

if ( !$username ) {
    Cpanel::Logger::logger(
        {
            'message'   => "Syntax: adduser <username> <homeroot> <password>",
            'level'     => 'die',
            'service'   => 'realadduser',
            'output'    => 2,
            'backtrace' => 0,
        }
    );
}
if ( !$homeroot ) {
    Cpanel::Logger::logger(
        {
            'message'   => "Syntax: adduser <username> <homeroot> <password>",
            'level'     => 'die',
            'service'   => 'realadduser',
            'output'    => 2,
            'backtrace' => 0,
        }
    );
}

if ( !-e '/etc/allowstupidstuff' ) {
    if ( $username =~ /^\d+/ ) {
        Cpanel::Logger::logger(
            {
                'message'   => "Invalid username $username. Usernames must not begin with a number.",
                'level'     => 'die',
                'service'   => 'realadduser',
                'output'    => 2,
                'backtrace' => 0,
            }
        );
    }
}

if ( !$shell ) {
    if ( -x '/bin/rstsh' ) {
        $shell = '/bin/rstsh';
    }
    elsif ( -x '/bin/bash' ) {
        $shell = '/bin/bash';
    }
    elsif ( -x '/usr/local/bin/bash' ) {
        $shell = '/usr/local/bin/bash';
    }
    elsif ( -x '/bin/sh' ) {
        $shell = '/bin/sh';
    }
    else {
        Cpanel::Logger::logger(
            {
                'message'   => "No valid shell found. Using /bin/false",
                'level'     => 'warn',
                'service'   => 'realadduser',
                'output'    => 2,
                'backtrace' => 0,
            }
        );
        $shell = '/bin/false';
    }
}
elsif ( $shell eq 'noshell' ) {
    if ( -x '/usr/local/cpanel/bin/noshell' ) {
        $shell = '/usr/local/cpanel/bin/noshell';
    }
    else {
        $shell = '/bin/false';
    }
}

if ($debug) {
    Cpanel::Logger::logger(
        {
            'message'   => "User: $username Home: $homeroot Shell: $shell Checks: $nochecks",
            'level'     => 'debug',
            'service'   => 'realadduser',
            'output'    => 1,
            'backtrace' => 0,
        }
    );
    exit;
}

my $home = $homeroot;
if ( !-e $home ) {
    mkdir( $home, 0755 );
}

if ( $pass eq '' ) {
    Cpanel::Logger::logger(
        {
            'message'   => "No password specified for $username",
            'level'     => 'info',
            'service'   => 'realadduser',
            'output'    => 1,
            'backtrace' => 0,
        }
    );
    $pass = '*';
}

my $minuid = 500;
my $mingid = 500;
my $maxuid = 32000;
my $maxgid = 32000;

# Set minuid according to /etc/wwwacct.conf
if ( open my $wwwacct_fh, '<', '/etc/wwwacct.conf' ) {
    while ( my $line = readline $wwwacct_fh ) {
        chomp $line;
        next if $line =~ m/^;/;
        if ( $line =~ m/^\s*MINUID\s+(\d+)/ ) {
            $minuid = $1;
        }
    }
    close $wwwacct_fh;
    if ( int($minuid) < 1 ) {
        $minuid = 500;
    }
    if ( $minuid < 100 ) {
        $minuid = 100;
    }
}

my $username_nodash = $username;
if ( !$nochecks ) {
    $username_nodash =~ s/-//g;
}
my @UIDS;
my @GIDS;

if ( -e '/etc/master.passwd' ) {
    Cpanel::RcsRecord::rcsrecord( '/etc/master.passwd', "BEGIN realadduser user $username" );
}
else {
    Cpanel::RcsRecord::rcsrecord( '/etc/shadow', "BEGIN realadduser user $username" );
}
Cpanel::RcsRecord::rcsrecord( '/etc/passwd', "BEGIN realadduser user $username" );

AcctLock::acctlock();

my $passwdlock = Cpanel::SafeFile::safeopen( \*PASSWD, '+<', '/etc/passwd' );
if( !$passwdlock ) {
    $logger->die("Could not edit /etc/passwd");
}
while (<PASSWD>) {
    my ( $user, undef, $uid, $gid, undef, undef ) = split( /:/, $_, 5 );
    if ( $user eq $username ) {
        Cpanel::SafeFile::safeclose( \*PASSWD, $passwdlock );
        AcctLock::acctunlock();
        Cpanel::Logger::logger(
            {
                'message'   => "User $username already exists",
                'level'     => 'die',
                'service'   => 'realadduser',
                'output'    => 2,
                'backtrace' => 0,
            }
        );
    }
    elsif ( !$nochecks ) {
        my $user_nodash = $user;
        $user_nodash =~ s/-//g;
        if ( $user_nodash eq $username_nodash ) {
            Cpanel::SafeFile::safeclose( \*PASSWD, $passwdlock );
            AcctLock::acctunlock();
            if ( $user =~ m/-/ ) {
                Cpanel::Logger::logger(
                    {
                        'message'   => "Username $username with a dash already exists",
                        'level'     => 'die',
                        'service'   => 'realadduser',
                        'output'    => 2,
                        'backtrace' => 0,
                    }
                );
            }
            elsif ( $username =~ m/-/ ) {
                Cpanel::Logger::logger(
                    {
                        'message'   => "Username $username without a dash already exists",
                        'level'     => 'die',
                        'service'   => 'realadduser',
                        'output'    => 2,
                        'backtrace' => 0,
                    }
                );
            }
        }
    }
    if ( $uid > $minuid ) {
        push @UIDS, $uid;
    }
    if ( $gid > $mingid ) {
        push @GIDS, $gid;
    }
}

my $grouplock = Cpanel::SafeFile::safeopen( \*GROUP, '+<', '/etc/group' );
if( !$grouplock ) {
    $logger->die("Could not edit /etc/group");
}
while (<GROUP>) {
    my ( $user, undef, $gid, undef ) = split( /:/, $_, 4 );
    if ( $gid > $mingid ) {
        push @GIDS, $gid;
    }
}

if (!$myuid) {
    $myuid   = $maxuid;
    my $lastuid = $maxuid;
    foreach my $uid ( sort { $a <=> $b } @UIDS ) {
        if ( ( $uid - $lastuid ) > 1 ) {
            $myuid = ( $lastuid + 1 );
            last;
        }
        $lastuid = $uid;
    }

    if ( $myuid == $maxuid ) {
        $myuid = ( $lastuid + 1 );
    }
}

if (!$mygid) {
    $mygid   = $maxgid;
    my $lastgid = $maxgid;
    foreach my $gid ( sort { $a <=> $b } @GIDS ) {
        if ( ( $gid - $lastgid ) > 1 ) {
            $mygid = ( $lastgid + 1 );
            last;
        }
        $lastgid = $gid;
    }

    if ( $mygid == $maxgid ) {
        $mygid = ( $lastgid + 1 );
    }
}

if ( -e '/vsrvmgrq' ) {
    my $nextuid = `/usr/local/cpanel/bin/vsrvmgradmin 0 UID`;
    $nextuid =~ s/\n//g;
    if ( $nextuid < 1 ) {
        Cpanel::SafeFile::safeclose( \*PASSWD, $passwdlock );
        Cpanel::SafeFile::safeclose( \*GROUP,  $grouplock );
        AcctLock::acctunlock();
        Cpanel::Logger::logger(
            {
                'message'   => "Unable to get uid from vserver master",
                'level'     => 'die',
                'service'   => 'realadduser',
                'output'    => 2,
                'backtrace' => 0,
            }
        );
    }
    if ( $nextuid !~ /^\d+$/ ) {
        Cpanel::SafeFile::safeclose( \*PASSWD, $passwdlock );
        Cpanel::SafeFile::safeclose( \*GROUP,  $grouplock );
        AcctLock::acctunlock();
        Cpanel::Logger::logger(
            {
                'message'   => "Invalid uid from vserver master!!!",
                'level'     => 'die',
                'service'   => 'realadduser',
                'output'    => 2,
                'backtrace' => 0,
            }
        );
    }
    $myuid = $nextuid;
    $mygid = $nextuid;
}

my $random = '';
open( RANDOM, '/dev/urandom' );
read RANDOM, $random, 4096;
close(RANDOM);
$random =~ s/\W//g;

my $cpass = '';

if ( $pass eq '*' ) {
    $cpass = '*';
}
else {
    $cpass = '';
    if ( -e '/scripts/md5crypt' && $hasmd5auth ) {
        my ( $fd0, $fd1 ) = Cpanel::OSSys::pipe();
        Cpanel::OSSys::write( $fd1, $pass, length($pass) );
        Cpanel::OSSys::write( $fd1, "\n",  length("\n") );
        $cpass = `/scripts/md5crypt $fd0`;
    }
    $cpass =~ s/\n//g;
    if ( $cpass eq '' ) {
        while ( $cpass eq undef or $cpass =~ /:/ ) {
            $cpass = crypt( $pass, $random );
        }
    }
}

my $mytime       = int( time / ( 60 * 60 * 24 ) );
my $passwd       = "${username}:x:${myuid}:${mygid}::${home}/${username}:${shell}\n";
my $masterpasswd = "${username}:${cpass}:${myuid}:${mygid}::0:0::${home}/${username}:${shell}\n";
my $shadow       = "${username}:${cpass}:${mytime}::::::\n";
my $group        = "${username}:x:${mygid}:${username}\n";

if ( $system =~ m/freebsd/i ) {
    system( $pwd_mkdb, '-C', '/etc/master.passwd' );

    # Unlock /etc/passwd
    Cpanel::SafeFile::safeclose( \*PASSWD, $passwdlock );
    my $mpasswdlock = Cpanel::SafeFile::safeopen( \*MPASSWD, '>>', '/etc/master.passwd' );
    if( !$mpasswdlock ) {
        $logger->die("Could not write to /etc/master.passwd");
    }
    print MPASSWD $masterpasswd;
    Cpanel::SafeFile::safeclose( \*MPASSWD, $mpasswdlock );

    system( $pwd_mkdb, '-p', '/etc/master.passwd' );
    if ($?) {
        warn "``$pwd_mkdb'' failed\n";
        Cpanel::SafeFile::safeclose( \*GROUP, $grouplock );
        AcctLock::acctunlock();
        exit( $? >> 8 );
    }
}
else {
    seek( PASSWD, 0, &Fcntl::SEEK_END );
    print PASSWD $passwd;

    my $shadowlock = Cpanel::SafeFile::safeopen( \*SHADOW, '>>', '/etc/shadow' );
    if( !$shadowlock ) {
        $logger->die("Could not write to /etc/shadow");
    }
    print SHADOW $shadow;

    truncate( PASSWD, tell(PASSWD) );

    Cpanel::SafeFile::safeclose( \*PASSWD, $passwdlock );
    Cpanel::SafeFile::safeclose( \*SHADOW, $shadowlock );
}

seek( GROUP, 0, &Fcntl::SEEK_END );
print GROUP $group;

truncate( GROUP, tell(GROUP) );
Cpanel::SafeFile::safeclose( \*GROUP, $grouplock );

AcctLock::acctunlock();

mkdir( $home . '/' . $username, 0711 );
Cpanel::SafetyBits::safe_chown( $myuid, $mygid, $home . '/' . $username );

if ( my $pid = fork() ) {
    waitpid( $pid, 0 );
}
else {
    Cpanel::SafetyBits::setuids($username);
    mkdir( $home . '/' . $username . '/mail', 0770 );
    exit();
}

open( SPOOL, '>', '/var/spool/mail/' . $username );
close(SPOOL);

Cpanel::SafetyBits::safe_chown( $myuid, $mailgid, '/var/spool/mail/' . $username );
Cpanel::SafetyBits::safe_chmod( 0660, $myuid, '/var/spool/mail/' . $username );

if ( $system =~ m/linux/i && -e '/etc/chroothttpd' ) {

    #update http env's passwd
    system( '/usr/local/cpanel/bin/chroothttpd', '--updatefiles' );
}

Cpanel::Logger::logger(
    {
        'message'   => "User $username added",
        'level'     => 'info',
        'service'   => 'realadduser',
        'output'    => 1,
        'backtrace' => 0,
    }
);

if ( -e '/etc/master.passwd' ) {
    Cpanel::RcsRecord::rcsrecord( '/etc/master.passwd', "END realadduser user $username" );
}
else {
    Cpanel::RcsRecord::rcsrecord( '/etc/shadow', "END realadduser user $username" );
}
Cpanel::RcsRecord::rcsrecord( '/etc/passwd', "END realadduser user $username" );

Cpanel::NSCD::clear_cache();