ze-filter  (ze-filter-0.8.0-develop-180218)
ze-ndc-server.c
Go to the documentation of this file.
1 
2 /*
3  *
4  * ze-filter - Mail Server Filter for sendmail
5  *
6  * Copyright (c) 2001-2018 - Jose-Marcio Martins da Cruz
7  *
8  * Auteur : Jose Marcio Martins da Cruz
9  * jose.marcio.mc@gmail.org
10  *
11  * Historique :
12  * Creation : janvier 2002
13  *
14  * This program is free software, but with restricted license :
15  *
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20  *
21  * More details about ze-filter license can be found at ze-filter
22  * web site : http://foss.jose-marcio.org
23  */
24 
25 #include <ze-sys.h>
26 #include <libze.h>
27 #include <libml.h>
28 
29 #include "ze-filter.h"
30 
31 static bool do_control(int, int, char **);
32 static bool check_control_access(char *, char *, char *);
33 
34 /* ****************************************************************************
35  * *
36  * *
37  ******************************************************************************/
38 #define CTRL_TO 5000
39 #define MAX_ARGS 16
40 
41 static void *
42 control_handler(name)
43  void *name;
44 {
45  int errs;
46  socklen_t addrlen, len;
47  int sockdomain;
48  int listenfd, connfd;
49  struct sockaddr *clisock;
50  char *p;
51  pthread_t tid;
52 
53  server_T server;
54 
55  tid = pthread_self();
56  (void) pthread_detach(tid);
57 
58  ZE_MessageInfo(9, "*** Starting %s ...", ZE_FUNCTION);
59 
61 
62  memset(&server, 0, sizeof (server));
63  if ((listenfd = server_listen(p, &server)) < 0) {
64  ZE_MessageError(10, "Error setting up control channel");
65  return NULL;
66  }
67 
68  addrlen = server.socklen;
69  sockdomain = server.family;
70 
71  errs = 0;
72 
73  ZE_MessageInfo(12, "sd : %d len : %d domain %d", listenfd, addrlen,
74  sockdomain);
75 
76  if ((clisock = (struct sockaddr *) malloc(addrlen)) == NULL) {
77  ZE_LogSysError("malloc(addrlen) error");
78  return NULL;
79  }
80 
81  for (;;) {
82  char client_addr[64], client_name[256];
83  char *s;
84  int nerr = 0;
85 
86  len = addrlen;
87 
88  connfd = accept(listenfd, clisock, &len);
89 
90  if (connfd < 0) {
91  ZE_LogSysError("accept error");
92  if (nerr > 256) {
93  ZE_MessageError(6, "Control channel thread exiting - too many errors");
94  break;
95  }
96  continue;
97  }
98  nerr = 0;
99 
100  if (sockdomain == AF_INET || sockdomain == AF_INET6) {
101  char *addr, *name, *user;
102 
103  addr = name = user = NULL;
104 
105  memset(client_addr, 0, sizeof (client_addr));
106  memset(client_name, 0, sizeof (client_name));
107 #if 1
108  if (get_hostbysock(clisock, len, client_addr, sizeof (client_addr),
109  client_name, sizeof (client_name))) {
110  addr = client_addr;
111  name = client_name;
112  }
113 #else
114  if (jsock_ntop(clisock, len, client_addr, sizeof (client_addr)))
115  addr = client_addr;
116 
117  if (get_hostbyaddr(client_addr, client_name, sizeof (client_name)))
118  name = client_name;
119 #endif
120 
121  ZE_MessageInfo(9, "Connect from %s (%s) on control channel",
122  STRNULL(addr, ""), STRNULL(name, ""));
123 
124  if (!check_control_access(addr, name, user)) {
125  ZE_MessageInfo(9, "Access denied to %s (%s) on control channel",
126  STRNULL(addr, ""), STRNULL(name, ""));
127  FD_PRINTF(connfd, "500 Access denied\n");
128  shutdown(connfd, SHUT_RDWR);
129  close(connfd);
130  continue;
131  }
132  }
133 
134  FD_PRINTF(connfd, "200 OK - Waiting for commands !\n");
135 
136  if (jfd_ready(connfd, ZE_SOCK_READ, CTRL_TO) == ZE_SOCK_READY) {
137  char buf[1024];
138  size_t sz;
139  char *argv[MAX_ARGS];
140  int argc;
141 
142  memset(buf, 0, sizeof (buf));
143  if ((sz = read(connfd, buf, sizeof (buf) - 1)) > 0) {
144  char *ptr;
145 
146  zeStrChomp(buf);
147  zeStr2Upper(buf);
148  zeStr2Lower(buf);
149 
150  ZE_MessageInfo(9, "CTRL CHAN CMD : %s", buf);
151 
152  argc = 0;
153  memset(argv, 0, sizeof (argv));
154  for (s = strtok_r(buf, " \t", &ptr);
155  argc < MAX_ARGS && s != NULL; s = strtok_r(NULL, " \t", &ptr)) {
156  argv[argc++] = s;
157  }
158 
159  if (do_control(connfd, argc, argv))
160  ZE_MessageInfo(9, "Command accepted on control channel");
161  }
162  } else {
163  ZE_MessageWarning(9, "Read timeout on control channel");
164  FD_PRINTF(connfd, "500 Read timeout on control channel\r\n");
165  }
166  shutdown(connfd, SHUT_RDWR);
167  close(connfd);
168  }
169 
170  FREE(clisock);
171 
172  return NULL;
173 }
174 
175 
176 /* ****************************************************************************
177  * *
178  * *
179  ******************************************************************************/
180 bool
182 {
183  pthread_t tid;
184  int r;
185 
186  ZE_MessageInfo(10, "*** Starting %s ...", ZE_FUNCTION);
187 
189  return TRUE;
190 
191  if ((r = pthread_create(&tid, NULL, control_handler, NULL)) != 0)
192  ZE_LogSysError("Error launching control_handler");
193 
194  return TRUE;
195 }
196 
197 
198 /* ****************************************************************************
199  * *
200  * *
201  ******************************************************************************/
202 static bool
203 do_control(sd, argc, argv)
204  int sd;
205  int argc;
206  char **argv;
207 {
208  char *cmd;
209  char *arg;
210  bool help = FALSE;
211  char *helpstr = "500 Command not understood";
212 
213  if (argv == NULL || argc == 0 || argv[0] == 0)
214  return FALSE;
215 
216  if (strcasecmp(argv[0], "help") == 0) {
217  help = TRUE;
218  argv++;
219  argc--;
220  }
221 
222  cmd = argv[0];
223  arg = argc > 0 ? argv[1] : NULL;
224 
225  /*
226  **
227  **
228  */
229 
230  if (argc == 0 || help) {
231  ndc_help(sd, NULL, help, argc, argv);
232 
233  return help;
234  }
235 
236  /*
237  **
238  **
239  */
240  if (strcasecmp(cmd, "VERSION") == 0) {
241  helpstr = " VERSION - writes ze-filter version and exit";
242 
243  if (help) {
244  ndc_help(sd, helpstr, help, argc, argv);
245 
246  return TRUE;
247  }
248 
249  FD_PRINTF(sd, "200 %s\r\n", PACKAGE);
250  return TRUE;
251  }
252 
253  if (help) {
254  ndc_help(sd, " You've asked for help !", help, argc, argv);
255 
256  return TRUE;
257  }
258 
259  /*
260  **
261  **
262  */
263  if (strcasecmp(cmd, "DUMPCF") == 0) {
264  char *scmd = NULL;
265  char *prmt;
266  int pi;
267  int mkcf = MK_CF_RUNNING;
268 
269  helpstr = " VERSION - writes ze-filter version and exit";
270 
271  if (help) {
272  ndc_help(sd, helpstr, help, argc, argv);
273  return TRUE;
274  }
275 
276  FD_PRINTF(sd, "200 OK for %s !\r\n", cmd);
277 
278  prmt = argc > 2 ? argv[2] : NULL;
279  if (arg != NULL) {
280  if (STRCASEEQUAL(arg, "running"))
281  mkcf = MK_CF_RUNNING;
282  if (STRCASEEQUAL(arg, "default"))
283  mkcf = MK_CF_DEFAULT;
284  if (STRCASEEQUAL(arg, "short"))
285  mkcf = MK_CF_NONE;
286  }
287  switch (mkcf) {
288  case MK_CF_NONE:
289  dump_j_conf(sd);
290  break;
291  case MK_CF_RUNNING:
293  break;
294  case MK_CF_DEFAULT:
296  break;
297  }
298  FD_PRINTF(sd, "200 %s done !\r\n", cmd);
299  return TRUE;
300  }
301 
302  /*
303  **
304  **
305  */
306  if (strcasecmp(cmd, "SETCF") == 0) {
307  char *scmd = NULL;
308  char *prmt;
309  int pi;
310 
311  helpstr = " ...\r\n";
312 
313  if (arg == NULL)
314  goto done_setcf;
315 
316  prmt = argc > 2 ? argv[2] : NULL;
317 
318  if (prmt != NULL) {
319  int id = cf_get_id(arg);
320 
321  FD_PRINTF(sd, "200 OK for %s %s %s !\r\n", cmd, arg, prmt);
322 
323  pi = -1;
324  if (id > 0)
325  pi = cf_set_val(id, prmt);
326 
327  if (pi == id) {
328 
329  switch (id) {
330  case CF_LOG_LEVEL:
331  ze_logLevel = atoi(prmt);
332  break;
334  (void) grey_set_dewhite_flags(prmt, TRUE);
335  break;
337  (void) grey_set_compat_domain_check(!STRCASEEQUAL(prmt, "NO"));
338  break;
339  }
340  FD_PRINTF(sd, "200 %s %s %s done !\r\n", cmd, arg, prmt);
341  return TRUE;
342  }
343  }
344 
345  done_setcf:
346  ndc_help(sd, helpstr, help, argc, argv);
347  return help;
348  }
349 
350  if (strcasecmp(cmd, "SETORACLE") == 0) {
351  char *prmt;
352 
353  helpstr = "............\r\n";
354 
355  if (arg == NULL)
356  goto done_setoracle;
357 
358  prmt = argc > 2 ? argv[2] : NULL;
359 
360  if (prmt != NULL) {
361  int type = -1, ind = 0;
362  double value;
363  char *p = arg;
364 
365  FD_PRINTF(sd, "200 OK for %s %s %s !\r\n", cmd, arg, prmt);
366 
367  if (zeStrRegex(p, "[rcmhp][0-9]{2,2}", NULL, NULL, TRUE)) {
368  switch (*arg) {
369  case 'c':
370  case 'C':
371  type = ORACLE_TYPE_CONN;
372  break;
373  case 'm':
374  case 'M':
375  type = ORACLE_TYPE_MSG;
376  break;
377  case 'h':
378  case 'H':
379  type = ORACLE_TYPE_HTML;
380  break;
381  case 'p':
382  case 'P':
383  type = ORACLE_TYPE_PLAIN;
384  break;
385  default:
386  type = -1;
387  }
388  p++;
389 
390  ind = zeStr2long(p, NULL, 0);
391  }
392 
393  value = zeStr2double(prmt, NULL, 0);
394  if (errno == ERANGE || errno == EINVAL)
395  goto done_setoracle;
396 
397  (void) oracle_set_score(type, ind, value);
398 
399  FD_PRINTF(sd, "200 %s %s %s done !\r\n", cmd, arg, prmt);
400 
401  return TRUE;
402  }
403 
404  done_setoracle:
405  ndc_help(sd, helpstr, help, argc, argv);
406  return help;
407  }
408 
409  /*
410  **
411  **
412  */
413  if (strcasecmp(cmd, "SET") == 0) {
414  char *scmd = NULL;
415  char *prmt;
416 
417  time_t pt;
418  long pi = 0;
419 
420  if (arg == NULL)
421  return FALSE;
422 
423  prmt = STRNULL(argv[2], "");
424 
425  scmd = "URLBLTIME";
426  if (strncasecmp(arg, scmd, strlen(scmd)) == 0) {
427  pt = zeStr2time(prmt, NULL, 3600);
428 
429  FD_PRINTF(sd, "200 OK for %s %s %ld s !\r\n", cmd, arg, pt);
430 
431  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
432  return TRUE;
433  }
434 
435  scmd = "LOGLEVEL";
436  if (strncasecmp(arg, scmd, strlen(scmd)) == 0) {
437  pi = atoi(prmt);
438 
439  FD_PRINTF(sd, "200 OK for %s %s %ld s !\r\n", cmd, arg, pi);
440 
441  if (pi >= 0)
442  ze_logLevel = pi;
443 
444  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
445  return TRUE;
446  }
447 
448  scmd = "LOG_SM_MACROS";
449  if (strncasecmp(arg, scmd, strlen(scmd)) == 0) {
450  extern bool log_sm_macros;
451 
452  if (strcasecmp(prmt, "YES") == 0)
453  log_sm_macros = TRUE;
454  else
455  log_sm_macros = FALSE;
456 
457  FD_PRINTF(sd, "200 OK for %s %s %s !\r\n", cmd, arg, prmt);
458 
459  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
460  return TRUE;
461  }
462 
463  scmd = "MXCHECKLEVEL";
464  if (strncasecmp(arg, scmd, strlen(scmd)) == 0) {
465  extern int mx_check_level;
466 
467  pi = atoi(prmt);
468 
469  FD_PRINTF(sd, "200 OK for %s %s %ld !\r\n", cmd, arg, pi);
470 
471  if (pi >= 0)
472  mx_check_level = pi;
473 
474  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
475  return TRUE;
476  }
477 
478  scmd = "TLONGCONN";
479  if (strncasecmp(arg, scmd, strlen(scmd)) == 0) {
480  extern time_t tlongconn;
481 
482  pi = atoi(prmt);
483 
484  FD_PRINTF(sd, "200 OK for %s %s %ld !\r\n", cmd, arg, pi);
485 
486  if (pi >= 30)
487  tlongconn = pi;
488  else
489  FD_PRINTF(sd, "500 %s %s not done : %s too short !\r\n", cmd, arg,
490  prmt);
491 
492  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
493  return TRUE;
494  }
495 
496  scmd = "GREYDELAYS";
497  if (strncasecmp(arg, scmd, strlen(scmd)) == 0) {
498  int i;
499  time_t delays[4];
500  bool ok;
501 
502  memset(delays, 0, sizeof (delays));
503 
504  for (i = 0; i < 4; i++) {
505  if (argc > i + 2)
506  delays[i] = zeStr2time(argv[i + 2], NULL, 3600);
507  }
508 
509  FD_PRINTF(sd, "200 OK for %s %s %ld !\r\n", cmd, arg, pi);
510  ok = grey_set_delays(delays[0], delays[1], delays[2], delays[3]);
511  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
512  return TRUE;
513  }
514 
515  scmd = "GREYLIFETIME";
516  if (strncasecmp(arg, scmd, strlen(scmd)) == 0) {
517  int i;
518  time_t lifetime[4];
519  bool ok;
520 
521  memset(lifetime, 0, sizeof (lifetime));
522 
523  for (i = 0; i < 4; i++) {
524  if (argc > i + 2)
525  lifetime[i] = zeStr2time(argv[i + 2], NULL, 3600);
526  }
527 
528  FD_PRINTF(sd, "200 OK for %s %s %ld !\r\n", cmd, arg, pi);
529  ok = grey_set_lifetime(lifetime[0], lifetime[1], lifetime[2]);
530  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
531  return TRUE;
532  }
533 
534  scmd = "GREYPENDING";
535  if (strncasecmp(arg, scmd, strlen(scmd)) == 0) {
536  int i;
537  int nb[4];
538  bool ok;
539 
540  memset(nb, 0, sizeof (nb));
541 
542  for (i = 0; i < 2; i++) {
543  if (argc > i + 2)
544  nb[i] = zeStr2long(argv[i + 2], NULL, 0);
545  }
546 
547  FD_PRINTF(sd, "200 OK for %s %s %ld !\r\n", cmd, arg, pi);
548  ok = grey_set_max_pending(nb[0], nb[1]);
549  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
550  return TRUE;
551  }
552 
553  scmd = "GREYTUPLE";
554  if (strncasecmp(arg, scmd, strlen(scmd)) == 0) {
555  int i;
556  char *tuple[3];
557  bool ok;
558 
559  memset(tuple, 0, sizeof (tuple));
560 
561  for (i = 0; i < 3; i++) {
562  tuple[i] = (argc > i + 2) ? argv[i + 2] : NULL;
563  }
564 
565  FD_PRINTF(sd, "200 OK for %s %s %ld !\r\n", cmd, arg, pi);
566  ok = grey_set_tuples(tuple[0], tuple[1], tuple[2]);
567  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
568  return TRUE;
569  }
570 
571  scmd = "GREYCLEANUP";
572  if (strncasecmp(arg, scmd, strlen(scmd)) == 0) {
573  time_t dt = 0;
574  bool ok;
575 
576  if (argc > 2) {
577  dt = zeStr2time(argv[2], NULL, 3600);
578 
579  FD_PRINTF(sd, "200 OK for %s %s %ld !\r\n", cmd, arg, dt);
580  ok = grey_set_cleanup_interval(dt);
581  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
582 
583  return TRUE;
584  } else
585  FD_PRINTF(sd, "400 KO for %s %s %ld !\r\n", cmd, arg, pi);
586 
587  return FALSE;
588  }
589 
590  scmd = "GREY_DEWHITE_THRESHOLD";
591  if (strncasecmp(arg, scmd, strlen(scmd)) == 0) {
592  double t;
593 
594  t = zeStr2double(prmt, NULL, 0);
595  if (errno != ERANGE && errno != EINVAL && t >= 0) {
596  FD_PRINTF(sd, "200 OK for %s %s %5.2f !\r\n", cmd, arg, t);
598  }
599 
600  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
601  return TRUE;
602  }
603 
604  }
605 
606  /*
607  **
608  **
609  */
610  if (strcasecmp(cmd, "BAYES") == 0) {
611  char *scmd = NULL;
612 
613  helpstr = "200 Not yet implemented !!!\r\n";
614 
615  if (help) {
616  ndc_help(sd, helpstr, help, argc, argv);
617  return TRUE;
618  }
619 
620  if (arg == NULL)
621  return FALSE;
622 
623  scmd = "REOPEN";
624  if (strncasecmp(arg, scmd, strlen(scmd)) == 0) {
625  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
627  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
628  return TRUE;
629  }
630 
631  ndc_help(sd, helpstr, help, argc, argv);
632  return TRUE;
633  }
634 
635  /*
636  **
637  **
638  */
639  if (strcasecmp(cmd, "GREYDELETE") == 0) {
640  char *db, *key;
641 
642  helpstr = "200 Not yet implemented !!!\r\n";
643 
644  if (help) {
645  ndc_help(sd, helpstr, help, argc, argv);
646  return TRUE;
647  }
648 
649  db = argv[1];
650  key = argv[2];
651 
652  if (db == NULL || key == NULL)
653  return FALSE;
654 
655  FD_PRINTF(sd, "200 OK for %s %s from %s !\r\n", cmd, key, db);
656 
657  ndc_help(sd, helpstr, help, argc, argv);
658  return TRUE;
659  }
660 
661  /*
662  **
663  **
664  */
665  if (strcasecmp(cmd, "SHOW") == 0) {
666  if (arg == NULL)
667  return FALSE;
668 
669  if (help) {
670  ndc_help(sd, helpstr, help, argc, argv);
671  return TRUE;
672  }
673 
674  if (strcasecmp(arg, "RUN") == 0) {
675  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
676  dump_j_conf(sd);
677  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
678  return TRUE;
679  }
680 
681  ndc_help(sd, helpstr, help, argc, argv);
682  return TRUE;
683  }
684 
685  /*
686  **
687  **
688  */
689  if (strcasecmp(cmd, "STATS") == 0) {
690  if (arg == NULL)
691  return FALSE;
692 
693  if (strcasecmp(arg, "ORACLE") == 0) {
694  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
696  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
697  return TRUE;
698  }
699 
700  if (strcasecmp(arg, "THROTTLE") == 0) {
701  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
702  smtprate_print_table(sd, 0, FALSE, FALSE, 3600, -1, 0);
703  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
704  return TRUE;
705  }
706 
707  if (strcasecmp(arg, "SMTPRATE") == 0) {
708  uint32_t flags;
709  char *prmt = STRNULL(argv[2], "");
710 
711  flags = smtprate_str2flags(prmt);
712  if (flags == 0) {
713  SET_BIT(flags, RATE_CONN);
714  SET_BIT(flags, RATE_RCPT);
715  }
716 
717  FD_PRINTF(sd, "200 FLAGS %08X for %s !\r\n", flags, prmt);
718 
719  FD_PRINTF(sd, "200 OK for %s %s %s!\r\n", cmd, arg, prmt);
720  smtprate_print_table(sd, 1, FALSE, FALSE, 3600, flags, 0);
721  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
722  return TRUE;
723  }
724 
725  if (strcasecmp(arg, "CONNOPEN") == 0) {
726  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
728  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
729  return TRUE;
730  }
731 
732  if (strcasecmp(arg, "HTIMES") == 0) {
733  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
735  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
736  return TRUE;
737  }
738 
739  if (strcasecmp(arg, "RAWHTIMES") == 0) {
740  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
742  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
743  return TRUE;
744  }
745 
746  if (strcasecmp(arg, "COUNTERS") == 0) {
747  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
748  dump_state(sd, 1, 1, FALSE, FALSE);
749  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
750  return TRUE;
751  }
752 
753  if (strcasecmp(arg, "RAWCOUNTERS") == 0) {
754  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
756  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
757  return TRUE;
758  }
759 
760  if (strcasecmp(arg, "SCORES") == 0) {
761  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
762  msg_score_stats_print(sd, 0);
763  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
764  return TRUE;
765  }
766 
767  if (strcasecmp(arg, "ORASCORE") == 0) {
768  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
769  msg_score_stats_print(sd, 2);
770  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
771  return TRUE;
772  }
773 
774  if (strcasecmp(arg, "REGSCORE") == 0) {
775  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
776  msg_score_stats_print(sd, 1);
777  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
778  return TRUE;
779  }
780 
781  if (strcasecmp(arg, "LIVEHISTORY") == 0) {
782  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
784  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
785  return TRUE;
786  }
787 
788  if (strcasecmp(arg, "LIVEHISTORY_R") == 0) {
789  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
791  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
792  return TRUE;
793  }
794 
795  ndc_help(sd, helpstr, help, argc, argv);
796  return TRUE;
797  }
798 
799  /*
800  **
801  **
802  */
803  if (strcasecmp(cmd, "RECONFIG") == 0) {
804  arg = STRNULL(arg, "");
805 
806  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
807  configure("ze-filter", conf_file, FALSE);
808  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
809  return TRUE;
810  }
811 
812 
813  /*
814  **
815  **
816  */
817  if (strcasecmp(cmd, "RELOAD") == 0 || strcasecmp(cmd, "REOPEN") == 0) {
818  if (arg == NULL)
819  return FALSE;
820 
821  if (strcasecmp(arg, "TABLES") == 0) {
822  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
824  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
825  return TRUE;
826  }
827 
828  if (strcasecmp(arg, "DATABASES") == 0) {
829  bool ok = FALSE;
830 
831  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
833  FD_PRINTF(sd, "200 URLBL : %s\n", STRBOOL(ok, "OK", "ERROR"));
834  ok = policy_reopen();
835  FD_PRINTF(sd, "200 POLICY : %s\n", STRBOOL(ok, "OK", "ERROR"));
836  ok = rcpt_reopen();
837  FD_PRINTF(sd, "200 USER : %s\n", STRBOOL(ok, "OK", "ERROR"));
838  ok = bfilter_db_reopen();
839  FD_PRINTF(sd, "200 BAYES : %s\n", STRBOOL(ok, "OK", "ERROR"));
840 #if 0
841  /*
842  * shall not reopen grey databases - may cause corruption
843  */
844  ok = grey_reload();
845  FD_PRINTF(sd, "200 GREY : %s\n", STRBOOL(ok, "OK", "ERROR"));
846 #endif
847  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
848  return TRUE;
849  }
850 
851  if (strcasecmp(arg, "LRDATA") == 0) {
852  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
854  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
855  return TRUE;
856  }
857 
858  if (strcasecmp(arg, "LOGFILES") == 0) {
859  bool ok = FALSE;
860 
861  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
862  ok = reopen_all_log_files();
863  FD_PRINTF(sd, "200 LOG FILES : %s\n", STRBOOL(ok, "OK", "ERROR"));
864  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
865  return TRUE;
866  }
867 
868  ndc_help(sd, helpstr, help, argc, argv);
869  return TRUE;
870  }
871 
872  /*
873  **
874  **
875  */
876  if (strcasecmp(cmd, "RESET") == 0) {
877  if (arg == NULL)
878  return FALSE;
879 
880  if (strcasecmp(arg, "STATS") == 0) {
881  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
882  reset_state();
883  save_state();
884  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
885  return TRUE;
886  }
887 
888  if (strcasecmp(arg, "GREYERRORS") == 0) {
889  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
891  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
892  return TRUE;
893  }
894 
895  ndc_help(sd, helpstr, help, argc, argv);
896  return TRUE;
897  }
898 
899  /*
900  **
901  **
902  */
903  if (strcasecmp(cmd, "RESTART") == 0) {
904  FD_PRINTF(sd, "200 OK for %s %s !\r\n", cmd, arg);
905  kill(0, SIGTERM);
906  sleep(1);
907  exit(0);
908  FD_PRINTF(sd, "200 %s %s done !\r\n", cmd, arg);
909  return TRUE;
910  }
911 
912  FD_PRINTF(sd, "500 What ? %s %s ?\r\n", STRNULL(cmd, ""), STRNULL(arg, ""));
913 
914  ndc_help(sd, helpstr, TRUE, argc, argv);
915 
916  return FALSE;
917 }
918 
919 /* ****************************************************************************
920  * *
921  * *
922  ******************************************************************************/
923 static bool
924 check_control_access(addr, name, user)
925  char *addr;
926  char *name;
927  char *user;
928 {
929  bool res = FALSE;
930 
931  switch (cf_get_int(CF_CTRL_ACCESS)) {
932  case OPT_NONE:
933  res = TRUE;
934  break;
935  case OPT_ACCESS:
936  {
937  char buf[256];
938 
939  memset(buf, 0, sizeof (buf));
940  if (check_policy("CtrlChan", addr, buf, sizeof (buf), TRUE)) {
941  switch (policy_decode(buf)) {
942  case JC_OK:
943  res = TRUE;
944  break;
945  case JC_REJECT:
946  res = FALSE;
947  break;
948  }
949  }
950  if (!res) {
951  ZE_MessageInfo(9, "addr=(%s)", addr);
953  "Control access denied for %s (%s) by access rules",
954  STRNULL(addr, "UNKNOWN"), STRNULL(name, "UNKNOWN"));
955  }
956  }
957  break;
958  }
959  return res;
960 }
961 
962 
963 #if 0
964 
965 *********************************************************************if
966  (strcasecmp(cmd, "HELP") == 0) {
967  if (strcasecmp(arg, "GET") == 0) {
968  char *hlpstr = " Commands : HELP GET\r\n" " GET \r\n";
969 
970  FD_PRINTF(sd, "200 %s\r\n", PACKAGE);
971 
972  FD_PRINTF(sd, "%s\r\n", hlpstr);
973  FD_PRINTF(sd, "200 OK !!\r\n");
974  return TRUE;
975  }
976 
977  if (strcasecmp(arg, "VERSION") == 0) {
978  char *hlpstr =
979  " Commands : HELP VERSION\r\n" " VERSION \r\n";
980 
981  FD_PRINTF(sd, "200 %s\r\n", PACKAGE);
982 
983  FD_PRINTF(sd, "%s\r\n", hlpstr);
984  FD_PRINTF(sd, "200 OK !!\r\n");
985  return TRUE;
986  }
987 
988  if (strcasecmp(arg, "SET") == 0) {
989  char *hlpstr =
990  " Commands : HELP SET \r\n"
991  " SET \r\n"
992  " URLBLTIME \r\n"
993  " RESOLVEWINDOW \r\n"
994  " DEBUGLEVEL \r\n"
995  " MXCHECKLEVEL \r\n"
996  " TLONGCONN \r\n"
997  " GREYDELAYS \r\n"
998  " GREYLIFETIME \r\n"
999  " GREYPENDING \r\n"
1000  " GREYTUPLE \r\n" " GREYCLEANUP \r\n"
1001  " GREY_DEWHITE_THRESHOLD \r\n";
1002 
1003  FD_PRINTF(sd, "200 %s\r\n", PACKAGE);
1004 
1005  FD_PRINTF(sd, "%s\r\n", hlpstr);
1006  FD_PRINTF(sd, "200 OK !!\r\n");
1007  return TRUE;
1008  }
1009 
1010  if (strcasecmp(arg, "SETCF") == 0) {
1011  char *hlpstr =
1012  " Commands : HELP SETCF \r\n" " SETCF VAR VALUE\r\n";
1013 
1014  FD_PRINTF(sd, "200 %s\r\n", PACKAGE);
1015 
1016  FD_PRINTF(sd, "%s\r\n", hlpstr);
1017  FD_PRINTF(sd, "200 OK !!\r\n");
1018  return TRUE;
1019  }
1020 
1021  if (strcasecmp(arg, "SETORACLE") == 0) {
1022  char *hlpstr =
1023  " Commands : HELP SETORACLE\r\n" " SETORACLE XNN VALUE \r\n";
1024 
1025  FD_PRINTF(sd, "200 %s\r\n", PACKAGE);
1026 
1027  FD_PRINTF(sd, "%s\r\n", hlpstr);
1028  FD_PRINTF(sd, "200 OK !!\r\n");
1029  return TRUE;
1030  }
1031 
1032  if (strcasecmp(arg, "SHOW") == 0) {
1033  char *hlpstr =
1034  " Commands : HELP SHOW \r\n" " SHOW \r\n" " CONF \r\n";
1035 
1036  FD_PRINTF(sd, "200 %s\r\n", PACKAGE);
1037 
1038  FD_PRINTF(sd, "%s\r\n", hlpstr);
1039  FD_PRINTF(sd, "200 OK !!\r\n");
1040  return TRUE;
1041  }
1042 
1043  if (strcasecmp(arg, "STATS") == 0) {
1044  char *hlpstr =
1045  " Commands : HELP STATS\r\n"
1046  " STATS \r\n"
1047  " ORACLE \r\n"
1048  " SCORES \r\n"
1049  " ORASCORE \r\n"
1050  " REGSCORE \r\n"
1051  " THROTTLE \r\n"
1052  " SMTPRATE \r\n"
1053  " CONNOPEN \r\n"
1054  " LIVEHISTORY \r\n" " COUNTERS \r\n" " RAWCOUNTERS \r\n";
1055 
1056  FD_PRINTF(sd, "200 %s\r\n", PACKAGE);
1057 
1058  FD_PRINTF(sd, "%s\r\n", hlpstr);
1059  FD_PRINTF(sd, "200 OK !!\r\n");
1060  return TRUE;
1061  }
1062 
1063  if (strcasecmp(arg, "RECONFIG") == 0) {
1064  char *hlpstr =
1065  " Commands : HELP RECONFIG \r\n" " RECONFIG \r\n";
1066 
1067  FD_PRINTF(sd, "200 %s\r\n", PACKAGE);
1068 
1069  FD_PRINTF(sd, "%s\r\n", hlpstr);
1070  FD_PRINTF(sd, "200 OK !!\r\n");
1071  return TRUE;
1072  }
1073 
1074  if (strcasecmp(arg, "RELOAD") == 0) {
1075  char *hlpstr =
1076  " Commands : HELP RELOAD | REOPAN\r\n"
1077  " RELOAD | REOPEN \r\n"
1078  " TABLES \r\n" " DATABASES \r\n" " LOGFILES \r\n";
1079 
1080  FD_PRINTF(sd, "200 %s\r\n", PACKAGE);
1081 
1082  FD_PRINTF(sd, "%s\r\n", hlpstr);
1083  FD_PRINTF(sd, "200 OK !!\r\n");
1084  return TRUE;
1085  }
1086 
1087  if (strcasecmp(arg, "RESTART") == 0) {
1088  char *hlpstr =
1089  " Commands : HELP RESTART \r\n" " RESTART \r\n";
1090 
1091  FD_PRINTF(sd, "200 %s\r\n", PACKAGE);
1092 
1093  FD_PRINTF(sd, "%s\r\n", hlpstr);
1094  FD_PRINTF(sd, "200 OK !!\r\n");
1095  return TRUE;
1096  }
1097 
1098  if (strcasecmp(arg, "RESET") == 0) {
1099  char *hlpstr =
1100  " Commands : HELP RESET \r\n"
1101  " RESET \r\n" " STATS\r\n" " GREYERRORS\r\n";
1102 
1103  FD_PRINTF(sd, "200 %s\r\n", PACKAGE);
1104 
1105  FD_PRINTF(sd, "%s\r\n", hlpstr);
1106  FD_PRINTF(sd, "200 OK !!\r\n");
1107  return TRUE;
1108  }
1109 }
1110 #endif
bool bfilter_db_reopen()
Definition: ze-bfilter.c:614
#define STRBOOL(x, t, f)
Definition: macros.h:87
int socklen_t
Definition: ze-sys.h:534
void grey_set_compat_domain_check(bool enable)
Definition: ze-grey.c:473
#define CF_CTRL_ACCESS
Definition: cfh-defs.h:50
int cf_set_val(int id, char *val)
Definition: ze-cf.c:691
bool check_policy(char *prefix, char *key, char *buf, size_t size, bool cdef)
Definition: ze-policy.c:119
bool grey_set_cleanup_interval(time_t tclean)
Definition: ze-grey.c:459
bool log_sm_macros
Definition: ze-smmacros.c:147
#define OPT_NONE
Definition: ze-cf.h:70
uint32_t smtprate_str2flags(char *)
Definition: ze-smtprate.c:1150
#define ZE_FUNCTION
Definition: ze-sys.h:471
#define CF_CTRL_SOCKET
Definition: cfh-defs.h:49
bool grey_set_tuples(char *ip, char *from, char *to)
Definition: ze-grey.c:355
#define MAX_ARGS
Definition: ze-ndc-server.c:39
#define FREE(x)
Definition: macros.h:37
bool setup_control_handler()
void dump_j_conf(int)
Definition: ze-config.c:748
int ze_logLevel
Definition: zeSyslog.c:34
#define STRNULL(x, r)
Definition: macros.h:81
bool ok
Definition: ze-connopen.c:59
bool grey_set_delays(time_t tp_min_norm, time_t tp_max_norm, time_t tp_min_null, time_t tp_max_null)
Definition: ze-grey.c:399
int dump_state(int, int, int, int, int)
#define CF_LOG_LEVEL
Definition: cfh-defs.h:56
void livehistory_log_table(int, bool)
int jfd_ready(int, bool, long)
Definition: ze-inet.c:529
#define FALSE
Definition: macros.h:160
void mk_cf_file(int, bool, bool)
Definition: ze-cf.c:353
bool zeStrRegex(char *, char *, long *, long *, bool)
Definition: zeStrings.c:544
void log_counters(int, bool)
Definition: ze-stats.c:330
time_t tlongconn
Definition: ze-filter.c:93
bool policy_reopen()
Definition: ze-policy.c:712
bool oracle_set_score(int, int, double)
#define MK_CF_DEFAULT
Definition: ze-cf.h:41
#define FD_PRINTF(fdp,...)
Definition: macros.h:45
char * zeStrChomp(char *)
Definition: zeStrings.c:501
void save_state()
Definition: ze-stats.c:430
bool jsock_ntop(struct sockaddr *, socklen_t, char *, size_t)
Definition: ze-inet.c:106
int cf_get_int(int id)
Definition: ze-cf.c:803
#define SET_BIT(p, i)
Definition: macros.h:166
bool rcpt_reopen()
Definition: ze-rcpt.c:572
bool callback_stats_dump(int fd, bool line)
Definition: ze-callback.c:91
bool get_hostbyaddr(char *ip, char *name, int len)
Definition: ze-inet.c:323
int policy_decode(char *)
Definition: ze-policy.c:722
void set_grey_dewhitelist_threshold(double val)
bool ndc_help(int fd, char *helpstr, bool help, int argc, char **argv)
Definition: ze-ndc-help.c:262
long zeStr2long(char *s, int *error, long dval)
Definition: zeStrConvert.c:35
socklen_t socklen
Definition: ze-server.h:33
#define ORACLE_TYPE_HTML
void grey_channel_error_clear()
#define CF_GREY_DEWHITE_FLAGS
Definition: cfh-defs.h:209
bool grey_set_lifetime(time_t tv, time_t tw, time_t tb)
Definition: ze-grey.c:422
bool get_hostbysock(struct sockaddr *sock, socklen_t slen, char *addr, size_t alen, char *name, size_t nlen)
Definition: ze-inet.c:421
double zeStr2double(char *s, int *error, double dval)
Definition: zeStrConvert.c:202
#define ZE_MessageInfo(level,...)
Definition: zeSyslog.h:90
int nb
Definition: ze-connopen.c:61
#define OPT_NO
Definition: ze-cf.h:44
#define TRUE
Definition: macros.h:157
#define ZE_MessageWarning(level,...)
Definition: zeSyslog.h:92
bool lr_data_load(bool background)
Definition: ze-lr-init.c:48
#define JC_OK
Definition: ze-policy.h:69
#define ZE_LogSysError(...)
Definition: zeSyslog.h:129
#define ZE_MessageError(level,...)
Definition: zeSyslog.h:93
char * cf_get_str(int id)
Definition: ze-cf.c:854
#define RATE_RCPT
Definition: ze-smtprate.h:52
char * conf_file
Definition: ze-cf.c:38
#define CF_CTRL_CHANNEL_ENABLE
Definition: cfh-defs.h:48
#define CF_GREY_COMPAT_DOMAIN_CHECK
Definition: cfh-defs.h:203
void reset_state()
Definition: ze-stats.c:528
void grey_set_dewhite_flags(char *, bool)
Definition: ze-grey.c:1772
int configure(char *, char *, bool)
Definition: ze-cf.c:1203
#define ORACLE_TYPE_PLAIN
void connopen_print_table(int)
Definition: ze-connopen.c:313
char * zeStr2Upper(char *)
Definition: zeStrings.c:312
bool reopen_all_log_files()
Definition: ze-signal.c:267
char * zeStr2Lower(char *)
Definition: zeStrings.c:295
bool grey_set_max_pending(int normal, int bounce)
Definition: ze-grey.c:442
int mx_check_level
Definition: ze-mxcheck.c:69
#define PACKAGE
Definition: version.h:28
#define CF_DUMP_COUNTERS
Definition: cfh-defs.h:63
#define MK_CF_RUNNING
Definition: ze-cf.h:42
int family
Definition: ze-server.h:30
#define STRCASEEQUAL(a, b)
Definition: macros.h:72
#define ZE_SOCK_READ
Definition: ze-inet.h:57
bool oracle_dump_counters(int, bool)
int server_listen(char *spec, server_T *server)
Definition: ze-server.c:334
#define ORACLE_TYPE_MSG
bool db_reopen_rurlbl_database()
Definition: ze-mailregex.c:840
void reload_cf_tables()
Definition: ze-cf.c:1066
#define ZE_SOCK_READY
Definition: ze-inet.h:61
void msg_score_stats_print(int, int)
Definition: ze-stats.c:118
long uint32_t
Definition: ze-sys.h:489
int cf_get_id(char *)
Definition: ze-cf.c:657
#define MK_CF_NONE
Definition: ze-cf.h:39
bool grey_reload()
Definition: ze-grey.c:1393
#define JC_REJECT
Definition: ze-policy.h:70
#define OPT_ACCESS
Definition: ze-cf.h:71
#define ORACLE_TYPE_CONN
time_t zeStr2time(char *s, int *error, time_t dval)
Definition: zeStrConvert.c:291
#define RATE_CONN
Definition: ze-smtprate.h:51
#define CTRL_TO
Definition: ze-ndc-server.c:38
void smtprate_print_table(int, int, int, int, time_t, uint32_t, int)