PNG  IHDR* pHYs+ IDATx]n#; cdLb Ǚ[at¤_:uP}>!Usă cag޿ ֵNu`ݼTâabO7uL&y^wFٝA"l[|ŲHLN밪4*sG3|Dv}?+y߉{OuOAt4Jj.u]Gz*҉sP'VQKbA1u\`& Af;HWj hsO;ogTu uj7S3/QzUr&wS`M$X_L7r2;aE+ώ%vikDA:dR+%KzƉo>eOth$z%: :{WwaQ:wz%4foɹE[9<]#ERINƻv溂E%P1i01 |Jvҗ&{b?9g=^wζXn/lK::90KwrюO\!ջ3uzuGv^;騢wq<Iatv09:tt~hEG`v;3@MNZD.1]L:{ծI3`L(÷ba")Y.iljCɄae#I"1 `3*Bdz>j<fU40⨬%O$3cGt]j%Fߠ_twJ;ABU8vP3uEԑwQ V:h%))LfraqX-ۿX]v-\9I gl8tzX ]ecm)-cgʒ#Uw=Wlێn(0hPP/ӨtQ“&J35 $=]r1{tLuǮ*i0_;NƝ8;-vݏr8+U-kruȕYr0RnC]*ެ(M:]gE;{]tg(#ZJ9y>utRDRMdr9㪩̞zֹb<ģ&wzJM"iI( .ꮅX)Qw:9,i좜\Ԛi7&N0:asϓc];=ΗOӣ APqz93 y $)A*kVHZwBƺnWNaby>XMN*45~ղM6Nvm;A=jֲ.~1}(9`KJ/V F9[=`~[;sRuk]rєT!)iQO)Y$V ی ۤmzWz5IM Zb )ˆC`6 rRa}qNmUfDsWuˤV{ Pݝ'=Kֳbg,UҘVz2ﴻnjNgBb{? ߮tcsͻQuxVCIY۠:(V뺕 ٥2;t`@Fo{Z9`;]wMzU~%UA蛚dI vGq\r82iu +St`cR.6U/M9IENDB`#!/usr/local/cpanel/3rdparty/bin/perl # cpanel - scripts/delpop Copyright 2022 cPanel, L.L.C. # All rights reserved. # copyright@cpanel.net http://cpanel.net # This code is subject to the cPanel license. Unauthorized copying is prohibited package scripts::delpop; use strict; use warnings; use Cpanel::AcctUtils::DomainOwner::Tiny (); use Cpanel::PwCache (); use Cpanel::SafetyBits (); use Cpanel::SafeFile (); use Cpanel::Email::Validate (); use Cpanel::Usage (); use Cpanel::Sys::Setsid::Fast (); use Cpanel::Hooks (); my @attributes = qw{ email user owner domain file }; # call binary run(@ARGV) unless caller(); sub run { my (@args) = @_; my $debug; my $verbose; my $email; my $opts = { email => \$email, debug => \$debug, verbose => \$verbose, }; # compatibility with previous binary version if ( scalar @args == 1 && $args[0] !~ /^\-/ ) { $email = $args[0]; } else { Cpanel::Usage::wrap_options( \@args, \&usage, $opts ); } my $pop = scripts::delpop->new( email => $email || undef ); # interactive fields my $interactive_fields = { email => 'Please enter the pop account to be removed (e.g. bob@sally.com)? ', }; foreach my $field ( sort keys %$interactive_fields ) { while ( !$pop->$field() ) { print $interactive_fields->{$field}; my $input; chomp( $input = ); $pop->$field($input) if length($input); } } Cpanel::Hooks::hook( { 'category' => 'scripts', 'event' => 'delpop', 'stage' => 'pre', }, { 'email' => $email }, ); $pop->delete(); Cpanel::Hooks::hook( { 'category' => 'scripts', 'event' => 'delpop', 'stage' => 'post', }, { 'email' => $email }, ); exit; } sub usage { my $prog = $0; print < Delete the specified email account. --help : display this documentation --email : a valid address email ( format: user\@domain.com ) USAGE exit 1; } sub new { my ( $package, %opts ) = @_; my $self = bless {}, __PACKAGE__; # create accessor and hooks $self->_set_attributes(); # set values map { $self->$_( $opts{$_} ) } keys %opts; return $self; } sub _set_attributes { # call once at first init return unless @attributes; foreach my $att (@attributes) { my $accessor = __PACKAGE__ . "::$att"; # allow symbolic refs to typeglob no strict 'refs'; *$accessor = sub { my ( $self, $v ) = @_; if ( defined $v ) { foreach (qw{before validate set after}) { if ( $_ eq 'set' ) { $self->{$att} = $v; next; } my $sub = '_' . $_ . '_' . $att; if ( defined &{ __PACKAGE__ . '::' . $sub } ) { return unless $self->$sub($v); } } } return $self->{$att}; }; } @attributes = undef; return 1; } sub _validate_email { my ( $self, $email ) = @_; Cpanel::Email::Validate::valid_email($email) or die "'$email' is an invalid email"; return 1; } sub _after_email { my ($self) = @_; # mix validation and before_save :) my ( $user, $domain ) = split( /\@/, $self->email ); $self->user($user); $self->domain($domain); return 1; } # we need to have access to the domain, when setting an owner sub _after_domain { my ($self) = @_; my $owner = Cpanel::AcctUtils::DomainOwner::Tiny::getdomainowner( $self->domain(), { 'default' => '' } ); die "Cannot find the owner of " . $self->domain() . ", try rebuilding /etc/userdomains first with /usr/local/cpanel/scripts/updateuserdomains" unless $owner; $self->owner($owner); return 1; } sub _before_owner { my ( $self, $owner ) = @_; # setuids my ( $uid, $gid ) = ( getpwnam($owner) )[ 2, 3 ]; die "cannot find user ", $owner unless defined $uid && defined $gid; Cpanel::Sys::Setsid::Fast::fast_setsid(); Cpanel::SafetyBits::setuids( $uid, $gid ); # This is very similar to the code in Cpanel::Email::_pop_exists # but it would be a chore to make that module available just for # this script. my $ownerhomedir = ( Cpanel::PwCache::getpwnam($owner) )[7]; die "cannot find home dir for user $owner" unless defined $ownerhomedir; my $file = join '/', $ownerhomedir, 'etc', $self->domain(), 'passwd'; $file =~ s/\.\.//g; $self->file($file); return 1; } sub _before_file { my ( $self, $file ) = @_; die "Unable to determine domain owner's passwd file.\n" unless -e $file; return 1; } sub _after_file { my ($self) = @_; # Untaint the value if ( $self->file() =~ m/^(.*)$/ ) { # direct access to untaint ( to avoid infinite loop ) $self->{file} = $1; } return 1; } sub _check_if_account_exists { my ($self) = @_; my $sflock = Cpanel::SafeFile::safeopen( \*PASSWD, '<', $self->file() ); die "Unable to read from domain owner's passwd file.\n" unless $sflock; my $found; my $user = $self->user(); my $match_regex = qr/^\Q$user\E:/; while ( my $line = ) { chomp $line; if ( $line =~ $match_regex ) { $found = 1; last; } } Cpanel::SafeFile::safeclose( \*PASSWD, $sflock ); die "Account does not exist.\n" unless $found; return 1; } sub delete { my ($self) = @_; $self->_check_if_account_exists(); # perform the deletion $ENV{'REMOTE_USER'} = $self->owner(); system '/usr/local/cpanel/cpanel-email', 'delpop', $self->email(); die "\nEmail account deletion failed ($?)\n" if ( $? != 0 ); print "Deleted " . $self->email() . " for user " . $self->owner() . "\n"; return 1; } 1;