а мне не подскажете?
правила в postfix аналогичные,
рабоатет на этом же сервере netams, у него за рассылку почтовых сообщений юзерям отвечает alert_report.c
postfix с аналогичными настройками не пропускает почту, генерируемую netams, в логах:
warning: Illegal address syntax from unknown[127.0.0.1] in MAIL command: netams@localhost,
попытки мои редактировать файл alert_report.c (менять Mail From, RCPT TO) резултата не дали пьсма не доходят, причем если я сам запускал smtp сесию, то без проблем отправляю письмо с netams@localhost,в postfix в main.cf записано
smtpd_client_restrictions = permit_mynetworks,
check_client_access hash:/etc/postfix/client_access
reject_rbl_client blackholes.mail-abuse.org,
permit
в client_access в нем написано:
netams@localhost OK,
но результата нет.
Не подкажете или как подправить файл alert_report.c в соотвестсвие smtp, или как все-таки обойти эти ограничения для указанного адреса?
вот файл alert_report.c
/*************************************************************************
*** Authentication, authorization, accounting + firewalling package
*** (c) 1998-2003 Anton Vinokurov <anton@netams.com>
*** (c) 2003 NeTAMS Development Team
*** All rights reserved. See 'Copying' file included in distribution
*** For latest version and more info, visit this project web page
*** located at http://www.netams.com
***
*************************************************************************/
/* $Id: alert_report.c,v 1.11.2.5 2004/05/06 10:35:01 jura Exp $ */
#include "netams.h"
//////////////////////////////////////////////////////////////////////////
void sAlerterInit(Service *s){
s->cfg = (ServiceAlerter_cfg*)aMalloc(sizeof(ServiceAlerter_cfg));
ServiceAlerter_cfg *cfg=(ServiceAlerter_cfg*)s->cfg;
cfg->queue=new FIFO(255);
cfg->self=s;
cfg->smtp_server=cfg->sms_server=cfg->pager_server=NULL;
pthread_create(&(s->t_id), NULL, &sAlerter, s);
return;
}
//////////////////////////////////////////////////////////////////////////
void sAlerterProcessCfg(char *param[32], Connection *conn, unsigned no_flag){
ServiceAlerter_cfg *cfg=(ServiceAlerter_cfg*)conn->service->cfg;
if (!strcasecmp(param[0], "report")) {
// we are not defining actual report here
// builtin report with oid=06100
aParse(conn, "default report with oid=06100 created\n");
}
else if (!strcasecmp(param[0], "smtp-server")) {
if (cfg->smtp_server) aFree(cfg->smtp_server);
cfg->smtp_server=set_string(param[1]);
aParse(conn, "smtp server name set to %s\n", cfg->smtp_server);
}
else if (!strcasecmp(param[0], "sms-server")) {
if (cfg->sms_server) aFree(cfg->sms_server);
cfg->sms_server=set_string(param[1]);
aParse(conn, "sms server name set to %s\n", cfg->sms_server);
}
else if (!strcasecmp(param[0], "pager-server")) {
if (cfg->pager_server) aFree(cfg->pager_server);
cfg->pager_server=set_string(param[1]);
aParse(conn, "pager server name set to %s\n", cfg->pager_server);
}
else aParse(conn, "unknown alerter command: %s\n", param[0]);
return;
}
//////////////////////////////////////////////////////////////////////////
void sAlerterListCfg(Service *s, FILE *f){
ServiceAlerter_cfg *cfg=(ServiceAlerter_cfg*)s->cfg;
fprintf(f, "service alerter %d\n", s->instance);
fprintf(f, "report oid 06100 name rep1 type traffic period day detail simple\n");
if (cfg->smtp_server) fprintf(f, "smtp-server %s\n", cfg->smtp_server);
if (cfg->sms_server) fprintf(f, "sms-server %s\n", cfg->sms_server);
if (cfg->pager_server) fprintf(f, "pager-server %s\n", cfg->pager_server);
fprintf(f, "\n");
return;
}
//////////////////////////////////////////////////////////////////////////
void cShowAlerter(Connection *conn){
Service *s=NULL;
while((s=Services.getServiceByName("alerter",s))) {
ServiceAlerter_cfg *cfg=(ServiceAlerter_cfg*)s->cfg;
fprintf(conn->stream_w,"service alerter %u\n",s->instance);
fprintf(conn->stream_w, "Alerter queue max: %u, current: %u\n\n", cfg->queue->max_items, cfg->queue->num_items);
}
return;
}
//////////////////////////////////////////////////////////////////////////
void *sAlerter(void *ss){
Service *s=(Service*)ss;
ServiceAlerter_cfg *cfg=(ServiceAlerter_cfg*)s->cfg;
Message *msg;
alert *al;
aLog(D_INFO, "service alerter:%u thread started (%p)\n", s->instance, s->cfg);
pthread_cleanup_push(sAlerterCancel, s);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
s->t_id=pthread_self();
// now we should sleep before starting storage service exec
s->Sleep();
aLog(D_INFO, "service alerter:%u processing queue\n", s->instance);
while (1) {
while(cfg->queue->num_items > 0) {
msg=cfg->queue->Pop();
if (msg->type==ALERT||msg->type==COMMAND) al=(alert*)msg->al; else { aDebug(DEBUG_ALERT, "non-alert (%d) in alerter:%u queue\n", msg->type, s->instance); continue; }
aDebug(DEBUG_ALERT, "ALERT: id:%u, type: %d, rep_id %06X, user_id %06X, tryN: %u\n", al->alert_id, al->type, al->report_id, al->user_id[0], al->tries);
if (!cProcessAlert(s, al)) { aFree(al->data); aFree(al); delete msg; }
// else { al->tries++; cfg->queue->Push(msg); }
}
s->Sleep(5000);
}
pthread_cleanup_pop(0);
return NULL;
}
//////////////////////////////////////////////////////////////////////////
void sAlerterCancel(void *v){
Service *s = (Service*)v;
ServiceAlerter_cfg *cfg=(ServiceAlerter_cfg*)s->cfg;
aFree(cfg->smtp_server);
aFree(cfg->sms_server);
aFree(cfg->pager_server);
aFree(cfg->queue);
aFree(cfg);
aLog(D_INFO, "cancelling service monitor:%u\n", s->instance);
}
//////////////////////////////////////////////////////////////////////////
void cSend(Connection *conn, char *param[32]){
Service *s;
// we looking for 1st alerter service and will use it
// if we want ue specific alerter service we should rework parsing
// in way send alerter <num> ...
s=Services.getServiceByName("alerter",NULL);
if(!s) { aLog(D_WARN, "cannot send because alerter service is not running!\n"); return; }
ServiceAlerter_cfg *cfg=(ServiceAlerter_cfg*)s->cfg;
Message *msg;
alert *al;
int i;
char *cmd;
msg = new Message();
al=(alert*)aMalloc(sizeof(alert));
msg->al=al;
al->sent=time(NULL);
al->expired=al->sent+60*60; // one hour expire
al->report_id=0x06100;
al->tries=0;
al->alert_id=cfg->queue->total_items+1;
int uid_idx;
for (uid_idx=0; uid_idx<MAX_ID_PER_ALERT; uid_idx++) al->user_id[uid_idx]=0; uid_idx=0;
int nid_idx;
for (nid_idx=0; nid_idx<MAX_ID_PER_ALERT; nid_idx++) { al->unit_id[nid_idx]=0; al->unit_id_recursive[nid_idx]=0; } nid_idx=0;
if (!strcasecmp(param[1], "report")) {
msg->type=ALERT;
aDebug(DEBUG_ALERT, "constructing MAIL report %u\n", al->alert_id);
i=2;
}
else if (!strcasecmp(param[1], "command")) {
msg->type=COMMAND;
aDebug(DEBUG_ALERT, "constructing MAIL command %u\n", al->alert_id);
cmd=set_string(param[2]);
aDebug(DEBUG_ALERT, "executing command \"%s\"...\n", cmd);
i=3;
}
else {
aDebug(DEBUG_ALERT, "unknown send command \"%s\"...\n", param[1]);
aFree(al);
return;
}
while (param!=empty) {
if (!strcasecmp(param, "to")) {
User *u;
u=Users.getUser(param[i+1]);
if (u) {
al->user_id[uid_idx]=u->id;
uid_idx++;
aDebug(DEBUG_ALERT, "user %s(%06X) added to MAIL msg as a recipient\n", u->name, u->id);
}
else {
aDebug(DEBUG_ALERT, "user %s not exist\n", param[i+1]);
}
i+=2;
}
else if (!strcasecmp(param, "on")) {
NetUnit *u;
char *c_param; int j;
c_param=param[i+1]; j=strlen(c_param);
if (c_param[j-1]=='+') { param[i+1][j-1]='\0'; j=1; } else j=0;
u=Units.getUnit(param[i+1]);
if (u) {
al->unit_id[nid_idx]=u->id;
al->unit_id_recursive[nid_idx]=j;
nid_idx++;
aDebug(DEBUG_ALERT, "unit %s(%06X)%s added to MAIL alert as a data\n", u->name, u->id, j?"+":"");
}
else {
aDebug(DEBUG_ALERT, "unit %s not exist\n", param[i+1]);
}
i+=2;
}
else {
aDebug(DEBUG_ALERT, "SEND: parameter '%s' not understood\n", param);
i++;
}
} //while
char *subject, *message, *buffer;
subject=message=NULL;
buffer=(char*)aMalloc(255);
timeU2T(time(NULL), buffer);
if (msg->type==ALERT){
print_to_string(&subject, "Report %06X %s on [ ", al->report_id, buffer);
print_to_string(&message, "This is automatically generated report by %s, version %d.%d(%d)\nTime: %s\n", aaa_fw_software_name, aaa_fw_major_version, aaa_fw_minor_version, aaa_fw_build_version, buffer);
NetUnit *u;
for (nid_idx=0; nid_idx<MAX_ID_PER_ALERT||!al->unit_id[nid_idx] ; nid_idx++) {
u=Units.getUnitById(al->unit_id[nid_idx]);
if ( u ) {
if (u->name) print_to_string(&subject, "%s%s ", u->name, al->unit_id_recursive[nid_idx]?"+":"");
else print_to_string(&subject, "%06X%s ", u->id, al->unit_id_recursive[nid_idx]?"+":"");
cReport(&message, u, al->report_id, al->unit_id_recursive[nid_idx], 0);
}
}
print_to_string(&subject, " ]");
}
else if (msg->type==COMMAND){
print_to_string(&subject, "%s command \"%s\"", aaa_fw_software_name, cmd);
print_to_string(&message, "This is processed command \"%s\" by %s, version %d.%d(%d)\nTime: %s\n\n", cmd, aaa_fw_software_name, aaa_fw_major_version, aaa_fw_minor_version, aaa_fw_build_version, buffer);
cExec(cmd, &message);
aFree(cmd);
}
al->data=NULL;
print_to_string(&al->data, "%s\n%s\n", subject, message);
aFree(subject); aFree(message); aFree(buffer);
al->alert_id=(unsigned)cfg->queue->Push(msg);
cfg->self->Wakeup();
aDebug(DEBUG_ALERT, "alert %u complete, data is %d bytes\n", al->alert_id, strlen(al->data));
return;
}
//////////////////////////////////////////////////////////////////////////
int cProcessAlert(Service *s, alert *al){
ServiceAlerter_cfg *cfg=(ServiceAlerter_cfg*)s->cfg;
int sock, status;
struct sockaddr_in addr;
struct hostent *hp;
FILE *fd;
char *buffer;
buffer=(char*)aMalloc(1024*4);
if ((sock=socket(AF_INET,SOCK_STREAM,0))==-1 ) { aLog(D_WARN, "creation of alerter socket failed: %d (%s)\n", sock, strerror(sock)); return -1; }
switch (al->type){
case MAIL:
case COMMAND:
{
// first we must check the validness of e-mail and report oid
// User *u;
// if ( !(u=Users.getUserById(al->user_id[0]))) { aLog(D_WARN, "unable to process alert %u: no user\n", al->alert_id); return -1; }
if (!(al->report_id==0x06100 || al->report_id==0x06101)) { aLog(D_WARN, "unable to process alert %u: report unknown\n", al->alert_id); return -1; }
// if ( !u->email ) { aLog(D_WARN, "unable to process alert %u: user email not set\n", al->alert_id); return -1; }
if (cfg->smtp_server==NULL) { aLog(D_WARN, "no SMTP server defined!\n"); return -1; }
hp=gethostbyname(cfg->smtp_server);
if (hp==NULL) { aLog(D_WARN, "gethostbyname: %d (%s)\n", h_errno, strerror(h_errno)); return -1; }
bzero((u_char*)(&addr), sizeof(addr));
addr.sin_family=AF_INET;
addr.sin_port=htons((unsigned short)25);
memcpy((char*)&addr.sin_addr, hp->h_addr_list[0], hp->h_length);
status=connect(sock, (struct sockaddr*)&addr, sizeof(addr));
if (status==-1 ){ aLog(D_WARN, "connect of socket failed: %d, (%s)\nPossibly no SMTP servers there!\n%s\n", errno, strerror(errno), cfg->smtp_server); return -1; }
fd = fdopen(sock, "w+");
if (fd==NULL) aLog(D_WARN, "fdopen of server socket() failed\n");
fgets(buffer, 4*1024, fd);
fprintf(fd, "HELO arhrdu %s\n", cfg->smtp_server);
fgets(buffer, 4*1024, fd);
fprintf(fd, "MAIL FROM: <root@relay.arhrdu.ru>\n");
fgets(buffer, 4*1024, fd);
int num_rcpts=0;
if (al->unit_id[0] && al->report_id==0x06101) {
NetUnit *uu;
uu=Units.getUnitById(al->unit_id[0]);
if (uu && uu->email) {
fprintf(fd, "RCPT TO: <pvn@arhrdu.ru>", uu->email);
aDebug(DEBUG_ALERT, "UNIT RCPT %d added: %s\n", num_rcpts+1, uu->email);
num_rcpts++;
fgets(buffer, 4*1024, fd);
}
}
if (al->user_id[0]) {
User *uu;
int j=0;
while (al->user_id[j]){
uu=Users.getUserById(al->user_id[j]);
if (uu && uu->email) {
fprintf(fd, "RCPT TO: <pvn@arhrdu.ru>", uu->email);
aDebug(DEBUG_ALERT, "USER RCPT %d added: %s\n", num_rcpts+1, uu->email);
num_rcpts++;
fgets(buffer, 4*1024, fd);
}
j++;
}
}
aDebug(DEBUG_ALERT, "RECIPIENTS DONE: total %d\n", num_rcpts);
if (num_rcpts==0) {
fprintf(fd, "QUIT\n");
fgets(buffer, 4*1024, fd);
aLog(D_WARN, "unable to process alert %u: no recipients found\n", al->alert_id);
return -1;
}
fprintf(fd, "DATA\n");
fgets(buffer, 4*1024, fd);
fprintf(fd, "From: %s daemon <root>\nSubject: %s\n.\n", aaa_fw_software_name, al->data);
fgets(buffer, 4*1024, fd);
fprintf(fd, "QUIT\n");
fgets(buffer, 4*1024, fd);
fclose(fd);
aDebug(DEBUG_ALERT, "MAIL (alert %u) sent ok (tries %u, bytes %d, rcpts=%d)\n", al->alert_id, al->tries, strlen(al->data), num_rcpts);
aLog(D_INFO, "MAIL (alert %u) sent ok (tries %u, bytes %d, rcpts=%d)\n", al->alert_id, al->tries, strlen(al->data), num_rcpts);
}
default: return -1;
} //switch
close(sock);
aFree(buffer);
return 0;
}
//////////////////////////////////////////////////////////////////////////
void cReport(char **message, NetUnit *u, oid report_id, unsigned is_recursive, unsigned level){
policy_data *pd;
if (!level || u->type==NETUNIT_GROUP) {
print_to_string(message, "\nProcessing NetUnit oid %06X, name %s, parent %s%s\n", u->id, u->name?u->name:"<\?\?>", u->parent?(u->parent->name?u->parent->name:"<\?\?>"):"<>", (is_recursive&&(u->type==NETUNIT_GROUP))?", recursive tree":"");
print_to_string(message, "%8s | %10s | %10s | %10s | %10s | %10s | %10s\n", "TYPE", "NAME", "AC-POLICY", "DAY-IN", "DAY-OUT", "MON-IN", "MON-OUT");
}
for (pd=u->ap.root; pd!=NULL; pd=pd->next) {
switch (u->type){
case NETUNIT_HOST: print_to_string(message, "%8s |", "host"); break;
case NETUNIT_USER: print_to_string(message, "%8s |", "user"); break;
case NETUNIT_NET: print_to_string(message, "%8s |", "net"); break;
case NETUNIT_CLUSTER: print_to_string(message, "%8s |", "cluster"); break;
case NETUNIT_GROUP: print_to_string(message, "%8s |", "group"); break;
default: print_to_string(message, "%8s |", "<\?\?>"); break;
}
print_to_string(message, " %10s | %10s | %10qu | %10qu | %10qu | %10qu\n", u->name, pd->policy->name, pd->d.in, pd->d.out, pd->m.in, pd->m.out);
}
if (is_recursive && u->type==NETUNIT_GROUP) {
for (NetUnit *t=Units.root; t!=NULL; t=t->next)
if (t->parent==u && t->type!=NETUNIT_GROUP)
cReport(message, t, report_id, is_recursive, level+1);
for (NetUnit *t=Units.root; t!=NULL; t=t->next)
if (t->parent==u && t->type==NETUNIT_GROUP)
cReport(message, t, report_id, is_recursive, level+1);
}
}
//////////////////////////////////////////////////////////////////////////