Limit outbound mails by user, domain or server average

This section contains scripts that hMailServer has contributed with. hMailServer 5 is needed to use these.
andyp
Normal user
Normal user
Posts: 191
Joined: 2008-01-18 21:00

Limit outbound mails by user, domain or server average

Post by andyp » 2009-01-12 00:02

MODERATOR EDIT: An updated version of the script below featuring fixes, improvements and file locking handling is available here: http://www.hmailserver.com/forum/viewto ... 20&t=28269

This script limits the outbound emails either by user account or by domain. It also calculates an average over the last x days and when the total amount of outbound emails reaches a defined level the mail is also blocked.

The primary reason for this script is the higher security. If one or some account gets hacked the damage is limited, at least I use the script therefore.

How does user or domain limits work?
You define a general user and domain limit. In a separate file you can also define exceptions for users or domain. The script counts every mail and if the amount reaches the limit a message will be send and the mail will be rejected. You can also define a warning level, when an email is send saying the limits will be reached soon. These mails can be send to the admin or the user.

How does server average limit work?
The script counts the outbound mail of the server and calculates an average over the last x days. When the server passes a threshold factor, let's say 5 times more than the average over the last 20 days the script rejects the mail. An email is send to the admin, also when a warning level is reached.

Have used it the last 20 days and works fine. Installation manual and script itself is in the zip.

version2: tiny error- missing "end sub" at the end of sub outgoing_limitations_send_message

version3: bugfix - outgoingstore file was created with the wrong data positions

version4: instability fix: Division 0 in the average calculation

version5: support of default domains
Attachments
limitsmtp_v5_version5.zip
(5.2 KiB) Downloaded 2743 times
Last edited by andyp on 2009-03-14 09:20, edited 9 times in total.

luci
Normal user
Normal user
Posts: 70
Joined: 2008-02-29 14:29
Location: Romania

Re: Limit outbound mails by user, domain or server average

Post by luci » 2009-01-23 11:09

Very useful, but I did not understood something.
The limit for user/domain is per day?
Radical Image Optimization Tool developer
Project Manager at CRIOSWEB

andyp
Normal user
Normal user
Posts: 191
Joined: 2008-01-18 21:00

Re: Limit outbound mails by user, domain or server average

Post by andyp » 2009-01-23 20:27

Yes, both user/domain and average.

bagalday
New user
New user
Posts: 2
Joined: 2009-02-03 21:25

Re: Limit outbound mails by user, domain or server average

Post by bagalday » 2009-02-03 23:21

This is very useful code. But I couldn't load it :) When the code is loaded, the outboundstore.txt and outboundexceptions.txt files are created. The first record is created in the outboundstore.txt file... Then, nothing happens, no more record is added to the file.

The view of the file:
# SMTP outgoing storage
39847 ali.veli@remed.com.tr 1
39847 @remed.com.tr 1

outboundstoreavg.txt is not created.

And the logs are below.
"03.02.2009 23:20:01" " User has authenticated. User ali.veli@remed.com.tr, Client 88.239.39.30"
"03.02.2009 23:20:01" " SMTP outgoing limitations"
"03.02.2009 23:20:01" " Number of recipients 1"
"03.02.2009 23:20:01" " Reading exceptions file C:\MailServer\Events\outboundexceptions.txt"
"03.02.2009 23:20:01" " Reading storage file C:\MailServer\Events\outboundstore.txt"
"03.02.2009 23:20:02" " User has authenticated. User ali.veli@remed.com.tr, Client 88.239.39.30"
"03.02.2009 23:20:02" " SMTP outgoing limitations"
"03.02.2009 23:20:02" " Number of recipients 1"
"03.02.2009 23:20:02" " Reading exceptions file C:\MailServer\Events\outboundexceptions.txt"
"03.02.2009 23:20:02" " Reading storage file C:\MailServer\Events\outboundstore.txt"
"03.02.2009 23:20:03" " User has authenticated. User ali.veli@remed.com.tr, Client 88.239.39.30"
"03.02.2009 23:20:03" " SMTP outgoing limitations"
"03.02.2009 23:20:03" " Number of recipients 1"
"03.02.2009 23:20:03" " Reading exceptions file C:\MailServer\Events\outboundexceptions.txt"
"03.02.2009 23:20:03" " Reading storage file C:\MailServer\Events\outboundstore.txt"

andyp
Normal user
Normal user
Posts: 191
Joined: 2008-01-18 21:00

Re: Limit outbound mails by user, domain or server average

Post by andyp » 2009-02-04 13:21

outboundstoreavg.txt is only created when the server avg limits activates. So when you reach the warning level or the limit the script stores the date and the kind (Warning / Limit Reached) to avoid sending a lot of msgs to the admin.

My outboundstore.txt looks different. Have you change something in the script?

Usually the amount of emails is before the email or domain!!!

bagalday
New user
New user
Posts: 2
Joined: 2009-02-03 21:25

Re: Limit outbound mails by user, domain or server average

Post by bagalday » 2009-02-08 10:32

There is an error on line 437. "End Sub" tag is forgotten. I have just corrected this. I didn't change anywhere in your code. You can see my public settings:

Public obApp
Public domain_buffer
Public Const ipslocalhost = "0.0.0.0" 'separated by #
Public Const user = "Administrator"
Public Const pw = "xxxxxxxxxxx"
Public Const logspath = "C:\MailServer\Events\" 'ends with a backslash
Public Const write_log_active = true

'User and Domain outgoing limitation
Public Const outgoingstore = "C:\MailServer\Events\outboundstore.txt"
Public Const outgoingexceptions = "C:\MailServer\Events\outboundexceptions.txt"
Public Const outgoingstoreavg = "C:\MailServer\Events\outboundstoreavg.txt"
Public Const max_emails_per_user = 100
Public Const max_emails_per_domain = 300
Public Const warning_factor = 0.8
Public Const server_average_days = 20 ' 0 will deactivate
Public Const server_average_threshold_factor = 10
Public Const warning_factor_avg = 0.6
Public Const msg_admin_warning = True
Public Const msg_admin_passed = True
Public Const msg_user_warning = True
Public Const msg_user_passed = True
Public Const msg_from = "Admin <admin@remed.com.tr>"
Public Const msg_fromaddress = "admin@remed.com.tr"

flesicek
Normal user
Normal user
Posts: 45
Joined: 2005-07-18 12:32
Contact:

Re: Limit outbound mails by user, domain or server average

Post by flesicek » 2009-02-18 16:05

Hi There,

I just install version 2 of the script and this VB error is shown in the hmalserver error log:

"ERROR" 676 "2009-02-18 14:52:24.547" "Script Error: Source: Microsoft VBScript runtime error - Error: 800A000D - Description: Type mismatch: 'CLng' - Line: 229 Column: 6 - Code: (null)"
"ERROR" 3068 "2009-02-18 14:57:26.906" "Script Error: Source: Microsoft VBScript runtime error - Error: 800A000D - Description: Type mismatch: 'CLng' - Line: 229 Column: 6 - Code: (null)"

Is there issue with script itself?

Jozef

andyp
Normal user
Normal user
Posts: 191
Joined: 2008-01-18 21:00

Re: Limit outbound mails by user, domain or server average

Post by andyp » 2009-02-19 14:05

Another user has a similar problem. That's odd.

After the line (about Nr. 147) ln = f.ReadLine could you add a line with write_log(ln), now every line in the storage is written in the log. Could you post me the output in the log, when the error happens.

flesicek
Normal user
Normal user
Posts: 45
Joined: 2005-07-18 12:32
Contact:

Re: Limit outbound mails by user, domain or server average

Post by flesicek » 2009-02-19 17:02

Hi,

I put that writeln and this is the total output:

"2/19/2009 4:00:05 PM" " User has authenticated. User jozef.balaz@smahu.com, Client 127.0.0.1"
"2/19/2009 4:00:05 PM" " SMTP outgoing limitations"
"2/19/2009 4:00:05 PM" " Number of recipients 1"
"2/19/2009 4:00:05 PM" " Reading exceptions file D:\Data\Logs\hMailServer events\outboundexceptions.txt"
"2/19/2009 4:00:05 PM" " Reading storage file D:\Data\Logs\hMailServer events\outboundstore.txt"
"2/19/2009 4:00:05 PM" "# SMTP outgoing storage"
"2/19/2009 4:00:05 PM" ""
"2/19/2009 4:00:05 PM" "39862 jozef.balaz@smahu.com 1"

this is hmailserver error log:
"ERROR" 4560 "2009-02-19 16:00:05.435" "Script Error: Source: Microsoft VBScript runtime error - Error: 800A000D - Description: Type mismatch: 'CLng' - Line: 230 Column: 6 - Code: (null)"

Thanks a lot for your support

Jozef

andyp
Normal user
Normal user
Posts: 191
Joined: 2008-01-18 21:00

Re: Limit outbound mails by user, domain or server average

Post by andyp » 2009-02-20 11:04

OK, this was a true bug. Posted the fixed code above.

flesicek
Normal user
Normal user
Posts: 45
Joined: 2005-07-18 12:32
Contact:

Re: Limit outbound mails by user, domain or server average

Post by flesicek » 2009-02-20 11:48

Hello AndyP,

thanks for patch. I can now see that users are stored in the file but now in the hmailserver error log, new error is shown:

"ERROR" 2416 "2009-02-20 10:43:37.875" "Script Error: Source: Microsoft VBScript runtime error - Error: 800A0006 - Description: Overflow - Line: 262 Column: 1 - Code: (null)"
"ERROR" 2428 "2009-02-20 10:44:37.412" "Script Error: Source: Microsoft VBScript runtime error - Error: 800A0006 - Description: Overflow - Line: 262 Column: 1 - Code: (null)"

Note: I follow update instructions and I delete all files and overwrite procedure as it is described in your document.

Can you please take a look?

Thanks for your great support.

Jozef

andyp
Normal user
Normal user
Posts: 191
Joined: 2008-01-18 21:00

Re: Limit outbound mails by user, domain or server average

Post by andyp » 2009-02-20 13:06

Please add a line containing write_log("toindex = " & toindex) after line toindex = idt - minday and post me the log.

flesicek
Normal user
Normal user
Posts: 45
Joined: 2005-07-18 12:32
Contact:

Re: Limit outbound mails by user, domain or server average

Post by flesicek » 2009-02-20 13:27

This is the result:

"2/20/2009 12:26:37 PM" " User has authenticated. User jozef.balaz@smahu.com, Client 127.0.0.1"
"2/20/2009 12:26:37 PM" " SMTP outgoing limitations"
"2/20/2009 12:26:37 PM" " Number of recipients 1"
"2/20/2009 12:26:37 PM" " Reading exceptions file D:\Data\Logs\hMailServer events\outboundexceptions.txt"
"2/20/2009 12:26:37 PM" " Reading storage file D:\Data\Logs\hMailServer events\outboundstore.txt"
"2/20/2009 12:26:37 PM" " adding to line 39864 3 @smahu.com"
"2/20/2009 12:26:37 PM" " adding to line 39864 2 jozef.balaz@smahu.com"
"2/20/2009 12:26:37 PM" "toindex = 0"

Jozef

andyp
Normal user
Normal user
Posts: 191
Joined: 2008-01-18 21:00

Re: Limit outbound mails by user, domain or server average

Post by andyp » 2009-02-20 13:32

OK, we should have it. Replace the provided functions please. Delete the outgoingstore file again.
Attachments
new functions.zip
(2 KiB) Downloaded 904 times

flesicek
Normal user
Normal user
Posts: 45
Joined: 2005-07-18 12:32
Contact:

Re: Limit outbound mails by user, domain or server average

Post by flesicek » 2009-02-20 14:52

Hello AndyP

Thanks a lot. It seems that everything is working perfectly

Jozef

andyp
Normal user
Normal user
Posts: 191
Joined: 2008-01-18 21:00

Re: Limit outbound mails by user, domain or server average

Post by andyp » 2009-02-20 15:11

I am wondering why you are the first one complaining. This script should have never worked. I increased the functionality day per day with a already existing store file. So I never had this error. :wink:

hhtrieu
New user
New user
Posts: 1
Joined: 2008-03-23 16:43

Re: Limit outbound mails by user, domain or server average

Post by hhtrieu » 2009-03-03 06:45

Hello AndyP

Great job! I have tested the script in my system and it worked perfectly.

There is just a specific case that might be checked: user sends mail by default domain (setting up in Advanced tab).

When using default domain for SMTP authentication, users just only type the username instead of the whole email account.

The error found in log file:

Description: Invalid procedure call or argument: 'Mid' - Line: 109 Column: 2 - Code: (null)"
"ERROR" 1884 "2009-02-25 15:35:25.423" "Script Error: Source: Microsoft VBScript runtime error - Error: 800A0005 -

Thank you

Trieu

andyp
Normal user
Normal user
Posts: 191
Joined: 2008-01-18 21:00

Re: Limit outbound mails by user, domain or server average

Post by andyp » 2009-03-03 17:34

Please insert the bold line into the code, then it should work.

If oclient.username <> "" Then
usern = oclient.username
domn = Mid(oclient.username,InStr(1,oclient.username,"@"))
elseif instr(1,oclient.username,"@") = 0 then
usern = oclient.username & "@yourdefaultdomain.com"
domn = "@yourdefaultdomain.com"

ElseIf is_local_domain(omessage.fromaddress) then
usern = omessage.fromaddress
domn = Mid(omessage.fromaddress,InStr(1,omessage.fromaddress,"@"))
Else
usern = "local"
domn = "@local"
End If

I will provide a new version in the next days, which can be better configured using a global variable.

ticoi
New user
New user
Posts: 1
Joined: 2009-03-04 10:48

Re: Limit outbound mails by user, domain or server average

Post by ticoi » 2009-03-04 11:19

I guess your code mus be change to this for working fine

If oclient.username <> "" Then
usern = oclient.username
If instr(1,oclient.username,"@") = 0 then
usern = oclient.username & "@yourdefaultdomain.com"
domn = "@yourdefaultdomain.com"
Else

domn = Mid(oclient.username,InStr(1,oclient.username,"@"))
End If

ElseIf is_local_domain(omessage.fromaddress) then
usern = omessage.fromaddress
domn = Mid(omessage.fromaddress,InStr(1,omessage.fromaddress,"@"))
Else
usern = "local"
domn = "@local"
End If

andyp
Normal user
Normal user
Posts: 191
Joined: 2008-01-18 21:00

Re: Limit outbound mails by user, domain or server average

Post by andyp » 2009-03-04 11:57

ticoi, you are right, of course! :lol:

andyp
Normal user
Normal user
Posts: 191
Joined: 2008-01-18 21:00

Re: Limit outbound mails by user, domain or server average

Post by andyp » 2009-03-14 09:21

Posted the new script above. Now default domains are supported.

bibleman
New user
New user
Posts: 1
Joined: 2009-04-24 11:21

Re: Limit outbound mails by user, domain or server average

Post by bibleman » 2009-04-24 11:32

Hello andyp,

This is a very handy utility that you have written. Well done!

However, when I try to load the script, no .txt file is created. What could be wrong?

I am using hmailserver 4.

Thanks
Last edited by bibleman on 2009-04-24 11:40, edited 1 time in total.

^DooM^
Site Admin
Posts: 13861
Joined: 2005-07-29 16:18
Location: UK

Re: Limit outbound mails by user, domain or server average

Post by ^DooM^ » 2009-04-24 11:37

Check the error log it should tell you what is wrong. If it doesn't make sure the hMail service has permissions to write to wherever the txt file is supposed to be created.
If at first you don't succeed, bomb disposal probably isn't for you! ヅ

ovais
New user
New user
Posts: 3
Joined: 2009-05-03 18:25

Re: Limit outbound mails by user, domain or server average

Post by ovais » 2009-05-03 18:37

Hi,

The script appears to be working fine, it is logging events but not preventing over quota users to send e-mails.

"Script Error: Source: Microsoft VBScript runtime error - Error: 800A01B6 - Description: Object doesn't support this property or method: 'oMessage.Recipients(...).OriginalAddress' - Line: 323 Column: 3 - Code: (null)"

The Hmailserver 4 is generating above mentioned error when ever any user exceeds his/her quota but without rejecting outgoing mails.

What could be wrong??

Thanks

^DooM^
Site Admin
Posts: 13861
Joined: 2005-07-29 16:18
Location: UK

Re: Limit outbound mails by user, domain or server average

Post by ^DooM^ » 2009-05-03 19:01

This script is for hMail V5, you are using V4. Perhaps that is the issue.
If at first you don't succeed, bomb disposal probably isn't for you! ヅ

andyp
Normal user
Normal user
Posts: 191
Joined: 2008-01-18 21:00

Re: Limit outbound mails by user, domain or server average

Post by andyp » 2009-05-04 10:46

This is definetly the issue. Method 'oMessage.Recipients(...).OriginalAddress' doesn't exist in V4. You have to redesign that specific part of the script, to get it running on V4.

ovais
New user
New user
Posts: 3
Joined: 2009-05-03 18:25

Re: Limit outbound mails by user, domain or server average

Post by ovais » 2009-05-04 22:07

I dont have knowledge of VBscripting but managed to get it working. If any one interested please let me know i will upload here.

andyp
Normal user
Normal user
Posts: 191
Joined: 2008-01-18 21:00

Re: Limit outbound mails by user, domain or server average

Post by andyp » 2009-05-05 10:58

Replace

Code: Select all

	If oMessage.FromAddress = emailadmin Then
		excptn = true
	Else
		For k = 0 To oMessage.recipients.count - 1
			If oMessage.recipients(k).OriginalAddress = emailadmin Then
				excptn = True
			End If
		Next
	End If
with

Code: Select all

	If oMessage.FromAddress = emailadmin Then
		excptn = true
	If InStr(1,"  " & oMessage.to,emailadmin ) > 0 Then
		excptn = true
	Else
		For k = 0 To oMessage.recipients.count - 1
			If oMessage.recipients(k).Address = emailadmin Then
				excptn = True
			End If
		Next
	End If
This should do the trick.

ovais
New user
New user
Posts: 3
Joined: 2009-05-03 18:25

Re: Limit outbound mails by user, domain or server average

Post by ovais » 2009-05-06 09:06

Thanks Andy, i will try it. I had removed same lines to get it working. :mrgreen:

ozhim
New user
New user
Posts: 2
Joined: 2009-12-20 13:10
Location: TR
Contact:

only user-limit control

Post by ozhim » 2009-12-20 13:16

'------------------------------------------------------------------
' Global variables and settings
'------------------------------------------------------------------
Public obApp
Public domain_buffer
Public Const ipslocalhost = "0.0.0.0" 'separated by #
Public Const user = "Administrator"
Public Const pw = "xXxXx"

Public Const outgoingstore = "E:\hMailServer\Events\Outgoing.txt"
Public Const outgoingexceptions = "E:\hMailServer\Events\Limit.txt"
Public Const date_file = "E:\hMailServer\Events\Limit_Date.txt"
Public Const log_path = "E:\hMailServer\Logs\"

Public Const user_limit = 250
Public Const warning_factor = 0.9

Public Const msg_from = "Deep Design Group <info@ddg.com.tr>"
Public Const msg_fromaddress = "info@ddg.com.tr"




'------------------------------------------------------------------
' Hmailserver Eventhandlers
'------------------------------------------------------------------
Sub OnAcceptMessage(oClient, oMessage)
Result.Value = 0
Set obApp = CreateObject("hMailServer.Application")
Call obApp.Authenticate(user, pw)
If has_client_authenticated(oClient) Then
write_log ("Dogrulandi " & oCLient.username & ", Client " & oClient.IPAddress)
if not check_limit(oClient, oMessage) Then
Result.Message = "Mailserver SMTP outgoing limits."
Result.Value = 2
End if
End if
End Sub

'------------------------------------------------------------------
' SMTP limit outgoing emails of domain and user
'------------------------------------------------------------------
function check_limit(oClient, oMessage)
check_limit = true
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim fs , f
Set fs = CreateObject("scripting.filesystemobject")
Dim idt
Dim content
Dim ln
Dim arr
Dim usern
Dim usernadd
Dim usernnr
Dim user_max
Dim reason
Dim rcptscnt
Dim dayamounts(200)
For i = 0 To 200
dayamounts(i) = 0
Next
Dim pos
Dim minday
minday = 999999

If oclient.username <> "" Then
If instr(1,oclient.username,"@") = 0 Then
usern = oclient.username & "@" & obApp.Settings.DefaultDomain
Else
usern = oclient.username
End If

ElseIf is_local_domain(omessage.fromaddress) then
usern = omessage.fromaddress
Else
usern = "local"
End If

content = "# " & get_date() & " SMTP outgoing storage" & nl & nl

usernadd = true
usernnr = 1
user_max = user_limit
idt = CLng(Date())

rcptscnt = omessage.Recipients.count
write_log("Sayac " & rcptscnt)
write_log(omessage.to)

If fs.FileExists(outgoingexceptions) Then
Set f = fs.OpenTextFile(outgoingexceptions, ForReading)
Do While Not f.AtEndOfStream
ln = f.ReadLine
If ln <> "" And Mid(ln,1,1) <> "#" And Len(ln) > 3 Then
arr = Split(ln,Chr(9))
If UBound(arr) = 1 Then
If arr(0) = usern Then
user_max = CLng(arr(1))
write_log ("Limit " & ln)
End if
Else
write_log ("Limit Basarisiz " & Mid(ln,1,25))
End If
ElseIf Len(ln) > 5 And f.Line > 4 + 1 then
write_log ("Satir Atlandi-1 " & Mid(ln,1,25))
End If
Loop
Else
Set f = fs.OpenTextFile(outgoingexceptions, ForWriting, true)
f.Write("# Outgoing limitation exceptions tab / Chr(9) separated" & nl)
f.Write("# Examples (without # at the beginning)" & nl)
f.Write("# @yourdomain.com 10000" & nl)
f.Write("# address@yourdomain.com 5000" & nl & nl)
f.Close
End If

If fs.FileExists(outgoingstore) Then

Set f = fs.OpenTextFile(outgoingstore, ForReading)
Do While Not f.AtEndOfStream
ln = f.ReadLine
If ln <> "" And Mid(ln,1,1) <> "#" And Len(ln) > 5 Then
arr = Split(ln," ")
If UBound(arr) > 1 Then
If minday > CLng(arr(0)) Then
minday = CLng(arr(0))
End If
End If
If UBound(arr) = 2 Or UBound(arr) = 3 Then
If CLng(arr(0)) = idt And arr(2) = usern Then
usernnr = CLng(arr(1)) + rcptscnt
usernadd = False
write_log ("Eklendi " & ln)
If usernnr > user_max Then

If UBound(arr) = 3 Then
If arr(3) = "X" then
write_log ("Durduruldu")
Else
write_log ("Reddedildi-1")
out_send_message oClient, oMessage, false, usernnr, user_max
End if
Else
write_log ("Reddedildi-2")
out_send_message oClient, oMessage, false, usernnr, user_max
End If
content = content & arr(0) & " " & usernnr & " " & arr(2) & " X" & nl

ElseIf usernnr > user_max * warning_factor then
If UBound(arr) = 3 Then
If arr(3) = "W" then
write_log ("Limit Doldu")
Else
write_log ("Uyarı Gonderildi")
out_send_message oClient, oMessage, true, usernnr, user_max
End if
Else
write_log ("Limit Dolmak Uzere")
out_send_message oClient, oMessage, true, usernnr, user_max
End If
content = content & arr(0) & " " & usernnr & " " & arr(2) & " W" & nl
Else
content = content & arr(0) & " " & usernnr & " " & arr(2) & nl
End If
Else
content = content & arr(0) & " " & arr(1) & " " & arr(2) & nl
End If

If Mid(arr(2),1,1) <> "@" Then
pos = idt - CLng(arr(0))
dayamounts(pos) = dayamounts(pos) + CLng(arr(1))
End If

Else
write_log ("Basarisiz-2 " & Mid(ln,1,25))
End If

ElseIf Len(ln) > 5 And f.Line > 1 + 1 then
write_log ("Satir Atlandi-1 " & Mid(ln,1,25))
End If

Loop
f.Close
If usernadd Then
content = content & idt & " " & usernnr & " " & usern & nl
End If
Set f = fs.OpenTextFile(outgoingstore, ForWriting, true)
f.Write(content)
f.Close
Else
content = content & idt & " " & usernnr & " " & usern & nl
Set f = fs.OpenTextFile(outgoingstore, ForWriting, true)
f.Write(content)
f.Close
End If

If user_max < usernnr Then
check_limit = false
write_log("ERR")
Else
write_log("OK")
End If


End function

































Sub out_send_message(oClient, oMessage, iswarning, nr, max)

Dim txt
Dim tmp

If oclient.username <> "" then
tmp = oclient.username
Else
tmp = oMessage.FromAddress
End If

If iswarning Then
txt = "SAYIN " & tmp & nl & nl
txt = txt & "HESAP GONDERIM LIMITI DOLMAK UZERE." & nl & nl
txt = txt & "GONDERILEN : " & nr & nl
txt = txt & "LIMIT : " & max & nl & nl

Set nMessage = CreateObject("hMailServer.Message")
nMessage.From = msg_from
nMessage.FromAddress = msg_fromaddress
nMessage.AddRecipient tmp, tmp
nMessage.Subject = "UYARI : MAIL GONDERIM LIMITI DOLMAK UZERE"
nMessage.Body = txt
nMessage.Save
Else
txt = "SAYIN " & tmp & nl & nl
txt = txt & "HESAP GONDERIM LIMITI DOLDU." & nl & nl
txt = txt & "GONDERILEN : " & nr & nl
txt = txt & "LIMIT : " & max & nl & nl

Set nMessage = CreateObject("hMailServer.Message")
nMessage.From = msg_from
nMessage.FromAddress = msg_fromaddress
nMessage.AddRecipient tmp, tmp
nMessage.Subject = "UYARI : MAIL GONDERIM DURDURURLDU"
nMessage.Body = txt
nMessage.Save
End If


End Sub













'------------------------------------------------------------------
' General functions of all scripts
'------------------------------------------------------------------
Function get_date
Dim tmp
Dim erg
tmp = Year(Date)
erg = CStr(tmp)

If Month(Date) < 10 Then
tmp = "0" & Month(Date)
Else
tmp = Month(Date)
End If
erg = erg & "-" & tmp

If day(Date) < 10 Then
tmp = "0" & day(Date)
Else
tmp = day(Date)
End If
erg = erg & "-" & tmp

get_date = erg
End Function


Function chk_date
Dim fso
Set fso = CreateObject("scripting.filesystemobject")
Dim old_date
Dim new_date
Dim hedef
new_date = get_date()
If fso.FileExists(date_file) Then

Set fs = fso.OpenTextFile(date_file)
old_date = fs.ReadLine
Set fs = Nothing
If old_date <> new_date Then
Set fs = fso.CreateTextFile(date_file)
fs.WriteLine new_date
Set fs = Nothing
hedef = log_path & "Outgoing_" & get_date() & ".txt"
fso.MoveFile outgoingstore, hedef
End If
else
Set fs = fso.CreateTextFile(date_file)
fs.WriteLine new_date
Set fs = Nothing
end if
Set fso = Nothing
End Function


Sub write_log(txt)
chk_date()
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Dim fs
Dim f
Set fs = CreateObject("scripting.filesystemobject")

Dim fn
Dim tmp
fn = log_path & "Report_" & get_date & ".log"
Set f = fs.opentextfile(fn, ForAppending, true)


tmp = """" & FormatDateTime(Date + time,0) & """" & Chr(9) & """" & txt & """" & nl

if txt="OK" or txt="ERR" then
tmp = tmp & nl
end if

f.Write(tmp)
f.Close

End Sub



Function nl
nl = Chr(13) & Chr(10)
End function

Function is_local_domain(domain_or_email)
is_local_domain = False
Dim domain
Dim doms
Dim alss
Dim i
Dim j

If InStr(1," " & domain_or_email,"@") > 0 Then
domain = Mid(domain_or_email, InStr(1,domain_or_email,"@") + 1)
Else
domain = domain_or_email
End If

If domain_buffer = "" then
i = 0
Set doms = obapp.Domains
Do While i <= doms.Count - 1
Set dom = doms.Item(i)
domain_buffer = domain_buffer & "#" & dom.Name
j = 0
Set alss = dom.DomainAliases
Do While j <= alss.Count - 1
Set als = alss.item(j)
domain_buffer = domain_buffer & "#" & als.AliasName
j = j + 1
Loop
i = i + 1
Loop
End If

If InStr(1, " " & domain_buffer, domain) > 0 Then
is_local_domain = True
End If
End Function

Function has_client_authenticated(oclient)
has_client_authenticated = false
If oCLient.username <> "" Or InStr(1," " & ipslocalhost, oClient.IPAddress) > 0 Then
has_client_authenticated = true
End if
End Function
Last edited by ozhim on 2009-12-22 18:51, edited 1 time in total.

andyp
Normal user
Normal user
Posts: 191
Joined: 2008-01-18 21:00

Re: Limit outbound mails by user, domain or server average

Post by andyp » 2009-12-21 15:13

What do you mean by
ozhim wrote:I just want to control users
Could you tell me what line in the code you have changed!

adp
New user
New user
Posts: 4
Joined: 2009-10-16 17:14

Re: Limit outbound mails by user, domain or server average

Post by adp » 2010-01-18 17:05

Hello,

thank you for posting this.

I would like to know if you could point out a way to convert the daily limits into absolute limits.

My Best,
Andreas

dnsadmin@genv.com
New user
New user
Posts: 4
Joined: 2007-09-17 15:48

Re: Limit outbound mails by user, domain or server average

Post by dnsadmin@genv.com » 2010-05-20 10:41

may you explain excactly what and how to use the variable ipslocalhost ?
thanks

mehal.thakor
New user
New user
Posts: 7
Joined: 2010-04-20 06:11

Re: Limit outbound mails by user, domain or server average

Post by mehal.thakor » 2010-05-27 12:50

Hi andyp,

The script is really good and useful.

I was just wondering: if the user has reached the limit, when the limit can reset i.e. how the particular user can start sending the e-mails?
Is any manual action required or is it automatic?

Thanks.

DjGL
New user
New user
Posts: 26
Joined: 2006-12-15 14:55

Re: Limit outbound mails by user, domain or server average

Post by DjGL » 2010-06-15 22:55

Hi andyp

Great script but where does the script get the "emailadmin" from?

And i guess you forgot something here :wink:

Code: Select all

		If msg_admin_warning then
		End If

morsapc
New user
New user
Posts: 6
Joined: 2010-09-10 18:56

Re: Limit outbound mails by user, domain or server average

Post by morsapc » 2010-09-14 04:43

It seems a very good script but I followed the instructions in the .txt file and implemented it but it does not seem to do something.
I can't copy an error message because there is none.
I tested it setting the limit to something small, like 2 messages and nothing.
Maybe it's this: I am using hMail as a mail relay so they arrive from the MTA by the LAN nic and are sended using the WAN nic. I declared only the WAN in the script.



Help plese!

ozgurerdogan
Senior user
Senior user
Posts: 266
Joined: 2010-11-19 18:50

Re: Limit outbound mails by user, domain or server average

Post by ozgurerdogan » 2010-11-19 19:15

Thank you for this very very very usefull script. One small question, does it also counts web based sent mails or only pop3 client based sent mails.

philg
Normal user
Normal user
Posts: 38
Joined: 2008-05-03 15:49

Re: Limit outbound mails by user, domain or server average

Post by philg » 2011-01-18 01:50

I'd also like to add my thanks for this one. I was hit by a hacker/spammer the other day and I wish I had this script installed then - it may have prevented 22,000+ spams being sent though my server, and the subsequent blacklist/isp warnings!

Anyway, I had to make a few little changes, mostly undeclared variables (i have option explicit turned on so all variables *have* to be declared).

its all working well so far (tested by sending a load of emails to a safe account.

Thanks loads :)
Phil

User avatar
mattg
Moderator
Moderator
Posts: 20103
Joined: 2007-06-14 05:12
Location: 'The Outback' Australia

Re: Limit outbound mails by user, domain or server average

Post by mattg » 2011-01-18 02:09

Philg,

Can you post your updated version with the declared variables for others to use?
Just 'cause I link to a page and say little else doesn't mean I am not being nice.
https://www.hmailserver.com/documentation

philg
Normal user
Normal user
Posts: 38
Joined: 2008-05-03 15:49

Re: Limit outbound mails by user, domain or server average

Post by philg » 2011-01-18 03:41

Urm, not easy I'm afraid cos its all mixed in with my other scripts which have been cobbled together from various scripts on here. The changes were mostly in the messages sent - changing the grammar, more than functional - there were 3 undeclared variables, i, k and nMessage which is only important if you turn on "option explicit" which is not on by default, but as a C++ programmer - I hate undeclared variables - IMHO its asking for trouble :)

If anyone really wants this, I can try and extract it all back out - but not tonight :shock:

Thanks,
Phil

User avatar
mattg
Moderator
Moderator
Posts: 20103
Joined: 2007-06-14 05:12
Location: 'The Outback' Australia

Re: Limit outbound mails by user, domain or server average

Post by mattg » 2011-01-18 05:56

No stress, Just thought it may have been easy enough to do.

Don't spend too much work on it.
Just 'cause I link to a page and say little else doesn't mean I am not being nice.
https://www.hmailserver.com/documentation

philg
Normal user
Normal user
Posts: 38
Joined: 2008-05-03 15:49

Re: Limit outbound mails by user, domain or server average

Post by philg » 2011-01-18 21:55

OK here are my modifications (it was easier than I thought because I had not made so many changes). NOTE That there may be some ommisions in the "generic functions" shared with autowhitelist and other scripts because I did not use those functions from this script.

line 1: Added

Code: Select all

Option Explicit
Around Line 80: [before For i = 0 To 200] Added...

Code: Select all

Dim i, k
Around Line 382:[before If oclient.username <> "" then] Added...

Code: Select all

Dim nMessage
NOTE: You don't need to make any changes if you don't use option explicit, but as I mentioned above, I don't like undeclared variables even though vbscript supports it - too it often leads to unexplained errors.

complete list file attached for reference.
limitsmtp_script.zip
Modified script to work with Option Explicit.
(3.65 KiB) Downloaded 676 times

marceloa
Normal user
Normal user
Posts: 33
Joined: 2010-05-08 20:00

Re: Limit outbound mails by user, domain or server average

Post by marceloa » 2011-02-16 00:36

very important plugin !

thanks

ObiWan
Senior user
Senior user
Posts: 278
Joined: 2010-07-21 14:30
Location: Halfway between Germany and Egypt

Re: Limit outbound mails by user, domain or server average

Post by ObiWan » 2011-03-03 18:27

Just a short note; at line 78 in your script you use a loop
to fill that 200 elements array with "0", now, to speed up
things a little bit, you may use the following code

Code: Select all

dim dayamounts

dayamounts = Split(Replace(String(400, "0"), "00", "0,") & "0", ",")
which will automatically allocate a 200 elements array and
fill it with "0" as needed and will be slightly faster than using
"dim" and the "for...next" loop :) - nothing special by the way
but may help a bit

HTH

Raoul
New user
New user
Posts: 1
Joined: 2011-03-31 18:26
Location: Isla de Margarita, Venezuela

Re: Limit outbound mails by user, domain or server average

Post by Raoul » 2011-03-31 18:32

Very cool! Thanks!!
And it is very easily adapted to deny certain users from mailing recipients outside their own domain.

masp
New user
New user
Posts: 8
Joined: 2011-05-31 17:00

Re: Limit outbound mails by user, domain or server average

Post by masp » 2011-09-01 00:27

So I've been testing out these scripts today and I've been getting this error:
"ERROR" 1500 "2011-08-31 18:14:57.930" "Script Error: Source: Microsoft VBScript runtime error - Error: 800A0046 - Description: Permission denied - Line: 458 Column: 2 - Code: (null)"
Which goes to this line in the script:

Code: Select all

Public Const logspath = "M:\Program Files\hMailServer\Logs\"   'ends with a backslash
......
Sub write_log(txt)
	Const ForReading = 1, ForWriting = 2, ForAppending = 8
	Dim fs
	Dim f
	
	If write_log_active then
		Set fs = CreateObject("scripting.filesystemobject")
		
		Dim fn
		Dim tmp 
		fn = logspath & "hmailserver_event_" & get_date & ".log"
		Set f = fs.opentextfile(fn, ForAppending, true)
		tmp = """" & FormatDateTime(Date + time,0) & """" & Chr(9) & """" & txt & """" & nl
		f.Write(tmp)
		f.Close
	End if
End Sub


Here is what's happening in procmon
Date & Time: 8/31/2011 6:15:19 PM
Event Class: File System
Operation: CreateFile
Result: SHARING VIOLATION
Path: M:\Program Files\hMailServer\Logs\hmailserver_event_2011-08-31.log
TID: 1504
Duration: 0.0000368
Desired Access: Generic Read/Write
Disposition: OpenIf
Options: Synchronous IO Non-Alert, Non-Directory File
Attributes: N
ShareMode: Read
AllocationSize: 0
This only happens when I am load testing the server (the entire server is still in testing), but it happens in as little as 2000 messages sent at once. I think it is leading to many of the emails sent not being counted, so even if the limit is 1000 and 1000 emails are sent, the script only thinks 500 have been sent so far. Has anyone else using this script run into the same issue? I'm looking into it further but I'm a bit out of my depth. Thanks

philg
Normal user
Normal user
Posts: 38
Joined: 2008-05-03 15:49

Re: Limit outbound mails by user, domain or server average

Post by philg » 2011-09-01 01:20

Hi Masp,

One thing I have learnt about hMailServer scripting in VB, is that its all too easy to get these sorts of problems.

I modified the logging functions to retry and to use a lock file to try and avoid clashes like this. I'm guessing that the server itself is calling multiple scripts in different threads at the same time. This might also account for the not counting all the emails - its far from ideal but on my server, the load is minimal with only 5 or so users, and I still get the occasional problem.

Are you using my modified scripts? I cant remember now if they include all the extra protection I added but I think so. I'm not in front of my server right now so I cant check too easily at the moment.

Thanks,
Phil

masp
New user
New user
Posts: 8
Joined: 2011-05-31 17:00

Re: Limit outbound mails by user, domain or server average

Post by masp » 2011-09-02 17:35

Thanks for responding Phil. I tried your scripts but that section is the same. If you get a chance and can post your updated ones I'd really appreciate it.

Right now I have a web service running that periodically checks the size of the mail queue and sends an alert if it gets huge, but it'd be better to proactive about monitoring the amount of mail people send out.

philg
Normal user
Normal user
Posts: 38
Joined: 2008-05-03 15:49

Re: Limit outbound mails by user, domain or server average

Post by philg » 2011-09-02 23:01

I have already posted my updates. I'm fairly sure I've not changed it since the ones you have tried :(

andyp
Normal user
Normal user
Posts: 191
Joined: 2008-01-18 21:00

Re: Limit outbound mails by user, domain or server average

Post by andyp » 2011-09-02 23:07

DjGL wrote:Hi andyp

Great script but where does the script get the "emailadmin" from?

And i guess you forgot something here :wink:

Code: Select all

		If msg_admin_warning then
		End If
Thanks I have already corrected the script and will provide it with database support and some other features in the next days

andyp
Normal user
Normal user
Posts: 191
Joined: 2008-01-18 21:00

Re: Limit outbound mails by user, domain or server average

Post by andyp » 2011-09-02 23:35

philg wrote:Hi Masp,

One thing I have learnt about hMailServer scripting in VB, is that its all too easy to get these sorts of problems.

I modified the logging functions to retry and to use a lock file to try and avoid clashes like this. I'm guessing that the server itself is calling multiple scripts in different threads at the same time. This might also account for the not counting all the emails - its far from ideal but on my server, the load is minimal with only 5 or so users, and I still get the occasional problem.

Are you using my modified scripts? I cant remember now if they include all the extra protection I added but I think so. I'm not in front of my server right now so I cant check too easily at the moment.

Thanks,
Phil
I had the same problem and did the same and then I wrote the log into a database, which completly solved it, provide the new script in the next days

ObiWan
Senior user
Senior user
Posts: 278
Joined: 2010-07-21 14:30
Location: Halfway between Germany and Egypt

Re: Limit outbound mails by user, domain or server average

Post by ObiWan » 2011-09-05 10:58

masp wrote:This only happens when I am load testing the server (the entire server is still in testing), but it happens in as little as 2000 messages sent at once. I think it is leading to many of the emails sent not being counted, so even if the limit is 1000 and 1000 emails are sent, the script only thinks 500 have been sent so far. Has anyone else using this script run into the same issue? I'm looking into it further but I'm a bit out of my depth. Thanks
That's why it would be a good idea using the hMS "log" method instead of using custom logfiles, see, the server may handle multiple parallel sessions at once and this also means that it will call multiple times the script so the chances of hitting a filesystem lock contention are higher whenever the server gets loaded; now, if you really need to use a custom logfile, you'd better insert some error checking code into your script and use a "do" loop to retry opening the file a few times (and wait between the various attempts), something like (e.g.)

Code: Select all


Sub write_log(txt)
   Const ForReading = 1, ForWriting = 2, ForAppending = 8
   Dim fs, f, fn, tmp
   Dim bOpened, nErr
   
   On Error Resume Next
   If write_log_active then
      Set fs = CreateObject("Scripting.FileSystemObject")
      fn = logspath & "hmailserver_event_" & get_date & ".log"
      bOpened = False
      nErr = 0
      Do
        Err.Clear
        Set f = fs.opentextfile(fn, ForAppending, true)
        If Err.Number <> 0 Then
          nErr = nErr + 1
          WScript.Sleep 1000  ' 1 second
        Else
          bOpened = True  
        End If
      Loop While (bOpened = False) And (nErr < 10)
      If bOpened = True Then
        tmp = Chr(34) & FormatDateTime(Date + time, 0) & Chr(34) & Chr(9) & Chr(34) & txt & Chr(34) & vbCrLf
        f.Write(tmp)
        f.Close
      End If        
   End if
End Sub

the above code (just a barebone example) will try opening the logfile 10 times and wait one second between tries, then, if the file was successfully opened will write the logline, otherwise... will just skip the log record; notice that you may want to adjust the delay between the attempts to fit your server load (while avoiding a too high log delay)

philg
Normal user
Normal user
Posts: 38
Joined: 2008-05-03 15:49

Re: Limit outbound mails by user, domain or server average

Post by philg » 2011-09-05 12:10

Yes I agree, but while it may be better to use the hMs Log method as described, that means all the log will go to the main hMs log file, which I guess would make debugging the script more difficult hence why the author created his own logs.

Also, these scripts write their own (text) data files so they need protection too, which I'm fairly sure (although not looking at the code right now) was the main change between my version of the script and the original. My VBScript file IO is protected using lock files. If the lock file exists and can not be opened in exclusive write mode, the script waits until it can open it exclusively before continuing. This ensures that only one process/thread can read/write the data file at any time, delaying other instances until the first is finished. Its simplistic but I think it works quite well.

But I guess I didn't bother with the log (which is equally as important of course) and can be done using ObiWan's code snippet which should suffice so long as things are not locked for more than 10 seconds (and the log calls should never take that long!).

Thanks,
Phil

ObiWan
Senior user
Senior user
Posts: 278
Joined: 2010-07-21 14:30
Location: Halfway between Germany and Egypt

Re: Limit outbound mails by user, domain or server average

Post by ObiWan » 2011-09-05 12:29

philg wrote:Yes I agree, but while it may be better to use the hMs Log method as described, that means all the log will go to the main hMs log file, which I guess would make debugging the script more difficult hence why the author created his own logs.
Well... that may be solved easily, just add some kind of "tag" to the entries logged by the script and it will be easy "grepping" the hMS logfile to extract only the script entries :) at the same time, such an approach would avoid lock-contentions since the hMS log method will take care of serializing writes
philg wrote:Also, these scripts write their own (text) data files so they need protection too, which I'm fairly sure (although not looking at the code right now) was the main change between my version of the script and the original. My VBScript file IO is protected using lock files. If the lock file exists and can not be opened in exclusive write mode, the script waits until it can open it exclusively before continuing. This ensures that only one process/thread can read/write the data file at any time, delaying other instances until the first is finished. Its simplistic but I think it works quite well.
That's another approach but it's risky, see, imagine some process/script keeping the logfile locked for a lot of time or either crashing w/o deleting the lockfile... in such a case the log calls would just "hang" waiting for an unlock; not a good thing imHo !
philg wrote:But I guess I didn't bother with the log (which is equally as important of course) and can be done using ObiWan's code snippet which should suffice so long as things are not locked for more than 10 seconds (and the log calls should never take that long!).
Right, the loop/delay is just meant to allow the script to wait a bit and retry gaining access to the file and the counter avoids waiting forever; in regular use a write call won't take so much so, after a second the log should return w/o problems or, in the worst case, it will return w/o logging the record but will at least allow the script to continue running and won't cause any "hang"

andyp
Normal user
Normal user
Posts: 191
Joined: 2008-01-18 21:00

Re: Limit outbound mails by user, domain or server average

Post by andyp » 2011-09-05 12:59

@philg and ObiWan
I agree to you both, but I have tried it with a lock file and cached the log and writing it at the end of the script, so the file is only opened once, but it didn't fly without 100% errors. So I am currently using a database with odbc, which is a lot better. If you have got an error and you activated the caching, the entire log is gone, thats not good ;-(. For me using the hm log wasn't useful, but it can be easily achieved by modifing one function. I also created taskids to separate the logs for each eventhandler, sometimes the log got mixed, when 2 or more eventhandlers ran at the same time. This is also the advantage of a db, in which you can find you log very fast with sql.

philg
Normal user
Normal user
Posts: 38
Joined: 2008-05-03 15:49

Re: Limit outbound mails by user, domain or server average

Post by philg » 2011-09-05 13:32

Hi Andy,

Yes I agree that the database sounds like the best solution (and far quicker too). And if you could post the updates to your original scripts, or just a whole new set of scripts and database structure, I'm sure everyone would find it useful :)

And ObiWan,
That's another approach but it's risky, see, imagine some process/script keeping the logfile locked for a lot of time or either crashing w/o deleting the lockfile... in such a case the log calls would just "hang" waiting for an unlock; not a good thing imHo !
OK I agree with that, but the description I gave re the locking was a little simplistic. I think if you took a look at my modified scripts that I posted a while back, I think you will find it has protection so it does not hang but at the same times, does its best to ensure the data is not lost - which is not important for log files but is more so for the data files!
Anyway, it has worked well for me for months now (on a fairly low volume server) but I think the database option would be better.

Thanks,
Phil

ObiWan
Senior user
Senior user
Posts: 278
Joined: 2010-07-21 14:30
Location: Halfway between Germany and Egypt

Re: Limit outbound mails by user, domain or server average

Post by ObiWan » 2011-09-05 16:00

philg wrote:OK I agree with that, but the description I gave re the locking was a little simplistic. I think if you took a look at my modified scripts that I posted a while back, I think you will find it has protection so it does not hang but at the same times, does its best to ensure the data is not lost - which is not important for log files but is more so for the data files!
Anyway, it has worked well for me for months now (on a fairly low volume server) but I think the database option would be better.
I admit I didn't look at the updated code; yet I think that using the native logging method and adding "tags" to the messages may be a good idea, see, you may then use find/findstr or grep ... or whatever floats your boat to parse the hMS logs and only extract "your" entries while, at the same time, totally avoiding the need for "lock aware" code :) - ok, it would be cool having some kind of "custom log" function so that you may write something like (e.g.)

Code: Select all


Sub LogMsg(sMsg)
  objServer.CustomLog sMsg, "c:\foobar\logfile.log"
End Sub

so that you'll just handle over (to hMailServer) the message and the logfile and it will handle all the gory details (queueing/serialization, conflicts resolution...) heh, you may even post this as a "whish" :) ... although, sincerely, I believe there are other more important features which are really needed like, for example, full SRS support to allow hMS to really support the whole SPF mechanism; all in all, given that hMailServer already supports SPF (checks) I can't see why it shouldn't fully support SRS too

^DooM^
Site Admin
Posts: 13861
Joined: 2005-07-29 16:18
Location: UK

Re: Limit outbound mails by user, domain or server average

Post by ^DooM^ » 2011-09-05 16:35

Isn't that what EventLog.Write does?
If at first you don't succeed, bomb disposal probably isn't for you! ヅ

andyp
Normal user
Normal user
Posts: 191
Joined: 2008-01-18 21:00

Re: Limit outbound mails by user, domain or server average

Post by andyp » 2011-09-05 17:28

EventLog.Write would be the right solution, if you like to use the hm log

philg
Normal user
Normal user
Posts: 38
Joined: 2008-05-03 15:49

Re: Limit outbound mails by user, domain or server average

Post by philg » 2011-09-05 17:54

Personally, in this case, I would rather use the custom log and I don't care (for this script) if an occasional log entry gets lost, so long, as ObiWan said, the log funciton does not lock up the server!

For the purpose of this script, the most important thing is to ensure the integrity of the data files. This is why I added the locking (which seems to work for me but using the database to store the data is a much much better idea).

I agree that in general, we should use hMS for logging where possible but this does not help the integrity of any data/text files in use by the scripts. Most of the scripts that extend hMS tend to use text files of some sort to store any data, and any that get updated by the script at runtime potentially have this problem.

AndyP's use of a database via an ODBC (or OLEDB I guess) is a good solution because its much easier to maintain data integrity in that environment than in VBScript, and you can use transactions and database locks etc. to protect the data and the user of the data.

Phil

Post Reply