Commit e75e9123 e75e9123344ff44bacdbe28d071411e6799384ec by Sergey Poznyakoff

Implement session ID for TCP/UDP servers.

* imap4d/imap4d.c (set_strerr_flt,clr_strerr_flt): New functions.
(imap4d_connection): Setup session prefix in strerr if
mu_log_session_id is set.
* imap4d/io.c (io_setio): Bugfix: unref debug stream.
* pop3d/extra.c (pop3d_setio): Likewise.
* pop3d/pop3d.c (set_strerr_flt,clr_strerr_flt): New functions.
(pop3d_connection): Setup session prefix in strerr if
mu_log_session_id is set.

* include/mailutils/acl.h (mu_acl_setenv)
(mu_acl_getenv,mu_acl_set_session_id): New functions.
* include/mailutils/server.h (mu_session_id): New extern.
(mu_m_server_configured_count): Fix signature.
* include/mailutils/syslog.h (mu_log_session_id): New extern.
* libmailutils/diag/syslog.c (mu_log_session_id): New global.

* libmailutils/server/acl.c (_mu_acl) <envv,envc,envn>: New
members.
(run_closure) <env>: New member.
(mu_acl_destroy): Free environment.
(_acl_match): Handle "family" variable.
(expand_arg): Propagate ACL environment to wordsplit.
(mu_acl_check_sockaddr): Propagate ACL environment.
(mu_acl_setenv)
(mu_acl_getenv,mu_acl_set_session_id): New functions.

* libmailutils/server/ipsrv.c (mu_ip_tcp_accept): Store session ID
in the ACL.
(mu_ip_udp_accept): Likewise.
* libmailutils/server/msrv.c (mu_m_server_configured_count): Fix
signature.
(mu_m_server_check_acl): Store session ID in the ACL.
* libmailutils/server/server.c (mu_session_id): New global variable.
(connection_loop): Increment session ID
(mu_acl_set_session_id): New function.
* libmailutils/stream/fltstream.c (filter_ctl): Handle
MU_IOCTL_SUBSTREAM.
* libmailutils/stream/logstream.c (_log_ctl): Likewise.
* libmu_cfg/common.c (mu_logging_param) <session-id>: New statement.
1 parent da65d500
...@@ -409,6 +409,69 @@ get_client_address (int fd, struct sockaddr_in *pcs) ...@@ -409,6 +409,69 @@ get_client_address (int fd, struct sockaddr_in *pcs)
409 return 0; 409 return 0;
410 } 410 }
411 411
412 static int
413 set_strerr_flt ()
414 {
415 mu_stream_t flt, trans[2];
416 int rc;
417
418 rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_SUBSTREAM, MU_IOCTL_OP_GET, trans);
419 if (rc == 0)
420 {
421 char sessidstr[10];
422 char *argv[] = { "inline-comment", NULL, "-S", NULL };
423
424 snprintf (sessidstr, sizeof sessidstr, "%08lx:", mu_session_id);
425 argv[1] = sessidstr;
426 rc = mu_filter_create_args (&flt, trans[0], "inline-comment", 3,
427 (const char **)argv,
428 MU_FILTER_ENCODE, MU_STREAM_WRITE);
429 mu_stream_unref (trans[0]);
430 if (rc == 0)
431 {
432 mu_stream_set_buffer (flt, mu_buffer_line, 0);
433 trans[0] = flt;
434 trans[1] = NULL;
435 rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_SUBSTREAM,
436 MU_IOCTL_OP_SET, trans);
437 mu_stream_unref (trans[0]);
438 if (rc)
439 mu_error (_("%s failed: %s"), "MU_IOCTL_SET_STREAM",
440 mu_stream_strerror (mu_strerr, rc));
441 }
442 else
443 mu_error (_("cannot create log filter stream: %s"), mu_strerror (rc));
444 }
445 else
446 {
447 mu_error (_("%s failed: %s"), "MU_IOCTL_GET_STREAM",
448 mu_stream_strerror (mu_strerr, rc));
449 }
450 return rc;
451 }
452
453 static void
454 clr_strerr_flt ()
455 {
456 mu_stream_t flt, trans[2];
457 int rc;
458
459 rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_SUBSTREAM, MU_IOCTL_OP_GET, trans);
460 if (rc == 0)
461 {
462 flt = trans[0];
463
464 rc = mu_stream_ioctl (flt, MU_IOCTL_SUBSTREAM, MU_IOCTL_OP_GET, trans);
465 if (rc == 0)
466 {
467 mu_stream_unref (trans[0]);
468 rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_SUBSTREAM,
469 MU_IOCTL_OP_SET, trans);
470 if (rc == 0)
471 mu_stream_unref (flt);
472 }
473 }
474 }
412 475
413 void 476 void
414 imap4d_child_signal_setup (RETSIGTYPE (*handler) (int signo)) 477 imap4d_child_signal_setup (RETSIGTYPE (*handler) (int signo))
...@@ -507,10 +570,21 @@ imap4d_connection (int fd, struct sockaddr *sa, int salen, ...@@ -507,10 +570,21 @@ imap4d_connection (int fd, struct sockaddr *sa, int salen,
507 struct mu_srv_config *pconf, void *data) 570 struct mu_srv_config *pconf, void *data)
508 { 571 {
509 struct imap4d_srv_config *cfg = (struct imap4d_srv_config *) pconf; 572 struct imap4d_srv_config *cfg = (struct imap4d_srv_config *) pconf;
573 int rc;
510 574
511 idle_timeout = pconf->timeout; 575 idle_timeout = pconf->timeout;
512 imap4d_transcript = pconf->transcript; 576 imap4d_transcript = pconf->transcript;
577
578 if (mu_log_session_id)
579 rc = set_strerr_flt ();
580 else
581 rc = 1;
582
513 imap4d_mainloop (fd, fd, cfg->tls); 583 imap4d_mainloop (fd, fd, cfg->tls);
584
585 if (rc == 0)
586 clr_strerr_flt ();
587
514 return 0; 588 return 0;
515 } 589 }
516 590
......
...@@ -76,6 +76,7 @@ io_setio (int ifd, int ofd, int tls) ...@@ -76,6 +76,7 @@ io_setio (int ifd, int ofd, int tls)
76 else 76 else
77 { 77 {
78 rc = mu_xscript_stream_create (&xstr, iostream, dstr, NULL); 78 rc = mu_xscript_stream_create (&xstr, iostream, dstr, NULL);
79 mu_stream_unref (dstr);
79 if (rc) 80 if (rc)
80 mu_error (_("cannot create transcript stream: %s"), 81 mu_error (_("cannot create transcript stream: %s"),
81 mu_strerror (rc)); 82 mu_strerror (rc));
......
...@@ -63,4 +63,8 @@ int mu_acl_check_fd (mu_acl_t acl, int fd, mu_acl_result_t *pres); ...@@ -63,4 +63,8 @@ int mu_acl_check_fd (mu_acl_t acl, int fd, mu_acl_result_t *pres);
63 int mu_acl_action_to_string (mu_acl_action_t act, const char **pstr); 63 int mu_acl_action_to_string (mu_acl_action_t act, const char **pstr);
64 int mu_acl_string_to_action (const char *str, mu_acl_action_t *pres); 64 int mu_acl_string_to_action (const char *str, mu_acl_action_t *pres);
65 65
66 int mu_acl_setenv (mu_acl_t acl, const char *name, const char *val);
67 const char *mu_acl_getenv (mu_acl_t acl, const char *name);
68 int mu_acl_set_session_id (mu_acl_t acl);
69
66 #endif 70 #endif
......
...@@ -21,6 +21,8 @@ ...@@ -21,6 +21,8 @@
21 #include <mailutils/types.h> 21 #include <mailutils/types.h>
22 #include <signal.h> 22 #include <signal.h>
23 23
24 extern unsigned long mu_session_id;
25
24 typedef int (*mu_conn_loop_fp) (int fd, void *conn_data, void *server_data); 26 typedef int (*mu_conn_loop_fp) (int fd, void *conn_data, void *server_data);
25 typedef void (*mu_conn_free_fp) (void *conn_data, void *server_data); 27 typedef void (*mu_conn_free_fp) (void *conn_data, void *server_data);
26 typedef int (*mu_server_idle_fp) (void *server_data); 28 typedef int (*mu_server_idle_fp) (void *server_data);
...@@ -124,7 +126,7 @@ const char * mu_m_server_pidfile (mu_m_server_t srv); ...@@ -124,7 +126,7 @@ const char * mu_m_server_pidfile (mu_m_server_t srv);
124 void mu_m_server_get_sigset (mu_m_server_t srv, sigset_t *sigset); 126 void mu_m_server_get_sigset (mu_m_server_t srv, sigset_t *sigset);
125 int mu_m_server_get_srvlist (mu_m_server_t srv, mu_list_t *plist); 127 int mu_m_server_get_srvlist (mu_m_server_t srv, mu_list_t *plist);
126 128
127 void mu_m_server_configured_count (mu_m_server_t msrv, size_t count); 129 void mu_m_server_configured_count (mu_m_server_t msrv, size_t *count);
128 130
129 void mu_m_server_begin (mu_m_server_t msrv); 131 void mu_m_server_begin (mu_m_server_t msrv);
130 int mu_m_server_run (mu_m_server_t msrv); 132 int mu_m_server_run (mu_m_server_t msrv);
......
...@@ -29,6 +29,7 @@ extern int mu_log_facility; ...@@ -29,6 +29,7 @@ extern int mu_log_facility;
29 extern char *mu_log_tag; 29 extern char *mu_log_tag;
30 extern int mu_log_print_severity; 30 extern int mu_log_print_severity;
31 extern unsigned mu_log_severity_threshold; 31 extern unsigned mu_log_severity_threshold;
32 extern int mu_log_session_id;
32 33
33 #define MU_LOG_TAG() (mu_log_tag ? mu_log_tag : mu_program_name) 34 #define MU_LOG_TAG() (mu_log_tag ? mu_log_tag : mu_program_name)
34 35
......
...@@ -133,3 +133,4 @@ int mu_log_facility = LOG_FACILITY; ...@@ -133,3 +133,4 @@ int mu_log_facility = LOG_FACILITY;
133 char *mu_log_tag = NULL; 133 char *mu_log_tag = NULL;
134 int mu_log_print_severity = 0; 134 int mu_log_print_severity = 0;
135 unsigned mu_log_severity_threshold = MU_LOG_DEBUG; 135 unsigned mu_log_severity_threshold = MU_LOG_DEBUG;
136 int mu_log_session_id;
......
...@@ -58,6 +58,21 @@ struct _mu_acl_entry ...@@ -58,6 +58,21 @@ struct _mu_acl_entry
58 struct _mu_acl 58 struct _mu_acl
59 { 59 {
60 mu_list_t aclist; 60 mu_list_t aclist;
61 char **envv;
62 size_t envc;
63 size_t envn;
64 };
65
66 struct run_closure
67 {
68 unsigned idx;
69 struct mu_cidr addr;
70
71 char **env;
72 char ipstr[40];
73 char *addrstr;
74 char *numbuf;
75 mu_acl_result_t *result;
61 }; 76 };
62 77
63 78
...@@ -117,11 +132,16 @@ mu_acl_count (mu_acl_t acl, size_t *pcount) ...@@ -117,11 +132,16 @@ mu_acl_count (mu_acl_t acl, size_t *pcount)
117 int 132 int
118 mu_acl_destroy (mu_acl_t *pacl) 133 mu_acl_destroy (mu_acl_t *pacl)
119 { 134 {
135 size_t i;
136
120 mu_acl_t acl; 137 mu_acl_t acl;
121 if (!pacl || !*pacl) 138 if (!pacl || !*pacl)
122 return EINVAL; 139 return EINVAL;
123 acl = *pacl; 140 acl = *pacl;
124 mu_list_destroy (&acl->aclist); 141 mu_list_destroy (&acl->aclist);
142 for (i = 0; i < acl->envc && acl->envv[i]; i++)
143 free (acl->envv[i]);
144 free (acl->envv);
125 free (acl); 145 free (acl);
126 *pacl = acl; 146 *pacl = acl;
127 return 0; 147 return 0;
...@@ -249,17 +269,6 @@ mu_acl_string_to_action (const char *str, mu_acl_action_t *pres) ...@@ -249,17 +269,6 @@ mu_acl_string_to_action (const char *str, mu_acl_action_t *pres)
249 return rc; 269 return rc;
250 } 270 }
251 271
252 struct run_closure
253 {
254 unsigned idx;
255 struct mu_cidr addr;
256
257 char ipstr[40];
258 char *addrstr;
259 char *numbuf;
260 mu_acl_result_t *result;
261 };
262
263 int 272 int
264 _acl_match (struct _mu_acl_entry *ent, struct run_closure *rp) 273 _acl_match (struct _mu_acl_entry *ent, struct run_closure *rp)
265 { 274 {
...@@ -297,6 +306,26 @@ acl_getvar (const char *name, size_t nlen, void *data) ...@@ -297,6 +306,26 @@ acl_getvar (const char *name, size_t nlen, void *data)
297 { 306 {
298 struct run_closure *rp = data; 307 struct run_closure *rp = data;
299 308
309 if (SEQ ("family", name, nlen))
310 {
311 switch (rp->addr.family)
312 {
313 case AF_INET:
314 return "AF_INET";
315
316 #ifdef MAILUTILS_IPV6
317 case AF_INET6:
318 return "AF_INET6";
319 #endif
320
321 case AF_UNIX:
322 return "AF_UNIX";
323
324 default:
325 return NULL;
326 }
327 }
328
300 if (SEQ ("aclno", name, nlen)) 329 if (SEQ ("aclno", name, nlen))
301 { 330 {
302 if (!rp->numbuf && mu_asprintf (&rp->numbuf, "%u", rp->idx)) 331 if (!rp->numbuf && mu_asprintf (&rp->numbuf, "%u", rp->idx))
...@@ -330,33 +359,19 @@ expand_arg (const char *cmdline, struct run_closure *rp, char **s) ...@@ -330,33 +359,19 @@ expand_arg (const char *cmdline, struct run_closure *rp, char **s)
330 { 359 {
331 int rc; 360 int rc;
332 struct mu_wordsplit ws; 361 struct mu_wordsplit ws;
333 const char *env[3]; 362 int envflag = 0;
334 363
335 mu_debug (MU_DEBCAT_ACL, MU_DEBUG_TRACE, ("Expanding \"%s\"", cmdline)); 364 mu_debug (MU_DEBCAT_ACL, MU_DEBUG_TRACE, ("Expanding \"%s\"", cmdline));
336 env[0] = "family"; 365 if (rp->env)
337 switch (rp->addr.family)
338 { 366 {
339 case AF_INET: 367 ws.ws_env = (const char **) rp->env;
340 env[1] = "AF_INET"; 368 envflag = MU_WRDSF_ENV;
341 break;
342
343 #ifdef MAILUTILS_IPV6
344 case AF_INET6:
345 env[1] = "AF_INET6";
346 break;
347 #endif
348
349 case AF_UNIX:
350 env[1] = "AF_UNIX";
351 break;
352 } 369 }
353 env[2] = NULL;
354 ws.ws_env = env;
355 ws.ws_getvar = acl_getvar; 370 ws.ws_getvar = acl_getvar;
356 ws.ws_closure = rp; 371 ws.ws_closure = rp;
357 rc = mu_wordsplit (cmdline, &ws, 372 rc = mu_wordsplit (cmdline, &ws,
358 MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD | 373 MU_WRDSF_NOSPLIT | MU_WRDSF_NOCMD |
359 MU_WRDSF_ENV | MU_WRDSF_ENV_KV | 374 envflag | MU_WRDSF_ENV_KV |
360 MU_WRDSF_GETVAR | MU_WRDSF_CLOSURE); 375 MU_WRDSF_GETVAR | MU_WRDSF_CLOSURE);
361 376
362 if (rc == 0) 377 if (rc == 0)
...@@ -553,6 +568,7 @@ mu_acl_check_sockaddr (mu_acl_t acl, const struct sockaddr *sa, int salen, ...@@ -553,6 +568,7 @@ mu_acl_check_sockaddr (mu_acl_t acl, const struct sockaddr *sa, int salen,
553 568
554 r.idx = 0; 569 r.idx = 0;
555 r.result = pres; 570 r.result = pres;
571 r.env = acl->envv;
556 *r.result = mu_acl_result_undefined; 572 *r.result = mu_acl_result_undefined;
557 r.numbuf = NULL; 573 r.numbuf = NULL;
558 mu_list_foreach (acl->aclist, _run_entry, &r); 574 mu_list_foreach (acl->aclist, _run_entry, &r);
...@@ -607,3 +623,94 @@ mu_acl_check_fd (mu_acl_t acl, int fd, mu_acl_result_t *pres) ...@@ -607,3 +623,94 @@ mu_acl_check_fd (mu_acl_t acl, int fd, mu_acl_result_t *pres)
607 return mu_acl_check_sockaddr (acl, &addr.sa, len, pres); 623 return mu_acl_check_sockaddr (acl, &addr.sa, len, pres);
608 } 624 }
609 625
626 static int
627 _acl_getenv (mu_acl_t acl, const char *name, size_t *pres)
628 {
629 size_t i;
630
631 if (!acl->envv)
632 return MU_ERR_NOENT;
633 for (i = 0; i < acl->envc; i++)
634 if (strcmp (acl->envv[i], name) == 0)
635 {
636 *pres = i;
637 return 0;
638 }
639 return MU_ERR_NOENT;
640 }
641
642 const char *
643 mu_acl_getenv (mu_acl_t acl, const char *name)
644 {
645 size_t i;
646
647 if (_acl_getenv (acl, name, &i) == 0)
648 {
649 return acl->envv[i + 1];
650 }
651 return NULL;
652 }
653
654 static int
655 _acl_env_store (mu_acl_t acl, int i, const char *val)
656 {
657 char *copy = strdup (val);
658 if (!copy)
659 return ENOMEM;
660 free (acl->envv[i]);
661 acl->envv[i] = copy;
662 return 0;
663 }
664
665 int
666 mu_acl_setenv (mu_acl_t acl, const char *name, const char *val)
667 {
668 size_t i;
669
670 if (_acl_getenv (acl, name, &i) == 0)
671 {
672 if (!val)
673 {
674 free (acl->envv[i]);
675 free (acl->envv[i + 1]);
676 memmove (acl->envv + i, acl->envv + i + 3,
677 (acl->envn + 1 - (i + 3)) * sizeof (acl->envv[0]));
678 acl->envn -= 2;
679 return 0;
680 }
681 return _acl_env_store (acl, i + 1, val);
682 }
683
684 if (!acl->envv || acl->envn + 1 == acl->envc)
685 {
686 char **p;
687
688 if (!val)
689 return 0;
690
691 if (acl->envv == NULL)
692 p = calloc (3, sizeof (acl->envv[0]));
693 else
694 {
695 p = realloc (acl->envv, (acl->envc + 3) * sizeof (acl->envv[0]));
696 if (!p)
697 return ENOMEM;
698 p[acl->envc] = NULL;
699 }
700
701 acl->envv = p;
702 acl->envc += 3;
703 }
704
705 if (_acl_env_store (acl, acl->envn, name))
706 return ENOMEM;
707 if (_acl_env_store (acl, acl->envn + 1, val))
708 {
709 free (acl->envv[acl->envn]);
710 acl->envv[acl->envn] = NULL;
711 return ENOMEM;
712 }
713 acl->envn += 2;
714
715 return 0;
716 }
......
...@@ -372,7 +372,10 @@ mu_ip_tcp_accept (mu_ip_server_t srv, void *call_data) ...@@ -372,7 +372,10 @@ mu_ip_tcp_accept (mu_ip_server_t srv, void *call_data)
372 if (srv->acl) 372 if (srv->acl)
373 { 373 {
374 mu_acl_result_t res; 374 mu_acl_result_t res;
375 int rc = mu_acl_check_sockaddr (srv->acl, &client.sa, size, &res); 375 int rc;
376
377 mu_acl_set_session_id (srv->acl);
378 rc = mu_acl_check_sockaddr (srv->acl, &client.sa, size, &res);
376 if (rc) 379 if (rc)
377 mu_debug (MU_DEBCAT_SERVER, MU_DEBUG_ERROR, 380 mu_debug (MU_DEBCAT_SERVER, MU_DEBUG_ERROR,
378 ("%s: mu_acl_check_sockaddr: %s", 381 ("%s: mu_acl_check_sockaddr: %s",
...@@ -453,7 +456,10 @@ mu_ip_udp_accept (mu_ip_server_t srv, void *call_data) ...@@ -453,7 +456,10 @@ mu_ip_udp_accept (mu_ip_server_t srv, void *call_data)
453 if (srv->acl) 456 if (srv->acl)
454 { 457 {
455 mu_acl_result_t res; 458 mu_acl_result_t res;
456 int rc = mu_acl_check_sockaddr (srv->acl, &client.sa, size, &res); 459 int rc;
460
461 mu_acl_set_session_id (srv->acl);
462 rc = mu_acl_check_sockaddr (srv->acl, &client.sa, size, &res);
457 if (rc) 463 if (rc)
458 mu_debug (MU_DEBCAT_SERVER, MU_DEBUG_ERROR, 464 mu_debug (MU_DEBCAT_SERVER, MU_DEBUG_ERROR,
459 ("%s: mu_acl_check_sockaddr: %s\n", 465 ("%s: mu_acl_check_sockaddr: %s\n",
......
...@@ -343,9 +343,12 @@ mu_m_server_set_max_children (mu_m_server_t srv, size_t num) ...@@ -343,9 +343,12 @@ mu_m_server_set_max_children (mu_m_server_t srv, size_t num)
343 int 343 int
344 mu_m_server_set_pidfile (mu_m_server_t srv, const char *pidfile) 344 mu_m_server_set_pidfile (mu_m_server_t srv, const char *pidfile)
345 { 345 {
346 char *p = strdup (pidfile);
347 if (!p)
348 return errno;
346 free (srv->pidfile); 349 free (srv->pidfile);
347 srv->pidfile = strdup (pidfile); 350 srv->pidfile = p;
348 return srv->pidfile ? 0 : errno; 351 return 0;
349 } 352 }
350 353
351 int 354 int
...@@ -476,9 +479,9 @@ add_server (mu_m_server_t msrv, struct mu_sockaddr *s, int type) ...@@ -476,9 +479,9 @@ add_server (mu_m_server_t msrv, struct mu_sockaddr *s, int type)
476 } 479 }
477 480
478 void 481 void
479 mu_m_server_configured_count (mu_m_server_t msrv, size_t count) 482 mu_m_server_configured_count (mu_m_server_t msrv, size_t *count)
480 { 483 {
481 mu_list_count (msrv->srvlist, &count); 484 mu_list_count (msrv->srvlist, count);
482 } 485 }
483 486
484 void 487 void
...@@ -645,7 +648,10 @@ mu_m_server_check_acl (mu_m_server_t msrv, struct sockaddr *s, int salen) ...@@ -645,7 +648,10 @@ mu_m_server_check_acl (mu_m_server_t msrv, struct sockaddr *s, int salen)
645 if (msrv->acl) 648 if (msrv->acl)
646 { 649 {
647 mu_acl_result_t res; 650 mu_acl_result_t res;
648 int rc = mu_acl_check_sockaddr (msrv->acl, s, salen, &res); 651 int rc;
652
653 mu_acl_set_session_id (msrv->acl);
654 rc = mu_acl_check_sockaddr (msrv->acl, s, salen, &res);
649 if (rc) 655 if (rc)
650 { 656 {
651 char *p = mu_sockaddr_to_astr (s, salen); 657 char *p = mu_sockaddr_to_astr (s, salen);
......
...@@ -38,6 +38,8 @@ struct _mu_connection ...@@ -38,6 +38,8 @@ struct _mu_connection
38 38
39 #define MU_SERVER_TIMEOUT 0x1 39 #define MU_SERVER_TIMEOUT 0x1
40 40
41 unsigned long mu_session_id;
42
41 struct _mu_server 43 struct _mu_server
42 { 44 {
43 int nfd; 45 int nfd;
...@@ -104,7 +106,10 @@ connection_loop (mu_server_t srv, fd_set *fdset) ...@@ -104,7 +106,10 @@ connection_loop (mu_server_t srv, fd_set *fdset)
104 struct _mu_connection *next = conn->next; 106 struct _mu_connection *next = conn->next;
105 if (FD_ISSET (conn->fd, fdset)) 107 if (FD_ISSET (conn->fd, fdset))
106 { 108 {
107 int rc = conn->f_loop (conn->fd, conn->data, srv->server_data); 109 int rc;
110
111 ++mu_session_id;
112 rc = conn->f_loop (conn->fd, conn->data, srv->server_data);
108 switch (rc) 113 switch (rc)
109 { 114 {
110 case 0: 115 case 0:
...@@ -291,3 +296,12 @@ mu_server_add_connection (mu_server_t srv, ...@@ -291,3 +296,12 @@ mu_server_add_connection (mu_server_t srv,
291 srv->tail = p; 296 srv->tail = p;
292 return 0; 297 return 0;
293 } 298 }
299
300 int
301 mu_acl_set_session_id (mu_acl_t acl)
302 {
303 char sessidstr[9];
304 snprintf (sessidstr, sizeof sessidstr, "%08lx", mu_session_id);
305 return mu_acl_setenv (acl, "sessid", sessidstr);
306 }
307
......
...@@ -422,6 +422,32 @@ filter_ctl (struct _mu_stream *stream, int code, int opcode, void *ptr) ...@@ -422,6 +422,32 @@ filter_ctl (struct _mu_stream *stream, int code, int opcode, void *ptr)
422 } 422 }
423 break; 423 break;
424 424
425 case MU_IOCTL_SUBSTREAM:
426 if (!ptr)
427 return EINVAL;
428 else
429 {
430 mu_stream_t *pstr = ptr;
431 switch (opcode)
432 {
433 case MU_IOCTL_OP_GET:
434 pstr[0] = fs->transport;
435 mu_stream_ref (pstr[0]);
436 pstr[1] = NULL;
437 break;
438
439 case MU_IOCTL_OP_SET:
440 mu_stream_unref (fs->transport);
441 fs->transport = pstr[0];
442 mu_stream_ref (fs->transport);
443 break;
444
445 default:
446 return EINVAL;
447 }
448 }
449 break;
450
425 case MU_IOCTL_TRANSPORT: 451 case MU_IOCTL_TRANSPORT:
426 switch (opcode) 452 switch (opcode)
427 { 453 {
......
...@@ -309,6 +309,32 @@ _log_ctl (struct _mu_stream *str, int code, int opcode, void *arg) ...@@ -309,6 +309,32 @@ _log_ctl (struct _mu_stream *str, int code, int opcode, void *arg)
309 } 309 }
310 break; 310 break;
311 311
312 case MU_IOCTL_SUBSTREAM:
313 if (!arg)
314 return EINVAL;
315 else
316 {
317 mu_stream_t *pstr = arg;
318 switch (opcode)
319 {
320 case MU_IOCTL_OP_GET:
321 pstr[0] = sp->transport;
322 mu_stream_ref (pstr[0]);
323 pstr[1] = NULL;
324 break;
325
326 case MU_IOCTL_OP_SET:
327 mu_stream_unref (sp->transport);
328 sp->transport = pstr[0];
329 mu_stream_ref (sp->transport);
330 break;
331
332 default:
333 return EINVAL;
334 }
335 }
336 break;
337
312 case MU_IOCTL_LOGSTREAM: 338 case MU_IOCTL_LOGSTREAM:
313 switch (opcode) 339 switch (opcode)
314 { 340 {
......
...@@ -171,6 +171,8 @@ static struct mu_cfg_param mu_logging_param[] = { ...@@ -171,6 +171,8 @@ static struct mu_cfg_param mu_logging_param[] = {
171 N_("Set syslog facility. Arg is one of the following: user, daemon, " 171 N_("Set syslog facility. Arg is one of the following: user, daemon, "
172 "auth, authpriv, mail, cron, local0 through local7 (case-insensitive), " 172 "auth, authpriv, mail, cron, local0 through local7 (case-insensitive), "
173 "or a facility number.") }, 173 "or a facility number.") },
174 { "session-id", mu_cfg_bool, &mu_log_session_id, 0, NULL,
175 N_("Log session ID") },
174 { "tag", mu_cfg_string, &mu_log_tag, 0, NULL, 176 { "tag", mu_cfg_string, &mu_log_tag, 0, NULL,
175 N_("Tag syslog messages with this string.") }, 177 N_("Tag syslog messages with this string.") },
176 { NULL } 178 { NULL }
......
...@@ -185,6 +185,7 @@ pop3d_setio (int ifd, int ofd, int tls) ...@@ -185,6 +185,7 @@ pop3d_setio (int ifd, int ofd, int tls)
185 else 185 else
186 { 186 {
187 rc = mu_xscript_stream_create (&xstr, iostream, dstr, NULL); 187 rc = mu_xscript_stream_create (&xstr, iostream, dstr, NULL);
188 mu_stream_unref (dstr);
188 if (rc) 189 if (rc)
189 mu_error (_("cannot create transcript stream: %s"), 190 mu_error (_("cannot create transcript stream: %s"),
190 mu_strerror (rc)); 191 mu_strerror (rc));
......
...@@ -366,17 +366,90 @@ pop3d_mainloop (int ifd, int ofd, int tls) ...@@ -366,17 +366,90 @@ pop3d_mainloop (int ifd, int ofd, int tls)
366 return status; 366 return status;
367 } 367 }
368 368
369 static int
370 set_strerr_flt ()
371 {
372 mu_stream_t flt, trans[2];
373 int rc;
374
375 rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_SUBSTREAM, MU_IOCTL_OP_GET, trans);
376 if (rc == 0)
377 {
378 char sessidstr[10];
379 char *argv[] = { "inline-comment", NULL, "-S", NULL };
380
381 snprintf (sessidstr, sizeof sessidstr, "%08lx:", mu_session_id);
382 argv[1] = sessidstr;
383 rc = mu_filter_create_args (&flt, trans[0], "inline-comment", 3,
384 (const char **)argv,
385 MU_FILTER_ENCODE, MU_STREAM_WRITE);
386 mu_stream_unref (trans[0]);
387 if (rc == 0)
388 {
389 mu_stream_set_buffer (flt, mu_buffer_line, 0);
390 trans[0] = flt;
391 trans[1] = NULL;
392 rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_SUBSTREAM,
393 MU_IOCTL_OP_SET, trans);
394 mu_stream_unref (trans[0]);
395 if (rc)
396 mu_error (_("%s failed: %s"), "MU_IOCTL_SET_STREAM",
397 mu_stream_strerror (mu_strerr, rc));
398 }
399 else
400 mu_error (_("cannot create log filter stream: %s"), mu_strerror (rc));
401 }
402 else
403 {
404 mu_error (_("%s failed: %s"), "MU_IOCTL_GET_STREAM",
405 mu_stream_strerror (mu_strerr, rc));
406 }
407 return rc;
408 }
409
410 static void
411 clr_strerr_flt ()
412 {
413 mu_stream_t flt, trans[2];
414 int rc;
415
416 rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_SUBSTREAM, MU_IOCTL_OP_GET, trans);
417 if (rc == 0)
418 {
419 flt = trans[0];
420
421 rc = mu_stream_ioctl (flt, MU_IOCTL_SUBSTREAM, MU_IOCTL_OP_GET, trans);
422 if (rc == 0)
423 {
424 mu_stream_unref (trans[0]);
425 rc = mu_stream_ioctl (mu_strerr, MU_IOCTL_SUBSTREAM,
426 MU_IOCTL_OP_SET, trans);
427 if (rc == 0)
428 mu_stream_unref (flt);
429 }
430 }
431 }
432
369 int 433 int
370 pop3d_connection (int fd, struct sockaddr *sa, int salen, 434 pop3d_connection (int fd, struct sockaddr *sa, int salen,
371 struct mu_srv_config *pconf, 435 struct mu_srv_config *pconf,
372 void *data) 436 void *data)
373 { 437 {
374 struct pop3d_srv_config *cfg = (struct pop3d_srv_config *) pconf; 438 struct pop3d_srv_config *cfg = (struct pop3d_srv_config *) pconf;
439 int rc;
375 440
376 idle_timeout = pconf->timeout; 441 idle_timeout = pconf->timeout;
377 pop3d_transcript = pconf->transcript; 442 pop3d_transcript = pconf->transcript;
378 443
444 if (mu_log_session_id)
445 rc = set_strerr_flt ();
446 else
447 rc = 1;
448
379 pop3d_mainloop (fd, fd, cfg->tls); 449 pop3d_mainloop (fd, fd, cfg->tls);
450
451 if (rc == 0)
452 clr_strerr_flt ();
380 return 0; 453 return 0;
381 } 454 }
382 455
......