/etc/virtual/limit file

WholesaleDialup

Verified User
Joined
Sep 25, 2004
Messages
178
Location
San Antonio, TX
We have set a limit of 300 emails per user by using the /etc/virtual/limit file as described in the DA knowledgebase.

This is fine except that we have some php scripts which send email to our customers. We need to be able to specify that some users (mainly us) can send more than 300 a day.

Is there a way to set a per user limit rather than just setting it globally? I can't imagine we are the first to need this solution. :confused:
 
Hello,

The limit file is checked using the /etc/exim.pl script.

Near the bottom, there is a function that looks like this:
Code:
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;
}
You can add more users there if you want to exempt them from being counted, eg, say you want to allow adminto sent as many emails as he wants, you'd enter:
Code:
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; }
        if ($name eq "[b]admin[/b]") { return 1; }

        return 0;
}
You can also change the code around however you want (if you know how).. for example, you could edit the "sub check_limits" function (below uid_exempt) and have it read in /etc/virtual/limit.1234 where 1234 is the clients UID number, thus giving you per user limits, etc.. (you'd need a file for each user).. or have it read in /etc/virtual/limits, then check if limits.1234 exists, and overwrite the $email_limit variable if it does.. thus giving you a default (limits) and override (limits.1234) if you want.

John
 
Hello,

The limit file is checked using the /etc/exim.pl script.

Near the bottom, there is a function that looks like this:
Code:
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;
}
You can add more users there if you want to exempt them from being counted, eg, say you want to allow adminto sent as many emails as he wants, you'd enter:
Code:
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; }
        if ($name eq "[b]admin[/b]") { return 1; }

        return 0;
}
You can also change the code around however you want (if you know how).. for example, you could edit the "sub check_limits" function (below uid_exempt) and have it read in /etc/virtual/limit.1234 where 1234 is the clients UID number, thus giving you per user limits, etc.. (you'd need a file for each user).. or have it read in /etc/virtual/limits, then check if limits.1234 exists, and overwrite the $email_limit variable if it does.. thus giving you a default (limits) and override (limits.1234) if you want.

John

THIS IS AN EXCELLENT SPAM FIGHTING TOOL..

Since I am not familiar with SSH and to alleviate the need for paying additional programming fees, may I suggest that a feature like this would be important enough to make it a part of the DA admin panel accessible via the browser and not only SSH...

It would certainly help alleviate the possibility of an individaul using the server to send thousands of spam mails.

It would also eliminate the need for contant moderation of user accounts...
 
Last edited:
Directadmin Support It's ok with ?? :

Code:
sub check_limits
{
	my $count = 0;

[COLOR="Red"][B]	#find the curent user
	$uid = find_uid();[/B][/COLOR]

[COLOR="Red"][B]	if (uid_exempt($uid)) { return "yes"; }[/B][/COLOR]
	open (LIMIT, "/etc/virtual/limit[COLOR="Red"][B].$name[/B][/COLOR]");
	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 "yes"; }

	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");
		}
	}

	my $sender_address = Exim::expand_string('$sender_address');
	my $mid = Exim::expand_string('$message_id');

	log_bandwidth($uid,"type=email&email=$sender_address&method=outgoing&id=$mid");

	return "yes"
}
 
Hello,

You're welcome to modify the file however you wish.

Note the $name variable isn't set until lower down in the code, so you'd need to change it around a bit.

John
 
I thought that $name was turned over by uid_exempt ?

perl isn't for me lol i will try later

thank's :)
 
Slightly OT : User viewable message when over limit?

How would one automatically notify the user when he is over limit?
Currently the script just dies and exim prints the message into the log.
I would like to email them to tell them its over the limit or near the limit.
 
Apart from going in and adding code to the already complicated exim.pl and exim.conf, if it were me, I would just write a cronjob, completely seperate from the exim configs, to run every 10 minutes to check the current limits, and send an email when desired.

John
 
Thanks for the hint. I'll try to mod the exim.pl first as this would be somewhat more efficient as it will only alert users who have reached the limit, instead of a cron to scan all of virtual for users over limit.

Will post mods here if I succeed!
 
Cronjobs actually run very quickly.

Remember that if you send an email to someone who's overlimit, they won't get the email if the email address is in the same server's user account. Be sure to use an email address off the server.

Jeff
 
Hello,

The /etc/virtual/limit is only for outgoing email.

Incoming email is only logged for bandwidth, but is limited by the quotas for that account. Once the inbox is full, no more mail will arrive.

John
 
John wrote:
Once the inbox is full, no more mail will arrive.
I wrote:
Remember that if you send an email to someone who's overlimit, they won't get the email if the email address is in the same server's user account. Be sure to use an email address off the server.
In my mind, these say the same thing. Am I mistaken somewhere?

Thanks.

Jeff
 
In my mind, these say the same thing. Am I mistaken somewhere?

Depends on what you mean by "over the limit" and sending versus receiving.

Over the limit with the limit file prevents a user from sending but not receiving.
Over the limit on quota will prevent the user from receiving but not sending.
 
mmmh sorry i missunderstood prolly.. of course if there is a quota and is full the user dont receive.. i thot you was talkin about the /etc/virtual/limit

just a missunderstood i think, nothing bad ^^
 
Apart from going in and adding code to the already complicated exim.pl and exim.conf, if it were me, I would just write a cronjob, completely seperate from the exim configs, to run every 10 minutes to check the current limits, and send an email when desired.

John

Wouldn't it be possible to include the current number on one of the user pages, maybe the CMD_USER_STATS, so the user can check how much emails he has left?
 
Back
Top