Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 113509 | Differences between
and this patch

Collapse All | Expand All

(-)qmail-1.03/chkuser.c (+1156 lines)
Line 0 Link Here
1
2
/*
3
 *
4
 * 'chkuser.c' v.2.0.8
5
 * for qmail/netqmail > 1.0.3 and vpopmail > 5.3.x
6
 *
7
 * Author: Antonio Nati tonix@interazioni.it
8
 * All rights on this software and
9
 * the identifying words chkusr and chkuser kept by the author
10
 *
11
 * This software may be freely used, modified and distributed,
12
 * but this lines must be kept in every original or derived version.
13
 * Original author "Antonio Nati" and the web URL
14
 * "http://www.interazioni.it/opensource"
15
 * must be indicated in every related work or web page
16
 *
17
 */
18
19
#include <pwd.h>
20
21
/* required by vpopmail */
22
#include <stdio.h>
23
24
#include <stdlib.h>
25
#include <string.h>
26
#include <unistd.h>
27
28
#include "dns.h"
29
#include "env.h"
30
#include "ipme.h"
31
#include "now.h"
32
#include "open.h"
33
#include "subfd.h"
34
#include "substdio.h"
35
#include "stralloc.h"
36
37
#include "vpopmail.h"
38
#include "vauth.h"
39
#include "vpopmail_config.h"
40
41
#include "chkuser.h"
42
#include "chkuser_settings.h"
43
44
#if defined _exit
45
#undef _exit
46
#endif
47
48
extern void flush();
49
extern void out (char *s);
50
51
extern char *remotehost;
52
extern char *remoteip;
53
extern char *remoteinfo;
54
extern char *relayclient;
55
extern char *fakehelo;
56
57
extern void die_nomem();
58
59
#define DIE_NOMEM() die_nomem()
60
61
#if defined CHKUSER_DEBUG
62
63
#if defined CHKUSER_DEBUG_STDERR
64
65
#define CHKUSER_DBG(a) write (STDERR_FILENO, a, strlen (a))
66
#define CHKUSER_DBG_INT(a) { int x; char str[30]; sprintf (str, "%d", a); write (STDERR_FILENO, str, strlen (str));}
67
68
#else
69
70
#define CHKUSER_DBG(a) write (STDOUT_FILENO, a, strlen (a))
71
#define CHKUSER_DBG_INT(a) { int x; char str[30]; sprintf (str, "%d", a); write (STDOUT_FILENO, str, strlen (str));}
72
73
#endif
74
#else
75
76
#define CHKUSER_DBG(a) /* DBG dummy */
77
#define CHKUSER_DBG_INT(a) /* DBG dummy */
78
79
#endif
80
81
static int INTRUSION_threshold_reached = 0;
82
static int first_time_init_flag = 1;
83
84
static int recipients = 0;
85
static int wrong_recipients = 0;
86
87
static stralloc user = {0};
88
static stralloc domain = {0};
89
static stralloc domain_path = {0};
90
static stralloc tmp_path = {0};
91
static stralloc alias_path = {0};
92
93
#if defined CHKUSER_IDENTIFY_REMOTE_VARIABLE
94
 static char *identify_remote;
95
#endif
96
97
#if defined CHKUSER_ENABLE_EXTENSIONS
98
#define CHKUSER_ENABLE_USERS_EXTENSIONS
99
#endif
100
101
#if defined CHKUSER_ENABLE_LISTS
102
#define CHKUSER_ENABLE_EZMLM_LISTS
103
#endif
104
105
#if defined CHKUSER_EXTENSION_DASH
106
#define CHKUSER_USERS_DASH CHKUSER_EXTENSION_DASH
107
#endif
108
109
110
#if defined CHKUSER_ENABLE_VAUTH_OPEN
111
 static int db_already_open = 0;
112
#endif
113
114
#if !defined CHKUSER_ALWAYS_ON && defined CHKUSER_STARTING_VARIABLE
115
  static char *starting_string = 0;
116
  static int starting_value = -1;
117
#endif
118
119
#if defined CHKUSER_RCPT_LIMIT_VARIABLE
120
  static char *maxrcpt_string = 0;
121
  static int maxrcpt_limit = 0;
122
  static int maxrcpt_limit_reached = 0;
123
#endif
124
125
#if defined CHKUSER_WRONGRCPT_LIMIT_VARIABLE
126
  static char *maxwrongrcpt_string = 0;
127
  static int maxwrongrcpt_limit = 0;
128
  static int maxwrongrcpt_limit_reached = 0;
129
#endif
130
131
#if defined CHKUSER_MBXQUOTA_VARIABLE
132
  static char *maxmbxquota_string = 0;
133
  static int maxmbxquota_limit = 0;
134
#endif
135
136
#if defined CHKUSER_SENDER_NOCHECK_VARIABLE
137
138
  static unsigned int sender_nocheck = 0;
139
140
#endif
141
142
#if defined CHKUSER_SENDER_FORMAT || defined CHKUSER_SENDER_MX
143
static stralloc sender_user = {0};
144
static stralloc sender_domain = {0};
145
#endif
146
147
148
#if defined CHKUSER_ERROR_DELAY
149
150
  static int chkuser_delay_interval = CHKUSER_ERROR_DELAY * 1000;
151
152
#define CHKUSER_DELAY()	chkuser_delay()
153
154
void chkuser_delay (void) {
155
156
        usleep (chkuser_delay_interval);
157
158
#if defined CHKUSER_ERROR_DELAY_INCREASE
159
        chkuser_delay_interval += CHKUSER_ERROR_DELAY_INCREASE * 1000;
160
#endif
161
}
162
163
#if defined CHKUSER_RCPT_DELAY_ANYERROR
164
#define CHKUSER_RCPT_DELAY_ANY() chkuser_delay()
165
#else
166
#define CHKUSER_RCPT_DELAY_ANY() /* no delay for any error */
167
#endif
168
169
#if defined CHKUSER_SENDER_DELAY_ANYERROR
170
#define CHKUSER_SENDER_DELAY_ANY() chkuser_delay()
171
#else
172
#define CHKUSER_SENDER_DELAY_ANY() /* no delay for any error */
173
#endif
174
175
176
#else
177
#define CHKUSER_DELAY() /* no delay */
178
#define CHKUSER_RCPT_DELAY_ANY() /* no delay */
179
#define CHKUSER_SENDER_DELAY_ANY() /* no delay */
180
#endif
181
182
#if defined CHKUSER_ENABLE_LOGGING
183
184
static stralloc logstr = { 0 };
185
186
static void chkuser_commonlog (char *sender, char *rcpt, char *title, char *description) {
187
188
  substdio_puts (subfderr, "CHKUSER ");
189
  substdio_puts (subfderr, title);
190
  substdio_puts (subfderr, ": from <");
191
  substdio_puts (subfderr, sender);
192
  substdio_puts (subfderr, ":" );
193
  if (remoteinfo) {
194
	substdio_puts (subfderr, remoteinfo);
195
  }
196
  substdio_puts (subfderr, ":" );
197
#if defined CHKUSER_IDENTIFY_REMOTE_VARIABLE
198
  if (identify_remote) substdio_puts (subfderr, identify_remote);
199
#endif
200
  substdio_puts (subfderr, "> remote <");
201
  if (fakehelo) substdio_puts (subfderr, fakehelo);
202
  substdio_puts (subfderr, ":" );
203
  if (remotehost) substdio_puts (subfderr, remotehost);
204
  substdio_puts (subfderr, ":" );
205
  if (remoteip) substdio_puts (subfderr, remoteip);
206
  substdio_puts (subfderr, "> rcpt <");
207
  substdio_puts (subfderr, rcpt);
208
  substdio_puts (subfderr, "> : ");
209
  substdio_puts (subfderr, description);
210
  substdio_puts (subfderr, "\n");
211
  substdio_flush (subfderr);
212
}
213
214
#else
215
#define chkuser_commonlog(a,b,c,d) /* no log */
216
#endif
217
218
#if defined CHKUSER_SENDER_FORMAT
219
220
static int check_sender_address_format (stralloc *user, stralloc *domain) {
221
222
        int x;
223
224
        for (x = 0; x < (user->len -1); ++x) {
225
                if ((!isalnum (user->s[x])) 
226
227
#if defined CHKUSER_ALLOW_SENDER_SRS
228
		&& (user->s[x] != '#')
229
		&& (user->s[x] != '+')
230
#endif
231
#if defined CHKUSER_ALLOW_SENDER_CHAR_1
232
		&& (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_1)
233
#endif
234
#if defined CHKUSER_ALLOW_SENDER_CHAR_2
235
		&& (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_2)
236
#endif
237
#if defined CHKUSER_ALLOW_SENDER_CHAR_3
238
		&& (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_3)
239
#endif
240
#if defined CHKUSER_ALLOW_SENDER_CHAR_4
241
		&& (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_4)
242
#endif
243
#if defined CHKUSER_ALLOW_SENDER_CHAR_5
244
		&& (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_5)
245
#endif
246
		&& (user->s[x] != '_') && (user->s[x] != '-') && (user->s[x] != '.') && (user->s[x] != '=')) {
247
                        return 0;
248
                }
249
        }
250
251
/*
252
 * Be careful, this is a base check
253
 *      Minimum is x.xx + ending \0
254
 *      Minimum characters needed are 5
255
 */
256
#if defined CHKUSER_MIN_DOMAIN_LEN
257
        if (domain->len < (CHKUSER_MIN_DOMAIN_LEN +1)) {
258
                return 0;
259
        }
260
#endif
261
262
/*
263
 *      This is a safety check
264
 */
265
#if defined CHKUSER_MIN_DOMAIN_LEN
266
        if (domain->len < 2) {
267
                return 0;
268
        }
269
#endif
270
271
        for (x = 0; x < (domain->len -1); ++x) {
272
                if ((!isalnum (domain->s[x])) && (domain->s[x] != '-') && (domain->s[x] != '.')) {
273
                        return 0;
274
                }
275
        }
276
277
        if ((domain->s[0] == '-') || (domain->s[domain->len -2] == '-') || (domain->s[0] == '.') || (domain->s[domain->len -2] == '.')) {
278
                return 0;
279
        }
280
        if (strstr (domain->s, "..") != NULL) {
281
                return 0;
282
        }
283
	if (strncmp (domain->s, "xn--", 4) == 0) {
284
		if (strstr (&domain->s[4], "--") != NULL)
285
			return 0;
286
	} else {
287
		if (strstr (domain->s, "--") != NULL)
288
			return 0;
289
	}
290
        if (strstr (domain->s, ".-") != NULL) {
291
                return 0;
292
        }
293
        if (strstr (domain->s, "-.") != NULL) {
294
                return 0;
295
        }
296
        if (strchr (domain->s, '.') == NULL) {
297
                return 0;
298
        }
299
300
        return 1;
301
}
302
303
#endif
304
305
#if defined CHKUSER_RCPT_FORMAT
306
307
static int check_rcpt_address_format (stralloc *user, stralloc *domain) {
308
309
        int x;
310
311
        for (x = 0; x < (user->len -1); ++x) {
312
                if ((!isalnum (user->s[x])) 
313
#if defined CHKUSER_ALLOW_RCPT_SRS
314
                && (user->s[x] != '#')
315
                && (user->s[x] != '+')
316
#endif
317
#if defined CHKUSER_ALLOW_RCPT_CHAR_1
318
                && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_1)
319
#endif
320
#if defined CHKUSER_ALLOW_RCPT_CHAR_2
321
                && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_2)
322
#endif
323
#if defined CHKUSER_ALLOW_RCPT_CHAR_3
324
                && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_3)
325
#endif
326
#if defined CHKUSER_ALLOW_RCPT_CHAR_4
327
                && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_4)
328
#endif
329
#if defined CHKUSER_ALLOW_RCPT_CHAR_5
330
                && (user->s[x] != CHKUSER_ALLOW_SENDER_CHAR_5)
331
#endif
332
333
		&& (user->s[x] != '_') && (user->s[x] != '-') && (user->s[x] != '.') && (user->s[x] != '=')) {
334
                        return 0;
335
                }
336
        }
337
338
/*
339
 * Be careful, this is a base check
340
 *      Minimum is x.xx + ending \0
341
 *      Minimum characters needed are 5
342
 */
343
#if defined CHKUSER_MIN_DOMAIN_LEN
344
        if (domain->len < (CHKUSER_MIN_DOMAIN_LEN +1)) {
345
                return 0;
346
        }
347
#endif
348
349
/*
350
 *      This is a safety check
351
 */
352
#if defined CHKUSER_MIN_DOMAIN_LEN
353
        if (domain->len < 2) {
354
                return 0;
355
        }
356
#endif
357
        for (x = 0; x < (domain->len -1); ++x) {
358
                if ((!isalnum (domain->s[x])) && (domain->s[x] != '-') && (domain->s[x] != '.')) {
359
                        return 0;
360
                }
361
        }
362
363
        if ((domain->s[0] == '-') || (domain->s[domain->len -2] == '-') || (domain->s[0] == '.') || (domain->s[domain->len -2] == '.')) {
364
                return 0;
365
        }
366
        if (strstr (domain->s, "..") != NULL) {
367
                return 0;
368
        }
369
	if (strncmp (domain->s, "xn--", 4) == 0) {
370
		if (strstr (&domain->s[4], "--") != NULL)
371
			return 0;
372
	} else {
373
		if (strstr (domain->s, "--") != NULL)
374
			return 0;
375
	}
376
        if (strstr (domain->s, ".-") != NULL) {
377
                return 0;
378
        }
379
        if (strstr (domain->s, "-.") != NULL) {
380
                return 0;
381
        }
382
        if (strchr (domain->s, '.') == NULL) {
383
                return 0;
384
        }
385
386
        return 1;
387
}
388
389
#endif
390
391
#if defined CHKUSER_SENDER_MX || defined CHKUSER_RCPT_MX
392
393
static   unsigned long mx_random;
394
static  ipalloc mx_ip = {0};
395
396
static int chkuser_mx_lookup (stralloc *domain) {
397
398
  int status;
399
400
	mx_random = now() + getpid();
401
	dns_init(0);
402
	status = dns_mxip (&mx_ip, domain, mx_random);
403
404
	if (status == DNS_MEM) DIE_NOMEM();
405
406
	return status;
407
}
408
409
#endif
410
411
412
void chkuser_cleanup (int exit_value) {
413
414
#if defined CHKUSER_DB_CLEANUP
415
	vclose ();
416
#endif
417
	_exit (exit_value);
418
}
419
420
static void first_time_init (void) {
421
422
  char * temp_string;
423
424
#if !defined CHKUSER_ALWAYS_ON && defined CHKUSER_STARTING_VARIABLE
425
        starting_string = env_get (CHKUSER_STARTING_VARIABLE);
426
        if (starting_string) {
427
                if (strcasecmp(starting_string, "ALWAYS") == 0) {
428
                        starting_value = 1;
429
                } else if (strcasecmp(starting_string, "DOMAIN") == 0) {
430
                        starting_value = 0;
431
                }
432
        } else {
433
                starting_string = "";
434
        }
435
#endif
436
437
#if defined CHKUSER_RCPT_LIMIT_VARIABLE
438
        maxrcpt_string = env_get (CHKUSER_RCPT_LIMIT_VARIABLE);
439
        if (maxrcpt_string) {
440
                maxrcpt_limit = atoi (maxrcpt_string);
441
                if (maxrcpt_limit < 1) {
442
                        maxrcpt_limit = 0;
443
                }
444
        } else {
445
                maxrcpt_string = "";;
446
        }
447
#endif
448
449
#if defined CHKUSER_WRONGRCPT_LIMIT_VARIABLE
450
        maxwrongrcpt_string = env_get (CHKUSER_WRONGRCPT_LIMIT_VARIABLE);
451
        if (maxwrongrcpt_string) {
452
                maxwrongrcpt_limit = atoi (maxwrongrcpt_string);
453
                if (maxwrongrcpt_limit < 1) {
454
                        maxwrongrcpt_limit = 0;
455
                }
456
        } else {
457
                maxwrongrcpt_string = "";
458
        }
459
#endif
460
461
#if defined CHKUSER_MBXQUOTA_VARIABLE
462
        maxmbxquota_string = env_get (CHKUSER_MBXQUOTA_VARIABLE);
463
        if (maxmbxquota_string) {
464
                maxmbxquota_limit = atoi (maxmbxquota_string);
465
                if (maxmbxquota_limit < 1) {
466
                	maxmbxquota_limit = 0;
467
                }
468
	} else {
469
               	maxmbxquota_string = "";
470
	}
471
#endif
472
473
#if defined CHKUSER_SENDER_NOCHECK_VARIABLE
474
475
        temp_string = env_get (CHKUSER_SENDER_NOCHECK_VARIABLE);
476
        if (temp_string) {
477
		sender_nocheck = 1;
478
        } else {
479
		sender_nocheck = 0;
480
        }
481
482
#endif
483
484
#if defined CHKUSER_IDENTIFY_REMOTE_VARIABLE
485
486
        identify_remote = env_get (CHKUSER_IDENTIFY_REMOTE_VARIABLE);
487
        if (identify_remote) {
488
        }
489
490
#endif
491
492
        if (!stralloc_ready (&user, 300)) DIE_NOMEM();
493
        if (!stralloc_ready (&domain, 500)) DIE_NOMEM();
494
        if (!stralloc_ready (&domain_path, 1000)) DIE_NOMEM();
495
        if (!stralloc_ready (&tmp_path, 1000)) DIE_NOMEM();
496
        if (!stralloc_ready (&alias_path, 1000)) DIE_NOMEM();
497
498
	first_time_init_flag = 0;
499
500
}
501
502
/*
503
 * realrcpt ()
504
 *
505
 * Returns:
506
 *
507
 *	CHKUSER_OK = 1 = Ok, recipients does exists
508
 *
509
 *	0 = Not in rcpthosts
510
 *
511
 *	< 0 various errors
512
 *
513
 *
514
 * Parameters:
515
 *	stralloc *sender = sender address
516
 *	stralloc *rcpt = rcpt address to check
517
 *
518
 *
519
*/
520
521
static int realrcpt (stralloc *sender, stralloc *rcpt)
522
{
523
  int count;
524
  int retstat = CHKUSER_KO;
525
  struct vqpasswd *user_passwd = NULL;
526
  int fd_file = -1;
527
  int read_char;
528
  int offset;
529
  char read_buf[1024];
530
531
#if defined CHKUSER_ENABLE_UIDGID
532
  uid_t eff_uid;
533
  gid_t eff_gid;
534
#endif
535
536
#if !defined CHKUSER_ALWAYS_ON && defined CHKUSER_STARTING_VARIABLE
537
  if (starting_value == -1) {
538
                if (addrallowed()) {
539
                        return CHKUSER_OK;
540
                } else {
541
                        if (relayclient) {
542
                                return CHKUSER_RELAYING;
543
                        }
544
545
			return CHKUSER_NORCPTHOSTS;
546
		}
547
  }
548
#endif
549
550
  if (INTRUSION_threshold_reached == 1) {
551
	return CHKUSER_ERR_INTRUSION_THRESHOLD;
552
  }
553
554
#if defined CHKUSER_RCPT_LIMIT_VARIABLE
555
556
  ++recipients;
557
  if ((maxrcpt_limit > 0) && (recipients >= maxrcpt_limit)) {
558
	chkuser_commonlog (sender->s, rcpt->s, "intrusion threshold", "max number of allowed rcpt");
559
	INTRUSION_threshold_reached = 1;
560
        return CHKUSER_ERR_MAXRCPT;
561
  }
562
#endif
563
564
/* Search the '@' character */
565
  count = byte_rchr(rcpt->s,rcpt->len,'@');
566
567
  if (count < rcpt->len) {
568
    if (!stralloc_copyb (&user, rcpt->s, count)) DIE_NOMEM();
569
    if (!stralloc_copys (&domain, rcpt->s + count + 1)) DIE_NOMEM();
570
  }
571
  else {
572
    if (!stralloc_copys (&user, rcpt->s)) DIE_NOMEM();
573
    domain.len = 0;
574
  }
575
  if (!stralloc_0 (&user)) DIE_NOMEM();
576
  if (!stralloc_0 (&domain)) DIE_NOMEM();
577
578
#if defined CHKUSER_ENABLE_UIDGID
579
580
/* qmail-smtpd is running now as (effective) qmaild:nofiles */
581
/* Save the effective UID & GID (qmaild:nofiles) */
582
  eff_uid = geteuid ();
583
  eff_gid = getegid ();
584
585
/* Now set new effective UID & GID, getting it from real UID & GID (vpopmail:vchkpw) */
586
  setegid (getgid());
587
  seteuid (getuid());
588
589
/* qmail-smtpd is running now as effective vpopmail:vchkpw */
590
#endif
591
592
593
/*
594
 * 
595
 * Now let's start the test/setting suite
596
 *
597
 **/
598
599
	switch (0) {
600
601
	case 0:
602
/* These are some preliminary settings */
603
  		case_lowers (user.s);
604
  		case_lowers (domain.s);
605
606
	case 1:
607
608
                if (domain.len == 1) {
609
#if defined CHKUSER_DOMAIN_WANTED
610
                        retstat = CHKUSER_ERR_DOMAIN_MISSING;
611
			break;
612
#else
613
                        if (!stralloc_copys (&domain, DEFAULT_DOMAIN)) DIE_NOMEM();
614
  			if (!stralloc_0 (&domain)) DIE_NOMEM();
615
#endif
616
                }
617
618
	case 2:
619
620
#if defined CHKUSER_RCPT_FORMAT
621
622
                if (check_rcpt_address_format (&user, &domain) == 0) {
623
                        retstat = CHKUSER_ERR_RCPT_FORMAT;
624
                        break;
625
                }
626
#endif
627
628
	case 3:
629
630
                if (!addrallowed()) {
631
632
#if defined CHKUSER_RCPT_MX
633
			switch (chkuser_mx_lookup(&domain)) {
634
635
				case DNS_HARD:
636
					retstat = CHKUSER_ERR_RCPT_MX;
637
					break;
638
639
				case DNS_SOFT:
640
					retstat = CHKUSER_ERR_RCPT_MX_TMP;
641
					break;
642
			}
643
644
			if (retstat != CHKUSER_KO) {
645
				break;
646
			}
647
#endif
648
649
  			if (relayclient) {
650
				retstat = CHKUSER_RELAYING;
651
				break;
652
  			}
653
654
                        retstat = CHKUSER_NORCPTHOSTS;
655
                        break;
656
                }
657
658
	case 4:
659
660
#if defined CHKUSER_ENABLE_VAUTH_OPEN
661
                if (db_already_open != 1) {
662
                        if (vauth_open () == 0) {
663
                                db_already_open == 1;
664
                        } else {
665
                                retstat = CHKUSER_ERR_AUTH_RESOURCE;
666
                        }
667
                };
668
#endif
669
670
	case 5:
671
672
#if defined CHKUSER_ENABLE_VGET_REAL_DOMAIN
673
/* Check if domain is a real domain */
674
675
                vget_real_domain(domain.s, domain.a);
676
677
                domain.len = strlen (domain.s) +1;
678
                if (domain.len > (domain.a - 1)) DIE_NOMEM();
679
#endif
680
681
/* Let's get domain's real path */
682
                if (vget_assign(domain.s, domain_path.s, domain_path.a -1, NULL, NULL) == NULL) {
683
			retstat = CHKUSER_OK;
684
			break;
685
		}
686
	
687
		domain_path.len = strlen (domain_path.s);
688
689
	case 6:
690
691
/* Check if domain has bouncing enabled */
692
693
#if !defined CHKUSER_ALWAYS_ON
694
695
#if defined CHKUSER_STARTING_VARIABLE
696
		if (starting_value == 0) {
697
#endif
698
699
	                if (!stralloc_copy (&tmp_path, &domain_path)) DIE_NOMEM();
700
701
#if defined CHKUSER_SPECIFIC_BOUNCING
702
	  		if (!stralloc_cats (&tmp_path, "/")) DIE_NOMEM();
703
	  		if (!stralloc_cats (&tmp_path, CHKUSER_SPECIFIC_BOUNCING)) DIE_NOMEM();
704
			if (!stralloc_0 (&tmp_path)) DIE_NOMEM();
705
	  		fd_file = open_read (tmp_path.s);	
706
	  		if (fd_file != -1) {
707
	      			close (fd_file);
708
			} else {
709
				retstat = CHKUSER_OK;
710
				break;
711
			}
712
#else
713
	  		if (!stralloc_cats (&tmp_path, "/.qmail-default")) DIE_NOMEM();
714
			if (!stralloc_0 (&tmp_path)) DIE_NOMEM();
715
716
	  		read_char = 0;
717
	  		fd_file = open_read (tmp_path.s);	
718
	  		if (fd_file != -1) {
719
	      			read_char = read (fd_file, read_buf, sizeof(read_buf) - 1);
720
	      			close (fd_file);
721
	      			if (read_char < 0) read_char = 0;
722
	  			}
723
	  		read_buf[read_char] = 0;
724
725
	  		if ( strstr(read_buf, CHKUSER_BOUNCE_STRING) == NULL ) {
726
				retstat = CHKUSER_OK;
727
				break;
728
	  		}
729
#endif
730
#if defined CHKUSER_STARTING_VARIABLE
731
		}
732
#endif
733
#endif
734
735
	case 7:
736
#if defined VALIAS
737
/* Check for aliases/forwards - valias*/
738
739
		if (valias_select (user.s, domain.s) != NULL) {
740
			retstat = CHKUSER_OK;
741
			break;
742
		}
743
#endif
744
745
	case 8:
746
#if defined CHKUSER_ENABLE_ALIAS
747
/* Check for aliases/forwards - .qmail.x files */
748
749
		if (!stralloc_copy (&tmp_path, &user)) DIE_NOMEM();
750
                /* Change all '.' in ':' before continuing on aliases */
751
                for (count = 0; count < tmp_path.len; ++count)
752
        	        if (*(tmp_path.s + count) == '.') *(tmp_path.s + count) = ':';
753
754
                if (!stralloc_copy (&alias_path, &domain_path)) DIE_NOMEM();
755
                if (!stralloc_cats (&alias_path, "/.qmail-")) DIE_NOMEM();
756
                if (!stralloc_cats (&alias_path, tmp_path.s)) DIE_NOMEM();
757
                if (!stralloc_0 (&alias_path)) DIE_NOMEM();
758
759
		fd_file = open_read (alias_path.s);
760
		if (fd_file != -1) {
761
			close (fd_file);
762
			retstat = CHKUSER_OK;
763
			break;
764
		}
765
#endif
766
767
	case 9:
768
769
#if defined CHKUSER_ENABLE_ALIAS_DEFAULT
770
771
		if (!stralloc_copy (&tmp_path, &user)) DIE_NOMEM();
772
                /* Change all '.' in ':' before continuing on aliases */
773
                for (count = 0; count < tmp_path.len; ++count)
774
        	        if (*(tmp_path.s + count) == '.') *(tmp_path.s + count) = ':';
775
776
                /* Search for the outer '-' character */
777
                for (offset = user.len - 1; offset > 0; --offset)
778
                        if (*(user.s + offset) == CHKUSER_USERS_DASH)  {
779
                                if (!stralloc_copy (&alias_path, &domain_path)) die_nomem();
780
                                if (!stralloc_cats (&alias_path, "/.qmail-")) die_nomem();
781
                                if (!stralloc_catb (&alias_path, user.s, offset)) die_nomem();
782
                                if (!stralloc_cats (&alias_path, "-default")) die_nomem();
783
                                if (!stralloc_0 (&alias_path)) die_nomem();
784
785
                                fd_file = open_read (alias_path.s);
786
                                if (fd_file != -1) {
787
                                        close (fd_file);
788
                                        retstat = CHKUSER_OK;
789
                                        break;
790
                                }
791
                        }
792
793
                if (retstat != CHKUSER_KO) {
794
                        break;
795
                }
796
797
#endif
798
799
        case 10:
800
#if defined CHKUSER_ENABLE_USERS
801
/* User control: check the existance of a real user */
802
803
                user_passwd = vauth_getpw (user.s, domain.s);
804
805
#if defined CHKUSER_ENABLE_USERS_EXTENSIONS
806
                if (user_passwd == NULL) {
807
                       count = 0;
808
                       while ((count < (user.len -1)) && (user_passwd == NULL)) {
809
                               count += byte_chr(&user.s[count], user.len - count, CHKUSER_USERS_DASH);
810
                               if (count < user.len) {
811
                                       if (!stralloc_copyb (&tmp_path, user.s, count)) DIE_NOMEM();
812
                                       if (!stralloc_0 (&tmp_path)) DIE_NOMEM();
813
                                       user_passwd = vauth_getpw (tmp_path.s, domain.s);
814
                                         ++count;
815
                               }
816
                        }
817
                }
818
819
#endif
820
                if (user_passwd != NULL) {
821
822
                /* If user exists check if he has BOUNCE_MAIL flag set */
823
824
                        if (user_passwd->pw_gid & BOUNCE_MAIL)
825
                                retstat = CHKUSER_KO;
826
                        else {
827
                                retstat = CHKUSER_OK;
828
#if defined CHKUSER_MBXQUOTA_VARIABLE
829
                                if ((maxmbxquota_limit > 0) && (strcasecmp(user_passwd->pw_shell, "NOQUOTA") != 0)) {
830
                                        if (!stralloc_copys (&tmp_path, user_passwd->pw_dir)) DIE_NOMEM();
831
                                        if (!stralloc_cats (&tmp_path, "/Maildir")) DIE_NOMEM();
832
                                        if (!stralloc_0 (&tmp_path)) DIE_NOMEM();
833
834
                                        if (vmaildir_readquota(tmp_path.s,format_maildirquota(user_passwd->pw_shell))
835
                                                >= maxmbxquota_limit) {
836
                                                retstat = CHKUSER_ERR_MBXFULL;
837
                                        }
838
                                }
839
#endif
840
                        }
841
                        break;
842
                }
843
#endif
844
845
	case 11:
846
#if defined CHKUSER_ENABLE_EZMLM_LISTS
847
/* Let's check for mailing lists */
848
849
		/* Search for the outer CHKUSER_EZMLM_DASH character */
850
	      	for (offset = user.len - 2; offset > 0; --offset) {
851
			if (*(user.s + offset) == CHKUSER_EZMLM_DASH)  {
852
				if (!stralloc_copy (&tmp_path, &domain_path)) DIE_NOMEM();
853
	      			if (!stralloc_cats (&tmp_path, "/")) DIE_NOMEM();
854
	      			if (!stralloc_catb (&tmp_path, user.s, offset)) DIE_NOMEM();
855
	      			if (!stralloc_cats (&tmp_path, "/mailinglist")) DIE_NOMEM();
856
	      			if (!stralloc_0 (&tmp_path)) DIE_NOMEM();
857
				fd_file = open_read (tmp_path.s);
858
				if (fd_file != -1) {
859
					close (fd_file);
860
					retstat = CHKUSER_OK;
861
					break;
862
				}
863
	        	}
864
		}
865
		if (retstat != CHKUSER_KO) {
866
			break;
867
		}
868
#endif
869
870
        case 12:
871
#if defined CHKUSER_ENABLE_MAILMAN_LISTS
872
/* Let's check for mailing lists */
873
874
                /* Search for the outer CHKUSER_MAILMAN_DASH character */
875
                for (offset = user.len - 2; offset > 0; --offset) {
876
                        if (*(user.s + offset) == CHKUSER_MAILMAN_DASH)  {
877
                                if (!stralloc_copy (&tmp_path, &domain_path)) DIE_NOMEM();
878
                                if (!stralloc_cats (&tmp_path, "/")) DIE_NOMEM();
879
				if (!stralloc_cats (&alias_path, "/.qmail-")) DIE_NOMEM();
880
                                if (!stralloc_catb (&tmp_path, user.s, offset)) DIE_NOMEM();
881
                                if (!stralloc_0 (&tmp_path)) DIE_NOMEM();
882
                                fd_file = open_read (tmp_path.s);
883
	                        read_char = 0;
884
        	                if (fd_file != -1) {
885
                	                read_char = read (fd_file, read_buf, sizeof(read_buf) - 1);
886
                        	        close (fd_file);
887
                                	if (read_char < 0) read_char = 0;
888
                                }
889
	                        read_buf[read_char] = 0;
890
891
        	                if ( strstr(read_buf, CHKUSER_MAILMAN_STRING) == NULL ) {
892
	                                retstat = CHKUSER_OK;
893
	                                break;
894
	                        }
895
896
                        }
897
                }
898
                if (retstat != CHKUSER_KO) {
899
                        break;
900
                }
901
#endif
902
903
/*
904
 * Add this code if another case is following
905
	case xx:
906
		code ....
907
		code ....
908
		code ....
909
		code ....
910
911
		if (xxxxxxxx) {
912
			retstat != CHKUSER_KO)
913
			break;
914
		}
915
*/
916
	    
917
        default:
918
                retstat = CHKUSER_KO;
919
920
	} /* end switch */
921
922
#if defined CHKUSER_ENABLE_UIDGID
923
/* Now switch back effective to saved UID & GID (qmaild:nofiles) */
924
925
  setegid (eff_gid);
926
  seteuid (eff_uid);
927
928
/* qmail-smtpd is running again as (effective) qmaild:nofiles */
929
#endif
930
931
  return retstat;
932
933
}
934
935
936
937
/*
938
 * chkuser_realrcpt ()
939
 *
940
 * Returns a simple status:
941
 *
942
 *      CHKUSER_OK = 1 = Ok, recipients does exists
943
 *
944
 *      CHKUSER_NORCPTHOSTS = Not in rcpthosts
945
 *
946
 *      CHKUSER_KO = ERROR
947
 *
948
 *
949
 * Parameters:
950
 *      stralloc *sender = sender address
951
 *      stralloc *rcpt = rcpt address to check
952
 *
953
 *
954
*/
955
956
int chkuser_realrcpt (stralloc *sender, stralloc *rcpt) {
957
958
int retstat;
959
960
  if (first_time_init_flag) {
961
        first_time_init ();
962
  }
963
964
  retstat = realrcpt (sender, rcpt);
965
966
	switch (retstat) {
967
968
		case CHKUSER_OK:
969
#if defined CHKUSER_LOG_VALID_RCPT
970
			chkuser_commonlog (sender->s, rcpt->s, "accepted rcpt", "found existing recipient");
971
#endif
972
			return CHKUSER_OK;
973
			break;
974
975
                case CHKUSER_RELAYING:
976
#if defined CHKUSER_LOG_VALID_RCPT
977
                        chkuser_commonlog (sender->s, rcpt->s, "relaying rcpt", "client allowed to relay");
978
#endif
979
                        return CHKUSER_RELAYING;
980
                        break;
981
982
		case CHKUSER_NORCPTHOSTS:
983
                        chkuser_commonlog (sender->s, rcpt->s, "rejected relaying", "client not allowed to relay");
984
		        CHKUSER_RCPT_DELAY_ANY();
985
			out(CHKUSER_NORELAY_STRING);
986
			break;
987
988
		case CHKUSER_KO:
989
			chkuser_commonlog (sender->s, rcpt->s, "rejected rcpt", "not existing recipient");
990
		        CHKUSER_DELAY();
991
 			out(CHKUSER_NORCPT_STRING);
992
			break;
993
994
		case CHKUSER_ERR_AUTH_RESOURCE:
995
			chkuser_commonlog (sender->s, rcpt->s, "no auth resource", "no auth resource available");
996
		        CHKUSER_RCPT_DELAY_ANY();
997
			out(CHKUSER_RESOURCE_STRING);
998
			break;
999
1000
		case CHKUSER_ERR_MBXFULL:
1001
			chkuser_commonlog (sender->s, rcpt->s, "mbx overquota", "rcpt mailbox is overquota");
1002
		        CHKUSER_RCPT_DELAY_ANY();
1003
			out(CHKUSER_MBXFULL_STRING);
1004
			break;
1005
1006
		case CHKUSER_ERR_MAXRCPT:
1007
			chkuser_commonlog (sender->s, rcpt->s, "rejected rcpt", "max number of recipients");
1008
		        CHKUSER_DELAY ();
1009
			out(CHKUSER_MAXRCPT_STRING);
1010
			break;
1011
1012
		case CHKUSER_ERR_MAXWRONGRCPT:
1013
			chkuser_commonlog (sender->s, rcpt->s, "rejected rcpt", "max number of invalid recipients");
1014
		        CHKUSER_DELAY ();
1015
			out(CHKUSER_MAXWRONGRCPT_STRING);
1016
			break;
1017
1018
		case CHKUSER_ERR_INTRUSION_THRESHOLD:
1019
			chkuser_commonlog (sender->s, rcpt->s, "rejected intrusion", "rcpt ignored, session over INTRUSION threshold");
1020
			CHKUSER_DELAY ();
1021
			out(CHKUSER_INTRUSIONTHRESHOLD_STRING);
1022
			break;
1023
1024
		case CHKUSER_ERR_DOMAIN_MISSING:
1025
		        CHKUSER_DELAY ();
1026
			out(CHKUSER_DOMAINMISSING_STRING);
1027
			break;
1028
1029
                case CHKUSER_ERR_RCPT_FORMAT:
1030
                        chkuser_commonlog (sender->s, rcpt->s, "rejected rcpt", "invalid rcpt address format");
1031
		        CHKUSER_RCPT_DELAY_ANY();
1032
			out(CHKUSER_RCPTFORMAT_STRING);
1033
                        break;
1034
1035
                case CHKUSER_ERR_RCPT_MX:
1036
			chkuser_commonlog (sender->s, rcpt->s, "rejected rcpt", "invalid rcpt MX domain");
1037
		        CHKUSER_RCPT_DELAY_ANY();
1038
			out(CHKUSER_RCPTMX_STRING);
1039
                        break;
1040
1041
                case CHKUSER_ERR_RCPT_MX_TMP:
1042
                        chkuser_commonlog (sender->s, rcpt->s, "rejected rcpt", "temporary DNS problem");
1043
                        CHKUSER_RCPT_DELAY_ANY();
1044
                        out(CHKUSER_RCPTMX_TMP_STRING);
1045
                        break;
1046
	}
1047
1048
1049
1050
#if defined CHKUSER_WRONGRCPT_LIMIT_VARIABLE
1051
	if ((retstat == CHKUSER_KO) || (retstat == CHKUSER_ERR_DOMAIN_MISSING)) {
1052
        	++wrong_recipients;
1053
        	if ((INTRUSION_threshold_reached == 0) && (maxwrongrcpt_limit > 0) && (wrong_recipients >= maxwrongrcpt_limit)) {
1054
        	        chkuser_commonlog (sender->s, rcpt->s, "intrusion threshold", "max number of allowed invalid rcpt");
1055
        	        INTRUSION_threshold_reached = 1;
1056
        	}
1057
	}
1058
#endif
1059
1060
	return CHKUSER_KO;
1061
}
1062
1063
1064
/*
1065
 *
1066
 * This routine checks for sender format and MX
1067
 *
1068
 */
1069
1070
1071
int chkuser_sender (stralloc *sender) {
1072
1073
int count;
1074
1075
	if (first_time_init_flag) {
1076
		first_time_init ();
1077
	}
1078
1079
#if !defined CHKUSER_ALWAYS_ON && defined CHKUSER_STARTING_VARIABLE
1080
	if (starting_value == -1) {
1081
		return CHKUSER_OK;
1082
	}
1083
#endif
1084
1085
#if defined CHKUSER_SENDER_FORMAT || defined CHKUSER_SENDER_MX
1086
1087
#if defined CHKUSER_SENDER_NOCHECK_VARIABLE
1088
1089
	if (sender_nocheck == 1) {
1090
		return CHKUSER_OK;
1091
	}
1092
#endif
1093
1094
        if (sender->len <= 1) {
1095
#if defined CHKUSER_LOG_VALID_SENDER
1096
		chkuser_commonlog (sender->s, "", "accepted null sender", "accepted null sender always");
1097
#endif
1098
                return CHKUSER_OK;
1099
	}
1100
1101
        count = byte_rchr(sender->s,sender->len,'@');
1102
        if (count < sender->len) {
1103
                if (!stralloc_copyb (&sender_user, sender->s, count)) DIE_NOMEM();
1104
                if (!stralloc_copys (&sender_domain, sender->s + count + 1)) DIE_NOMEM();
1105
        } else {
1106
                if (!stralloc_copys (&sender_user, sender->s)) DIE_NOMEM();
1107
                sender_domain.len = 0;
1108
        }
1109
        if (!stralloc_0 (&sender_user)) DIE_NOMEM();
1110
        if (!stralloc_0 (&sender_domain)) DIE_NOMEM();
1111
1112
#if defined CHKUSER_SENDER_FORMAT
1113
        if (check_sender_address_format (&sender_user, &sender_domain) == 0) {
1114
                chkuser_commonlog (sender->s, "", "rejected sender", "invalid sender address format");
1115
		CHKUSER_SENDER_DELAY_ANY();
1116
		out(CHKUSER_SENDERFORMAT_STRING);
1117
	        return CHKUSER_ERR_SENDER_FORMAT;
1118
        }
1119
1120
#endif
1121
1122
#if defined CHKUSER_SENDER_MX
1123
1124
	switch (chkuser_mx_lookup(&sender_domain)) {
1125
1126
		case DNS_HARD:
1127
			CHKUSER_SENDER_DELAY_ANY();
1128
			out(CHKUSER_SENDERMX_STRING);
1129
			chkuser_commonlog (sender->s, "", "rejected sender", "invalid sender MX domain");
1130
			return CHKUSER_ERR_SENDER_MX;
1131
			break;
1132
1133
		case DNS_SOFT:
1134
			CHKUSER_SENDER_DELAY_ANY();
1135
			out(CHKUSER_SENDERMX_TMP_STRING);
1136
			chkuser_commonlog (sender->s, "", "rejected sender", "temporary DNS problem");
1137
			return CHKUSER_ERR_SENDER_MX_TMP;
1138
			break;
1139
	}
1140
1141
#if defined CHKUSER_LOG_VALID_SENDER
1142
                        chkuser_commonlog (sender->s, "", "accepted sender", "sender accepted");
1143
#endif
1144
1145
	return CHKUSER_OK;
1146
#endif
1147
1148
#else
1149
1150
	return CHKUSER_OK;
1151
1152
#endif
1153
1154
}
1155
1156
(-)qmail-1.03/chkuser.h (+51 lines)
Line 0 Link Here
1
2
/*
3
 *
4
 * 'chkuser.h' v.2.0.8
5
 * for qmail/netqmail > 1.0.3 and vpopmail > 5.3.x
6
 *
7
 * Author: Antonio Nati tonix@interazioni.it
8
 * All rights on this software and
9
 * the identifying words chkusr and chkuser kept by the author
10
 *
11
 * This software may be freely used, modified and distributed,
12
 * but this lines must be kept in every original or derived version.
13
 * Original author "Antonio Nati" and the web URL
14
 * "http://www.interazioni.it/opensource"
15
 * must be indicated in every related work or web page
16
 *
17
 */
18
19
#define CHKUSER
20
#define CHKUSER_VERSION		"2.0.8"
21
#define CHKUSER_VERSION_RL	2
22
#define CHKUSER_VERSION_MJ	0
23
#define CHKUSER_VERSION_MN	8
24
25
#define CHKUSER_OK			1
26
#define CHKUSER_RELAYING		0
27
#define CHKUSER_KO			-1
28
#define CHKUSER_NORCPTHOSTS		-10
29
#define CHKUSER_ERR_AUTH_RESOURCE	-20
30
#define CHKUSER_ERR_MBXFULL		-30
31
#define CHKUSER_ERR_MAXRCPT		-40
32
#define CHKUSER_ERR_MAXWRONGRCPT	-50
33
#define CHKUSER_ERR_DOMAIN_MISSING	-60
34
#define CHKUSER_ERR_RCPT_FORMAT		-70
35
#define CHKUSER_ERR_RCPT_MX		-75
36
#define CHKUSER_ERR_RCPT_MX_TMP		-76
37
#define CHKUSER_ERR_SENDER_FORMAT	-80
38
#define CHKUSER_ERR_SENDER_MX		-85
39
#define CHKUSER_ERR_SENDER_MX_TMP	-86
40
#define CHKUSER_ERR_INTRUSION_THRESHOLD	-90
41
42
void chkuser_cleanup (int exit_value);
43
int chkuser_realrcpt (stralloc *sender, stralloc *rcpt);
44
int chkuser_sender (stralloc *sender);
45
46
#ifdef TLS_H
47
#undef _exit
48
#define _exit(value) { if (ssl) ssl_free(ssl); chkuser_cleanup(value); }
49
#else
50
#define _exit(value) chkuser_cleanup(value);
51
#endif
(-)qmail-1.03/Makefile (-3 / +7 lines)
Lines 304-309 Link Here
304
exit.h auto_spawn.h
304
exit.h auto_spawn.h
305
	./compile chkspawn.c
305
	./compile chkspawn.c
306
306
307
chkuser.o: \
308
compile chkuser.c chkuser.h chkuser_settings.h
309
	./compile chkuser.c
310
307
clean: \
311
clean: \
308
TARGETS
312
TARGETS
309
	rm -f `cat TARGETS`
313
	rm -f `cat TARGETS`
Lines 1618-1631 Link Here
1618
timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o received.o \
1622
timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o received.o \
1619
date822fmt.o now.o qmail.o cdb.a fd.a wait.a datetime.a getln.a \
1623
date822fmt.o now.o qmail.o cdb.a fd.a wait.a datetime.a getln.a \
1620
open.a sig.a case.a env.a stralloc.a alloc.a strerr.a substdio.a error.a str.a \
1624
open.a sig.a case.a env.a stralloc.a alloc.a strerr.a substdio.a error.a str.a \
1621
fs.a auto_qmail.o base64.o socket.lib dns.o ip.o ipalloc.o
1625
fs.a auto_qmail.o base64.o socket.lib chkuser.o dns.o ip.o ipalloc.o
1622
	./load qmail-smtpd qregex.o rcpthosts.o commands.o timeoutread.o \
1626
	./load qmail-smtpd chkuser.o qregex.o rcpthosts.o commands.o timeoutread.o \
1623
	timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \
1627
	timeoutwrite.o ip.o ipme.o ipalloc.o control.o constmap.o \
1624
	tls.o ssl_timeoutio.o ndelay.a -L/usr/local/ssl/lib -lssl -lcrypto \
1628
	tls.o ssl_timeoutio.o ndelay.a -L/usr/local/ssl/lib -lssl -lcrypto \
1625
	received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \
1629
	received.o date822fmt.o now.o qmail.o cdb.a fd.a wait.a \
1626
	datetime.a getln.a open.a sig.a case.a env.a stralloc.a \
1630
	datetime.a getln.a open.a sig.a case.a env.a stralloc.a \
1627
	alloc.a strerr.a substdio.a error.a fs.a auto_qmail.o base64.o  `cat \
1631
	alloc.a strerr.a substdio.a error.a fs.a auto_qmail.o base64.o  `cat \
1628
	socket.lib` dns.o str.a `cat dns.lib`
1632
	socket.lib` dns.o str.a `head -n 1 /var/vpopmail/etc/lib_deps` `cat dns.lib`
1629
1633
1630
qmail-smtpd.0: \
1634
qmail-smtpd.0: \
1631
qmail-smtpd.8
1635
qmail-smtpd.8
(-)qmail-1.03/qmail-smtpd.c (-10 / +12 lines)
Lines 29-34 Link Here
29
#include "cdb.h"
29
#include "cdb.h"
30
#include "fork.h"
30
#include "fork.h"
31
#include "dns.h"
31
#include "dns.h"
32
#include "chkuser.h"
32
33
33
#define BMCHECK_BMF 0
34
#define BMCHECK_BMF 0
34
#define BMCHECK_BMFNR 1
35
#define BMCHECK_BMFNR 1
Lines 611-616 Link Here
611
void smtp_mail(arg) char *arg;
612
void smtp_mail(arg) char *arg;
612
{
613
{
613
  if (!addrparse(arg)) { err_syntax(); return; }
614
  if (!addrparse(arg)) { err_syntax(); return; }
615
  if (chkuser_sender (&addr) != CHKUSER_OK) { return; }
614
  flagsize = 0;
616
  flagsize = 0;
615
  mailfrom_parms(arg);
617
  mailfrom_parms(arg);
616
  if (flagsize) { err_size(); return; }
618
  if (flagsize) { err_size(); return; }
Lines 664-680 Link Here
664
666
665
  if (!flagspp) { sppout(); return; }
667
  if (!flagspp) { sppout(); return; }
666
668
667
  if (relayclient) {
669
  switch (chkuser_realrcpt (&mailfrom, &addr)) {
668
    --addr.len;
670
    case CHKUSER_KO:
669
    if (!stralloc_cats(&addr,relayclient)) die_nomem();
671
      return;
670
    if (!stralloc_0(&addr)) die_nomem();
672
      break;
673
    case CHKUSER_RELAYING:
674
      --addr.len;
675
      if (!stralloc_cats(&addr,relayclient)) die_nomem();
676
      if (!stralloc_0(&addr)) die_nomem();
677
      break;
671
  }
678
  }
672
  else
679
  
673
    if (!addrallowed()) {
674
		strerr_warn6("qmail-smtpd: Attempted relay from ",mailfrom.s," at ",remoteip," to ",addr.s,0);
675
		err_nogateway();
676
		return;
677
	}
678
  if (!env_get("RELAYCLIENT") && brtcheck()) { 
680
  if (!env_get("RELAYCLIENT") && brtcheck()) { 
679
    flagbrt = 1; 
681
    flagbrt = 1; 
680
    log_deny("BAD RCPT TO", mailfrom.s,addr.s);
682
    log_deny("BAD RCPT TO", mailfrom.s,addr.s);
(-)qmail-1.03/TARGETS (+1 lines)
Lines 403-406 Link Here
403
man
403
man
404
setup
404
setup
405
check
405
check
406
chkuser.o
406
update_tmprsadh
407
update_tmprsadh

Return to bug 113509