ze-filter  (ze-filter-0.8.0-develop-180218)
ze-spool.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 
26 #include <ze-sys.h>
27 
28 #include "ze-filter.h"
29 #include "ze-filter-data.h"
30 #include "ze-spool.h"
31 
32 #define SWAP_PTR(a,b) do { void *c = a; a = b; b = c;} while (0)
33 
34 /* ****************************************************************************
35  * *
36  * *
37  ******************************************************************************/
38 
40 bool spool_file_write(CTXPRIV_T *, char *, size_t);
43 
44 
45 /* ****************************************************************************
46  * *
47  * *
48  ******************************************************************************/
49 bool
51  CTXPRIV_T *priv;
52 {
53  char *p;
54  char fname[256];
55 
56  int fd;
57 
58  char *rc = CRLF;
59 
60 #if _FFR_CLEAN_MSG_BUF
61  rc = "\n";
62 #endif
63 
64  if (priv->fd >= 0)
65  return TRUE;
66 
67  priv->fp_open = FALSE;
68 
69  if (priv->fname != NULL)
70  ZE_LogMsgWarning(0, "fd closed, but fname not NULL");
71  FREE(priv->fname);
72 
73  if ((p = cf_get_str(CF_SPOOLDIR)) == NULL)
74  p = ZE_SPOOLDIR;
75 
76  if (cf_get_int(CF_CLUSTER) == OPT_YES) {
77  char *server = NULL;
78 
79  server = STRNULL(priv->mailserver, "SERVER");
80 
81  snprintf(fname, sizeof (fname), "%s/%s.%s.%04X", p, server,
82  CONNID_STR(priv->id), priv->nb_msgs);
83 
84  } else {
85  snprintf(fname, sizeof (fname), "%s/%s.%04X", p, CONNID_STR(priv->id),
86  priv->nb_msgs);
87  }
88 
89  fd = open(fname, O_WRONLY | O_APPEND | O_CREAT, 0640);
90 
91  if (fd < 0) {
92  ZE_LogSysError("can't create spool file (%s)", fname);
93  fd = -1;
94  return FALSE;
95  }
96 
97  if (fchmod(fd, S_IRUSR | S_IWUSR) != 0)
98  ZE_LogSysError("can't change spool file rights (%s)", fname);
99 
100  priv->fd = fd;
101  priv->fp_open = TRUE;
102 
103  if ((priv->fname = strdup(fname)) == NULL)
104  ZE_LogSysError("strdup(%s) error", fname);
105 
106  /*
107  * Let's add a fake From line
108  */
110  char s[256];
111  char t[256];
112  time_t tid = CONNID_INT(priv->id);
113 
114 #if HAVE_CTIME_R
115 #ifdef _POSIX_PTHREAD_SEMANTICS
116  ctime_r(&tid, t);
117 #else
118  ctime_r(&tid, t, sizeof (t));
119 #endif
120 #else
121 #if HAVE_CTIME
122  strlcpy(t, ctime(&tid, sizeof (t));
123 #else
124  strlcpy(t, "-", sizeof (t));
125 #endif
126 #endif
127 
128  if ((p = strchr(t, '\r')) != NULL)
129  *p = '\0';
130  if ((p = strchr(t, '\n')) != NULL)
131  *p = '\0';
132 
133  if (priv->env_from != NULL)
134  snprintf(s, sizeof (s) - 3, "From %s %s", priv->env_from, t);
135  else
136  snprintf(s, sizeof (s) - 3, "From %s %s", "<unknown>", t);
137  strcat(s, rc);
138 
139  if (write(priv->fd, s, strlen(s)) != strlen(s))
140  ZE_LogSysError("can't write fake From: line to %s", priv->fname);
141  }
142 
143  if (1) {
144  char rbuf[512];
145  char *mac_srv_name = NULL;
146  char *mac_cl_addr = NULL;
147  char *mac_cl_ptr = NULL;
148  char *mac_cl_name = NULL;
149  char *mac_qid = NULL;
150 
151  mac_srv_name = sm_macro_get_str(priv->sm, "j");
152  mac_srv_name = STREMPTY(mac_srv_name, my_hostname);
153  mac_cl_addr = sm_macro_get_str(priv->sm, "{client_addr}");
154  mac_cl_addr = STREMPTY(mac_cl_addr, "null");
155  mac_cl_ptr = sm_macro_get_str(priv->sm, "{client_ptr}");
156  mac_cl_ptr = STREMPTY(mac_cl_ptr, "null");
157  mac_cl_name = sm_macro_get_str(priv->sm, "{client_name}");
158  mac_cl_name = STREMPTY(mac_cl_name, "null");
159  mac_qid = sm_macro_get_str(priv->sm, "i");
160  mac_qid = STREMPTY(mac_qid, "null");
161 
162 /*
163 Received: from qxxge.proxad.net (sge78-3-82-247-96-164.fbx.proxad.net [82.247.96.164])
164  by paris.ensmp.fr (8.14.4/8.14.4/JMMC-31/May/2010) with SMTP id o73Ed8Cs001045
165  for <dns@ensmp.fr>; Tue, 3 Aug 2010 16:39:09 +0200 (MEST)
166 */
167  snprintf(rbuf, sizeof (rbuf),
168  "Received: from %s (%s [%s])%s\tby %s with SMTP id %s%s",
169  mac_cl_ptr,
170  mac_cl_name, mac_cl_addr, rc, mac_srv_name, mac_qid, rc);
171 
172  if (write(priv->fd, rbuf, strlen(rbuf)) != strlen(rbuf))
173  ZE_LogSysError("can't write fake Received: line to %s", priv->fname);
174 
175  snprintf(rbuf, sizeof (rbuf),
176  "X-ze-filter-Envelope: %s from %s/%s/%s/%s/%s%s",
177  CONNID_STR(priv->id),
178  mac_cl_name, mac_cl_ptr, mac_cl_addr,
179  priv->helohost, priv->env_from, rc);
180  /*
181  * snprintf(rbuf, sizeof(rbuf),
182  * "X-Received: from %s (%s [%s])%s",
183  * mac_cl_ptr,
184  * mac_cl_name,
185  * mac_cl_addr,
186  * rc);
187  */
188  if (write(priv->fd, rbuf, strlen(rbuf)) != strlen(rbuf))
189  ZE_LogSysError("can't write fake X-ze-filter-Envelope: line to %s",
190  priv->fname);
191  }
192 
193  return TRUE;
194 }
195 
196 /* ****************************************************************************
197  * *
198  * *
199  ******************************************************************************/
200 bool
201 spool_file_write(priv, buf, size)
202  CTXPRIV_T *priv;
203  char *buf;
204  size_t size;
205 {
206  if (priv->fd < 0)
207  return TRUE;
208 
209  if (write(priv->fd, buf, size) != size) {
210  ZE_LogSysError("Error writing on spool file %s", priv->fname);
211  return FALSE;
212  }
213 
214  return TRUE;
215 }
216 
217 /* ****************************************************************************
218  * *
219  * *
220  ******************************************************************************/
221 bool
223  CTXPRIV_T *priv;
224 {
225  if (priv->fd < 0)
226  return TRUE;
227 
228  priv->fp_open = FALSE;
229  if (close(priv->fd) < 0) {
230  ZE_LogSysError("error closing spool file");
231  priv->fd = -1;
232  return FALSE;
233  }
234  priv->fd = -1;
235 
236  return TRUE;
237 }
238 
239 
240 /* ****************************************************************************
241  * *
242  * *
243  ******************************************************************************/
244 bool
246  CTXPRIV_T *priv;
247 {
248  char *filename = NULL;
249  char *suffix = NULL;
250  size_t sz = 0;
251 
252  (void) spool_file_close(priv);
253 
254  if (priv->fname == NULL)
255  goto fin;
256 
257  if (!priv->save_msg) {
258  unlink(priv->fname);
259  goto fin;
260  }
261 
262  suffix = STREMPTY(priv->fsuffix, SUFFIX_UNKNOWN);
263  sz = strlen(priv->fname) + strlen(suffix) + 4;
264 
265  filename = (char *) malloc(sz);
266  if (filename != NULL) {
267  snprintf(filename, sz, "%s%s", priv->fname, suffix);
268  if (rename(priv->fname, filename) == 0)
269  SWAP_PTR(filename, priv->fname);
270  else
271  ZE_LogSysError("Error renaming quarantine file : %s", priv->fname);
272  } else
273  ZE_LogSysError("Quarantine file name malloc error : %s", priv->fname);
274  ZE_MessageInfo(11, "%-12s : quarantine file %s", CONNID_STR(priv->id),
275  priv->fname);
276 
277 fin:
278  priv->fsuffix = NULL;
279  priv->save_msg = FALSE;
280  FREE(priv->fname);
281  FREE(filename);
282 
283  return TRUE;
284 }
285 
286 /* ****************************************************************************
287  * *
288  * *
289  ******************************************************************************/
290 bool
292  CTXPRIV_T *priv;
293 {
294  if (priv == NULL)
295  return FALSE;
296 
297  return priv->fp_open;
298 }
#define CF_SPOOLDIR
Definition: cfh-defs.h:68
char * fname
bool spool_file_write(CTXPRIV_T *, char *, size_t)
Definition: ze-spool.c:201
bool spool_file_forget(CTXPRIV_T *)
Definition: ze-spool.c:245
#define CONNID_INT(connid)
Definition: ze-filter.h:114
#define CRLF
Definition: macros.h:224
#define FREE(x)
Definition: macros.h:37
bool spool_file_is_open(CTXPRIV_T *priv)
Definition: ze-spool.c:291
#define STRNULL(x, r)
Definition: macros.h:81
#define FALSE
Definition: macros.h:160
#define strlcpy
Definition: zeString.h:32
#define OPT_YES
Definition: ze-cf.h:45
#define SWAP_PTR(a, b)
Definition: ze-spool.c:32
int cf_get_int(int id)
Definition: ze-cf.c:803
#define strchr
Definition: ze-sys.h:218
char my_hostname[]
Definition: ze-filter.c:89
CONNID_T id
char * mailserver
bool spool_file_close(CTXPRIV_T *)
Definition: ze-spool.c:222
char * fsuffix
#define CF_QUARANTINE_ADD_FROM_LINE
Definition: cfh-defs.h:73
#define ZE_MessageInfo(level,...)
Definition: zeSyslog.h:90
#define TRUE
Definition: macros.h:157
#define CF_CLUSTER
Definition: cfh-defs.h:58
#define ZE_LogSysError(...)
Definition: zeSyslog.h:129
char * cf_get_str(int id)
Definition: ze-cf.c:854
#define STREMPTY(x, r)
Definition: macros.h:82
#define ZE_LogMsgWarning(level,...)
Definition: zeSyslog.h:112
char * env_from
char * helohost
sm_mac_T * sm
#define CONNID_STR(connid)
Definition: ze-filter.h:113
#define ZE_SPOOLDIR
Definition: defs.h:30
char * sm_macro_get_str(sm_mac_T *, char *)
Definition: ze-smmacros.c:191
#define SUFFIX_UNKNOWN
Definition: ze-spool.h:36
bool spool_file_create(CTXPRIV_T *)
Definition: ze-spool.c:50