ze-filter  (ze-filter-0.8.0-develop-180218)
ze-dbrcpt.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 : Tue Jan 24 21:29:12 CET 2006
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 #include <ze-filter.h>
28 #include <ze-dbrcpt.h>
29 
30 /* ****************************************************************************
31  * *
32  * *
33  **************************************************************************** */
34 #define DREF 32
35 
36 
37 static ZEDB_T hdb = ZEDB_INITIALIZER;
38 static bool rdonly = TRUE;
39 
40 #define DBG_LEVEL 12
41 
42 /* ****************************************************************************
43  * *
44  * *
45  **************************************************************************** */
46 bool
48  bool rd;
49 {
50  bool res = TRUE;
51 
52  char *dbname;
53  char dbpath[1024];
54  char *cfdir = NULL;
55 
56  memset(dbpath, 0, sizeof (dbpath));
57 
58  cfdir = cf_get_str(CF_CDBDIR);
59  if (cfdir == NULL || strlen(cfdir) == 0)
60  cfdir = ZE_CDBDIR;
61 
62  dbname = cf_get_str(CF_DB_RCPT);
63  ADJUST_FILENAME(dbpath, dbname, cfdir, "ze-rcpt.db");
64 
65  ZE_MessageInfo(15, "Opening Rcpt Database : %s", dbpath);
66  if (zeDb_OK(&hdb))
67  return TRUE;
68  zeDb_Lock(&hdb);
69  rdonly = rd;
70  if (!zeDb_OK(&hdb))
71  res =
72  zeDb_Open(&hdb, NULL, dbpath, (rdonly ? 0444 : 0644), rdonly, TRUE, 0);
73  zeDb_Unlock(&hdb);
74  return res;
75 }
76 
77 /* ****************************************************************************
78  * *
79  * *
80  **************************************************************************** */
81 bool
83 {
84  bool res = TRUE;
85  char path[1024];
86 
87  zeDb_Lock(&hdb);
88  if (zeDb_OK(&hdb))
89  res = zeDb_Close(&hdb);
90  snprintf(path, sizeof (path), "%s/%s", cf_get_str(CF_CDBDIR), "ze-rcpt.db");
91  res = zeDb_Open(&hdb, NULL, path, (rdonly ? 0444 : 0644), rdonly, TRUE, 0);
92  zeDb_Unlock(&hdb);
93  return res;
94 }
95 
96 /* ****************************************************************************
97  * *
98  * *
99  **************************************************************************** */
100 bool
102 {
103  bool res = TRUE;
104 
105  if (!zeDb_OK(&hdb))
106  return res;
107  zeDb_Lock(&hdb);
108  if (zeDb_OK(&hdb))
109  res = zeDb_Close(&hdb);
110  zeDb_Unlock(&hdb);
111  return res;
112 }
113 
114 /* ****************************************************************************
115  * *
116  * *
117  **************************************************************************** */
118 #define MAX_ERR 8
119 
120 /* ****************************************************************************
121  * *
122  * *
123  **************************************************************************** */
124 
125 /*
126 ** Checks order
127 **
128 ** 1. Full check of key
129 ** 2. If key is an IP address,
130 ** Check IP and IP nets
131 ** 3. If key is a domain name
132 ** Check domain and sous domains
133 ** 4. If key is an email address
134 ** check rcpt part
135 **
136 */
137 
138 bool
139 db_rcpt_check_email(prefix, key, bufout, size)
140  char *prefix;
141  char *key;
142  char *bufout;
143  size_t size;
144 {
145  char k[256];
146  char v[1024];
147  bool found = FALSE;
148  char *p = NULL;
149  char *domain = NULL;
150  static int nerr = 0;
151  bool is_email = FALSE;
152  char *email = NULL;
153 
154  if (!zeDb_OK(&hdb) && !db_rcpt_open(TRUE)) {
155  if (nerr++ < MAX_ERR)
156  ZE_LogMsgError(0, "Can't open rcpt database");
157  return FALSE;
158  }
159 
160  if (key == NULL)
161  return FALSE;
162  if (strlen(key) == 0)
163  key = "default";
164  nerr = 0;
165  zeDb_Lock(&hdb);
166  /*
167  * let's get the domain part and check if this is an email
168  * ** address
169  */
170  if ((domain = strchr(key, '@')) != NULL) {
171  is_email = TRUE;
172  if ((email = strdup(key)) != NULL)
173  (void) extract_email_address(email, key, strlen(key) + 1);
174  else
175  ZE_LogSysError("strdup(%s) error", key);
176  domain++;
177  } else
178  domain = key;
179 
180  /*
181  * if this is an email address, let's first check
182  * ** the entire key
183  */
184  if (is_email && email != NULL && strlen(email) > 0) {
185  /*
186  * First of all, let's check the entire key
187  */
188  snprintf(k, sizeof (k), "%s:%s", prefix, email);
189  (void) zeStr2Lower(k);
190  ZE_MessageInfo(DBG_LEVEL, "KEY FULL : Looking for %s ...", k);
191  if (zeDb_GetRec(&hdb, k, v, sizeof (v))) {
192  if ((bufout != NULL) && (size > 0))
193  strlcpy(bufout, v, size);
194  ZE_MessageInfo(DBG_LEVEL, " : Found %s %s...", k, v);
195  found = TRUE;
196  goto fin;
197  }
198  }
199 
200  /*
201  * if this is only the domain part
202  */
203  if (!is_email && strlen(domain) > 0) {
204  /*
205  * First of all, let's check the entire key
206  */
207  snprintf(k, sizeof (k), "%s:%s", prefix, domain);
208  (void) zeStr2Lower(k);
209  ZE_MessageInfo(DBG_LEVEL, "KEY FULL : Looking for %s ...", k);
210  if (zeDb_GetRec(&hdb, k, v, sizeof (v))) {
211  if ((bufout != NULL) && (size > 0))
212  strlcpy(bufout, v, size);
213  ZE_MessageInfo(DBG_LEVEL, " : Found %s %s...", k, v);
214  found = TRUE;
215  goto fin;
216  }
217  }
218 #if 0
219  /*
220  ** Entire key doesn't match - lets check domain part
221  **
222  ** Do I really need this ?????
223  ** Now done at ze-rcpt.c
224  */
225  if (FALSE && !found) {
226  /*
227  * This is a domain name
228  */
229  /*
230  * Try each part beginning from the most complete one
231  */
232  p = domain;
233  while (p != NULL && strlen(p) > 0) {
234  snprintf(k, sizeof (k), "%s:%s", prefix, p);
235  (void) zeStr2Lower(k);
236  ZE_MessageInfo(DBG_LEVEL, "NAME : Looking for %s", k);
237  if (zeDb_GetRec(&hdb, k, v, sizeof (v))) {
238  if ((bufout != NULL) && (size > 0))
239  strlcpy(bufout, v, size);
240  ZE_MessageInfo(DBG_LEVEL, " : Found %s %s...", k, v);
241  found = TRUE;
242  break;
243  }
244  p = strchr(p, '.');
245  if (p != NULL)
246  p++;
247 #if 1
248  /*
249  * don't check upper levels
250  */
251  break;
252 #endif
253  }
254 
255  /*
256  * Is this really needed ???
257  */
258  if (found) {
259 
260  }
261 
262  if (found)
263  goto fin;
264  }
265 #if 0
266  /*
267  * Entire key doesn't match - lets check rcpt part
268  */
269  if (!found && is_email && email != NULL) {
270  snprintf(k, sizeof (k), "%s:%s", prefix, email);
271  (void) zeStr2Lower(k);
272  domain = strchr(k, '@');
273  if (domain != NULL)
274  *(++domain) = '\0';
275  ZE_MessageInfo(DBG_LEVEL, "k = %s", k);
276  if (zeDb_GetRec(&hdb, k, v, sizeof (v))) {
277  if ((bufout != NULL) && (size > 0))
278  strlcpy(bufout, v, size);
279  found = TRUE;
280  goto fin;
281  }
282  }
283 #endif
284 
285 #endif
286 
287 fin:
288  FREE(email);
289  zeDb_Unlock(&hdb);
290  return found;
291 }
292 
293 /* ****************************************************************************
294  * *
295  * *
296  **************************************************************************** */
297 bool
298 db_rcpt_check_domain(prefix, key, bufout, size, flags)
299  char *prefix;
300  char *key;
301  char *bufout;
302  size_t size;
303  uint32_t flags;
304 {
305  char k[256];
306  char v[1024];
307  bool found = FALSE;
308  char *p = NULL;
309  char *domain = NULL;
310  static int nerr = 0;
311  int level = 0;
312 
313  if (!zeDb_OK(&hdb) && !db_rcpt_open(TRUE)) {
314  if (nerr++ < MAX_ERR)
315  ZE_LogMsgError(0, "Can't open rcpt database");
316  return FALSE;
317  }
318 
319  if (key == NULL)
320  return FALSE;
321  if (strlen(key) == 0)
322  key = "default";
323  nerr = 0;
324  zeDb_Lock(&hdb);
325  /*
326  * let's get the domain part and check if this is an email
327  * ** address
328  */
329  if ((domain = strchr(key, '@')) != NULL)
330  domain++;
331  else
332  domain = key;
333  if (domain == NULL || strlen(domain) == 0)
334  domain = "default";
335  p = domain;
336  level = 0;
337  if (p != NULL && strlen(p) > 0) {
338  snprintf(k, sizeof (k), "%s:%s", prefix, p);
339  (void) zeStr2Lower(k);
340  ZE_MessageInfo(DBG_LEVEL, "NAME : Looking for %s", k);
341  if (zeDb_GetRec(&hdb, k, v, sizeof (v))) {
342  ZE_MessageInfo(DBG_LEVEL, " : Found %s %s...", k, v);
343  if ((bufout != NULL) && (size > 0))
344  strlcpy(bufout, v, size);
345  found = TRUE;
346  }
347  }
348 
349  if (!found) {
350  p = domain;
351  level = 0;
352  while (p != NULL && strlen(p) > 0) {
353  snprintf(k, sizeof (k), "%s:*.%s", prefix, p);
354  (void) zeStr2Lower(k);
355  ZE_MessageInfo(DBG_LEVEL, "NAME : Looking for %s", k);
356  if (zeDb_GetRec(&hdb, k, v, sizeof (v))) {
357  ZE_MessageInfo(DBG_LEVEL, " : Found %s %s...", k, v);
358  if ((bufout != NULL) && (size > 0))
359  strlcpy(bufout, v, size);
360  found = TRUE;
361  break;
362  }
363  p = strchr(p, '.');
364  if (p != NULL)
365  p++;
366  }
367  }
368 
369  /*
370  * not found - let's check if a default value is defined
371  */
372  if (!found) {
373  snprintf(k, sizeof (k), "%s:%s", prefix, "default");
374  (void) zeStr2Lower(k);
375  ZE_MessageInfo(DBG_LEVEL, "NAME : Looking for %s", k);
376  if (zeDb_GetRec(&hdb, k, v, sizeof (v))) {
377  ZE_MessageInfo(DBG_LEVEL, " : Found %s %s...", k, v);
378  if ((bufout != NULL) && (size > 0))
379  strlcpy(bufout, v, size);
380  found = TRUE;
381  }
382  }
383 
384 fin:
385  zeDb_Unlock(&hdb);
386  return found;
387 }
bool zeDb_Unlock(ZEDB_T *h)
Database unlock.
Definition: zeDb.c:907
#define CF_CDBDIR
Definition: cfh-defs.h:78
bool zeDb_OK(ZEDB_T *h)
Definition: zeDb.c:649
#define FREE(x)
Definition: macros.h:37
#define ZE_CDBDIR
Definition: defs.h:34
Definition: zeDb.h:47
#define FALSE
Definition: macros.h:160
#define strlcpy
Definition: zeString.h:32
#define ZE_LogMsgError(level,...)
Definition: zeSyslog.h:113
#define CF_DB_RCPT
Definition: cfh-defs.h:152
#define ADJUST_FILENAME(path, fname, cfdir, defval)
Definition: macros.h:236
char * extract_email_address(char *, char *, size_t)
bool db_rcpt_close()
Definition: ze-dbrcpt.c:101
#define strchr
Definition: ze-sys.h:218
bool zeDb_Open(ZEDB_T *h, ZEDB_ENV_T *, char *, int, bool, bool, size_t)
Definition: zeDb.c:462
bool zeDb_Close(ZEDB_T *h)
Definition: zeDb.c:667
#define DBG_LEVEL
Definition: ze-dbrcpt.c:40
#define MAX_ERR
Definition: ze-dbrcpt.c:118
#define ZE_MessageInfo(level,...)
Definition: zeSyslog.h:90
bool zeDb_GetRec(ZEDB_T *h, char *, void *, size_t)
Definition: zeDb.c:791
#define TRUE
Definition: macros.h:157
bool db_rcpt_check_domain(char *prefix, char *key, char *bufout, size_t size, uint32_t flags)
Definition: ze-dbrcpt.c:298
#define ZE_LogSysError(...)
Definition: zeSyslog.h:129
char * cf_get_str(int id)
Definition: ze-cf.c:854
bool db_rcpt_open(bool rd)
Definition: ze-dbrcpt.c:47
char * zeStr2Lower(char *)
Definition: zeStrings.c:295
bool db_rcpt_check_email(char *prefix, char *key, char *bufout, size_t size)
Definition: ze-dbrcpt.c:139
bool db_rcpt_reopen()
Definition: ze-dbrcpt.c:82
#define ZEDB_INITIALIZER
Definition: zeDb.h:111
long uint32_t
Definition: ze-sys.h:489
char domain[]
bool zeDb_Lock(ZEDB_T *h)
Database lock.
Definition: zeDb.c:896