View Full Version : smtp
netmotiv8
11-16-2003, 02:05 PM
Can u disable smtp per user? It is not an option to offer when creating a package. can this be made an option?
As part of our product range we offer 'LITE' hosting packages which do not allow smtp and instead user have to send outgoing mail via their ISP.
DirectAdmin Support
11-17-2003, 12:12 AM
Hello,
That is not a feature that DA supports. It is possible with some perl knowledge, but beyond the scope of this forum (see /etc/exim.pl)
John
chuckd
11-17-2003, 06:32 AM
netmotiv8's post is a little ambiguous, but I read it as asking whether you could disable clients sending mail _through_ their account. This would only be allowed if you were using POP before SMTP or another SMTP authentication protocol. And if you were it should be trivial to disable it for a particular domain no?
nobaloney
11-19-2003, 08:19 AM
No. Definitely not trivial.
Jeff
chuckd
11-19-2003, 03:09 PM
Strange. What does DA use to do POP before SMTP? For me it's a one line mod to the pop-before-smtp Perl script.
nobaloney
11-19-2003, 03:35 PM
Originally posted by chuckd
Strange. What does DA use to do POP before SMTP? For me it's a one line mod to the pop-before-smtp Perl script.
Chuck, I withdraw my "definitely" and look forward to you telling us how to do it :) .
I just don't have the time to investigate it, at least not through the end of the year.
Jeff
DirectAdmin Support
11-19-2003, 11:26 PM
I wrote up a little program which does the checking of the /var/log/maillog file.
It checks for a modification time change every 2 seconds, and when it finds one, it opens the file, jumps to where it last read data, and reads the few new lines and makes the appropriate changes to the /etc/virtual/pophosts file. Because it's only looking for a change in the file "headers" and doesn't open the file unless required, it uses next to no resources. It keeps track of who authenticated when, so that 30 minutes later, their ip will be removed from the file.
It's homemade and hardcoded in superfast c++ :)
John
chuckd
11-20-2003, 03:31 AM
Very nice. Much better than using some of the other monstrosities available.
The pop-before-smtp.pl script is a beautiful example of Perl at its best. Recent versions have got larger due to an expanding user base, but I always remember being shocked by the simplicity of the original versions. Also uses very little resources but obviously couldn't be as lean as your proggy.
markus
11-10-2004, 02:21 PM
hmm... sorry for bumping this old thread.
I'm also interested in disabling SMTP on a per user basis, if possible.
I would like to offer SMTP as add-on, not as a default feature. Or at least a way to disable it for some users.
Is this possible? Is it too difficult to implement?
Thanks
nobaloney
11-11-2004, 04:30 PM
The smtp server, exim, runs either serverwide or not at all. Even if you turn off the daemon it will still be called by programs that want to run it.
You can create a custom exim.conf file that will not forward email (either in or out or both) for specific users. Or you can pay someone to do it for you.
If you wish to do the latter we'd be a good company to check with, since we wrote the exim.conf file DA uses.
Jeff
markus
11-12-2004, 06:46 PM
hmm... I would like to learn how to do it. :cool:
I should say I have no idea about exim/perl.
I've been analizing the exim.conf and exim.pl files, also I've been using the following URL for references:
http://www.exim.org/exim-html-4.40/doc/html/spec.html
Arggg... I hate computers! (I've been working with them since 1986) ;)
Here's my first try: What would happen making the following modifications to exim.conf ?
FIND:
domainlist local_domains = lsearch;/etc/virtual/domains
AFTER ADD:
domainlist local_domains_without_smtp = lsearch;/etc/virtual/domains_without_smtp
FIND:
accept hosts = :
AFTER ADD:
deny domains = +local_domains_without_smtp
Jeff, can you give me a hand on this, please?
resolveit
11-13-2004, 02:08 PM
Originally posted by markus
hmm... I would like to learn how to do it. :cool:
I should say I have no idea about exim/perl.
I've been analizing the exim.conf and exim.pl files, also I've been using the following URL for references:
http://www.exim.org/exim-html-4.40/doc/html/spec.html
Arggg... I hate computers! (I've been working with them since 1986) ;)
Here's my first try: What would happen making the following modifications to exim.conf ?
FIND:
domainlist local_domains = lsearch;/etc/virtual/domains
AFTER ADD:
domainlist local_domains_without_smtp = lsearch;/etc/virtual/domains_without_smtp
FIND:
accept hosts = :
AFTER ADD:
deny domains = +local_domains_without_smtp
Jeff, can you give me a hand on this, please?
Seeing as Jeff offered his services as a PAID service I don't think he would just give you the answer, Pay him a little money (he surely is not an unreasonable man) and get it done right the first time.
Regards,
Onno
markus
11-13-2004, 03:51 PM
Sorry, I'm really confused. Can I expect help from other DA users here? ...or what is this forum all about?
...are you telling me I'm posting in the wrong community?
On the other hand, this might be something for a feature-request as it probably might be of interest to other DA users.
http://www.directadmin.com/forum/showthread.php?s=&threadid=5717
nobaloney
11-13-2004, 05:57 PM
You can get support here from lots of people, including me.
I'm happy to answer all questions I can as time and resources permit.
Right now I'm very busy working for paid clients and on finishing up the VirusBlocker exim.conf file.
And certainly you don't expect me to pay one of our programmers to answer questions here free, do you :rolleyes: ?
Jeff
markus
11-13-2004, 09:35 PM
Certainly, I never said I was willing to pay for this information. I just posted in the hope of getting a bit of help. If you're so busy doing bussiness, well congrats. :D
ok, I noticed a little bug in my previous "try". If anyone wants to give it a try, I believe I got it now.
Create a file /etc/virtual/domains_without_smtp, then insert a line for every local domain you want to deny SMTP access. Look at file /etc/virtual/domains for an example of its syntax. ...or look at this page for more information:
http://www.exim.org/exim-html-4.40/doc/html/spec_38.html
EDIT:
/etc/exim.conf
FIND:
domainlist local_domains = lsearch;/etc/virtual/domains
AFTER ADD:
domainlist local_domains_without_smtp = lsearch;/etc/virtual/domains_without_smtp
FIND:
# Deny unless sender address can be verified:
# This statement requires the sender address to be verified before any
# subsequent ACL statement can be used. If verification fails, the incoming
# recipient address is refused. Verification consists of trying to route the
# address, to see if a bounce message could be delivered to it. In the case of
# remote addresses, basic verification checks only the domain.
require verify = sender
BEFORE ADD:
deny sender_domains = +local_domains_without_smtp
I have made some tests and it seems to work. :rolleyes:
Does anyone see any problem on this approach?
Well, all it needs (if it works) is add an option to manage the contents of the file /etc/virtual/domains_without_smtp from the DA reseller panels or so.
Cheers
markus
11-15-2004, 09:30 PM
ok, my previous attempt also fail as the sender may use a different domain as return path.
So, I guess the only way to achieve this is at SMTP AUTH time, by touching the exim.pl script.
Here's a new attempt:
#
# OPEN:
#
/etc/exim.pl
#
# FIND:
#
open(PASSFILE, "< $homepath/.shadow") || return "no";
$crypted_pass = <PASSFILE>;
close PASSFILE;
#
# AFTER ADD:
#
#+MOD: Is User Domain Allowed to use SMTP
$domain = get_user_domain($username);
if (not is_smtp_allowed($domain)) { return "no"; }
#-MOD: Is User Domain Allowed to use SMTP
#
# FIND:
#
#the username contain a domain, which is now in $domain.
#this is a pure virtual pop account.
open(PASSFILE, "< /etc/virtual/$domain/passwd") || return "no";
#
# BEFORE ADD:
#
#+MOD: Is User Domain Allowed to use SMTP
if (not is_smtp_allowed($domain)) { return "no"; }
#-MOD: Is User Domain Allowed to use SMTP
#
# FIND:
#
sub find_uid_apache
#
# BEFORE ADD:
#
#+MOD: Is User Domain Allowed to use SMTP
sub is_smtp_allowed
{
my ($domain) = @_;
open(DOMAINS,"/etc/virtual/domains_without_smtp");
while (<DOMAINS>)
{
$_ =~ s/\n//;
if ($domain eq $_)
{
return 0;
}
}
close(DOMAINS);
return 1;
}
sub get_user_domain
{
my ($username) = @_;
my $domain="";
open(DOMAINOWNERS,"/etc/virtual/domainowners");
while (<DOMAINOWNERS>)
{
$_ =~ s/\n//;
my ($dmn,$usr) = split(/: /, $_);
if ($usr eq $username)
{
return $dmn;
}
}
close(DOMAINOWNERS);
return -1;
}
#-MOD: Is User Domain Allowed to use SMTP
Here's the whole /etc/exim.pl file already modified:
#!/usr/bin/perl
#smtpauth
#called by exim to verify if an smtp user is allowed to
#send email through the server
#possible success:
# user is in /etc/virtual/domain.com/passwd and password matches
# user is in /etc/passwd and password matches in /etc/shadow
sub smtpauth
{
$username = Exim::expand_string('$1');
$password = Exim::expand_string('$2');
$domain = "";
$unixuser = 1;
if ($username =~ /\@/)
{
$unixuser = 0;
($username,$domain) = split(/\@/, $username);
if ($domain eq "") { return "no"; }
}
if ($unixuser == 1)
{
#the username passed doesn't have a domain, so its a system account
$homepath = (getpwnam($username))[7];
if ($homepath eq "") { return 0; }
open(PASSFILE, "< $homepath/.shadow") || return "no";
$crypted_pass = <PASSFILE>;
close PASSFILE;
#+MOD: Is User Domain Allowed to use SMTP
$domain = get_user_domain($username);
if (not is_smtp_allowed($domain)) { return "no"; }
#-MOD: Is User Domain Allowed to use SMTP
if ($crypted_pass eq crypt($password, $crypted_pass)) { return "yes"; }
else { return "no"; }
}
else
{
#+MOD: Is User Domain Allowed to use SMTP
if (not is_smtp_allowed($domain)) { return "no"; }
#-MOD: Is User Domain Allowed to use SMTP
#the username contain a domain, which is now in $domain.
#this is a pure virtual pop account.
open(PASSFILE, "< /etc/virtual/$domain/passwd") || return "no";
while (<PASSFILE>)
{
($test_user,$test_pass) = split(/:/,$_);
$test_pass =~ s/\n//g; #snip out the newline at the end
if ($test_user eq $username)
{
if ($test_pass eq crypt($password, $test_pass))
{
close PASSFILE;
return "yes";
}
}
}
close PASSFILE;
return "no";
}
return "no";
}
#+MOD: Is User Domain Allowed to use SMTP
sub is_smtp_allowed
{
my ($domain) = @_;
open(DOMAINS,"/etc/virtual/domains_without_smtp");
while (<DOMAINS>)
{
$_ =~ s/\n//;
if ($domain eq $_)
{
return 0;
}
}
close(DOMAINS);
return 1;
}
sub get_user_domain
{
my ($username) = @_;
my $domain="";
open(DOMAINOWNERS,"/etc/virtual/domainowners");
while (<DOMAINOWNERS>)
{
$_ =~ s/\n//;
my ($dmn,$usr) = split(/: /, $_);
if ($usr eq $username)
{
return $dmn;
}
}
close(DOMAINOWNERS);
return -1;
}
#-MOD: Is User Domain Allowed to use SMTP
sub find_uid_apache
{
my ($work_path) = @_;
my @pw;
# $pwd will probably look like '/home/username/domains/domain.com/public_html'
# it may or may not use /home though. others are /usr/home, but it's ultimately
# specified in the /etc/passwd file. We *could* parse through it, but for efficiency
# reasons, we'll only check /home and /usr/home .. if they change it, they can
# manually adjust if needed.
@dirs = split(/\//, $work_path);
foreach $dir (@dirs)
{
# check the dir name for a valid user
# get the home dir for that user
# compare it with the first part of the work_path
if ( (@pw = getpwnam($dir)) )
{
if ($work_path =~/^$pw[7]/)
{
return $pw[2];
}
}
}
return -1;
}
sub get_domain_owner
{
my ($domain) = @_;
my $username="";
open(DOMAINOWNERS,"/etc/virtual/domainowners");
while (<DOMAINOWNERS>)
{
$_ =~ s/\n//;
my ($dmn,$usr) = split(/: /, $_);
if ($dmn eq $domain)
{
return $usr;
}
}
close(DOMAINOWNERS);
return -1;
}
sub find_uid_auth_id
{
# this will be passwed either
# 'username' or 'user@domain.com'
my ($auth_id) = @_;
my $unixuser = 1;
my $domain = "";
my $user = "";
my $username = $auth_id;
my @pw;
if ($auth_id =~ /\@/)
{
$unixuser = 0;
($user,$domain) = split(/\@/, $auth_id);
if ($domain eq "") { return "-1"; }
}
if (!$unixuser)
{
# we need to take $domain and get the user from /etc/virtual/domainowners
# once we find it, set $username
my $u = get_domain_owner($domain);;
if ($u != -1)
{
$username = $u;
}
}
#log_str("username found from $auth_id: $username:\n");
if ( (@pw = getpwnam($username)) )
{
return $pw[2];
}
return -1;
}
sub find_uid_sender
{
my $sender_address = Exim::expand_string('$sender_address');
my ($user,$domain) = split(/\@/, $sender_address);
my $username = get_domain_owner($domain);
if ( (@pw = getpwnam($username)) )
{
return $pw[2];
}
return -1;
}
sub find_uid
{
my $uid = Exim::expand_string('$originator_uid');
my $username = getpwuid($uid);
my $auth_id = Exim::expand_string('$authenticated_id');
my $work_path = $ENV{'PWD'};
if ($username eq "apache" || $username eq "nobody")
{
$uid = find_uid_apache($work_path);
if ($uid != -1) { return $uid; }
}
$uid = find_uid_auth_id($auth_id);
if ($uid != -1) { return $uid; }
# we don't want to rely on this, but it's all thats left.
return find_uid_sender;
}
sub uid_exempt
{
my ($uid) = @_;
if ($uid == 0) { return 1; }
my $name = getpwuid($uid);
if ($name eq "root") { return 1; }
if ($name eq "diradmin") { return 1; }
return 0;
}
#check_limits
#used to enforce limits for the number of emails sent
#by a user. It also logs the bandwidth of the data
#for received mail.
sub check_limits
{
my $count = 0;
open (LIMIT, "/etc/virtual/limit");
my $email_limit = int(<LIMIT>);
close(LIMIT);
#find the curent user
$uid = find_uid();
#log_str("Found uid: $uid\n");
if (uid_exempt($uid)) { return; }
my $name="";
if ($email_limit > 0)
{
#check this users limit
if (($name = getpwuid($uid)))
{
$count = (stat("/etc/virtual/usage/$name"))[7];
if ($count > $email_limit)
{
die("You ($name) have reach your daily email limit of $email_limit emails\n");
}
}
}
open(USAGE, ">>/etc/virtual/usage/$name");
print USAGE "1";
close(USAGE);
chmod (0660, "/etc/virtual/usage/$name");
log_bandwidth($uid);
return "yes"
}
sub log_bandwidth
{
my ($uid) = @_;
my $name = getpwuid($uid);
if (uid_exempt($uid)) { return; }
if ($name eq "") { return; }
my $bytes = Exim::expand_string('$message_size');
if ($bytes == -1) { return; }
open (BYTES, ">>/etc/virtual/usage/$name.bytes");
print BYTES "$bytes\n";
close(BYTES);
chmod (0660, "/etc/virtual/usage/$name.bytes");
}
sub log_str
{
my ($str) = @_;
open (LOG, ">> /tmp/test.txt");
print LOG $str;
close(LOG);
}
Usage of file /etc/virtual/domains_without_smtp is the same, just enter denied domains, one per line.
ClayRabbit
05-25-2005, 10:45 PM
Sorry for bumping old thread, but if it's still actual, you can take a look at my new SMTP Limiter Plugin (http://www.directadmin.com/forum/showthread.php?s=&threadid=8393)
Powered by vBulletin™ Version 4.0.4 Copyright © 2012 vBulletin Solutions, Inc. All rights reserved.