Browse Source

Optionally exclude domains from address rewriting

Useful for subdomains which are handled by the same
mail server.
tags/1.0
Timo Röhling 11 years ago
parent
commit
45648f63df
4 changed files with 49 additions and 7 deletions
  1. 39
    5
      postsrsd.c
  2. 7
    0
      postsrsd.default
  3. 1
    1
      postsrsd.init.in
  4. 2
    1
      postsrsd.upstart.in

+ 39
- 5
postsrsd.c View File

140
   return buf;
140
   return buf;
141
 }
141
 }
142
 
142
 
143
-static void handle_forward (srs_t *srs, FILE *fp, const char *address, const char *domain)
143
+static void handle_forward (srs_t *srs, FILE *fp, const char *address, const char *domain, const char **excludes)
144
 {
144
 {
145
   int result;
145
   int result;
146
+  size_t addrlen;
146
   char value[1024];
147
   char value[1024];
147
   char outputbuf[1024], *output;
148
   char outputbuf[1024], *output;
148
 
149
 
150
+  addrlen = strlen(address);
151
+  for(; *excludes; excludes++) {
152
+    size_t len;
153
+    len = strlen(*excludes);
154
+    if (len >= addrlen) continue;
155
+    if (strcasecmp(*excludes, &address[addrlen - len]) == 0 && (**excludes == '.' || address[addrlen - len - 1] == '@')) {
156
+      fputs ("500 Domain excluded from SRS\n", fp);
157
+      fflush (fp);
158
+      return;
159
+    }
160
+  }
149
   result = srs_forward(srs, value, sizeof(value), address, domain);
161
   result = srs_forward(srs, value, sizeof(value), address, domain);
150
   if (result == SRS_SUCCESS) {
162
   if (result == SRS_SUCCESS) {
151
     output = url_encode(outputbuf, sizeof(outputbuf), value);
163
     output = url_encode(outputbuf, sizeof(outputbuf), value);
159
   fflush (fp);
171
   fflush (fp);
160
 }
172
 }
161
 
173
 
162
-static void handle_reverse (srs_t *srs, FILE *fp, const char *address, const char *domain)
174
+static void handle_reverse (srs_t *srs, FILE *fp, const char *address, const char *domain, const char **excludes)
163
 {
175
 {
164
   int result;
176
   int result;
165
   char value[1024];
177
   char value[1024];
197
     "   -c<dir>        chroot to <dir> (default: none)\n"
209
     "   -c<dir>        chroot to <dir> (default: none)\n"
198
     "   -u<user>       switch user id after port bind (default: none)\n"
210
     "   -u<user>       switch user id after port bind (default: none)\n"
199
     "   -t<seconds>    timeout for idle client connections (default: 1800)\n"
211
     "   -t<seconds>    timeout for idle client connections (default: 1800)\n"
212
+    "   -X<domain>     exclude additional domain from address rewriting\n"
200
     "   -D             fork into background\n"
213
     "   -D             fork into background\n"
201
     "   -4             force IPv4 socket (default: any)\n"
214
     "   -4             force IPv4 socket (default: any)\n"
202
     "   -6             force IPv6 socket (default: any)\n"
215
     "   -6             force IPv6 socket (default: any)\n"
207
   );
220
   );
208
 }
221
 }
209
 
222
 
210
-typedef void(*handle_t)(srs_t*, FILE*, const char*, const char*);
223
+typedef void(*handle_t)(srs_t*, FILE*, const char*, const char*, const char**);
211
 
224
 
212
 int main (int argc, char **argv)
225
 int main (int argc, char **argv)
213
 {
226
 {
223
   char *tmp;
236
   char *tmp;
224
   srs_t *srs;
237
   srs_t *srs;
225
   struct pollfd fds[3];
238
   struct pollfd fds[3];
239
+  const char **excludes;
240
+  size_t s1 = 0, s2 = 1;
226
   handle_t handler[2] = { handle_forward, handle_reverse };
241
   handle_t handler[2] = { handle_forward, handle_reverse };
227
 
242
 
243
+  excludes = (const char**)calloc(1, sizeof(char*));
228
   tmp = strrchr(argv[0], '/');
244
   tmp = strrchr(argv[0], '/');
229
   if (tmp) self = strdup(tmp + 1); else self = strdup(argv[0]);
245
   if (tmp) self = strdup(tmp + 1); else self = strdup(argv[0]);
230
 
246
 
231
-  while ((opt = getopt(argc, argv, "46d:f:r:s:u:t:p:c:Dhv")) != -1) {
247
+  while ((opt = getopt(argc, argv, "46d:f:r:s:u:t:p:c:X::Dhv")) != -1) {
232
     switch (opt) {
248
     switch (opt) {
233
       case '?':
249
       case '?':
234
         return EXIT_FAILURE;
250
         return EXIT_FAILURE;
268
       case 'h':
284
       case 'h':
269
         show_help();
285
         show_help();
270
         return EXIT_SUCCESS;
286
         return EXIT_SUCCESS;
287
+      case 'X':
288
+        if (optarg != NULL) {
289
+          tmp = strtok(optarg, ",; \t\r\n");
290
+          while (tmp) {
291
+            if (s1 + 1 >= s2) {
292
+              s2 *= 2;
293
+              excludes = (const char **)realloc(excludes, s2 * sizeof(char*));
294
+              if (excludes == NULL) {
295
+                fprintf (stderr, "%s: Out of memory\n\n", self);
296
+                return EXIT_FAILURE;
297
+              }
298
+            }
299
+            excludes[s1++] = strdup(tmp);
300
+            tmp = strtok(NULL, ",; \t\r\n");
301
+          }
302
+          excludes[s1] = NULL;
303
+        }
304
+        break;
271
       case 'v':
305
       case 'v':
272
         fprintf (stdout, "%s\n", VERSION);
306
         fprintf (stdout, "%s\n", VERSION);
273
         return EXIT_SUCCESS;
307
         return EXIT_SUCCESS;
415
             }
449
             }
416
             key = url_decode(keybuf, sizeof(keybuf), token);
450
             key = url_decode(keybuf, sizeof(keybuf), token);
417
             if (!key) break;
451
             if (!key) break;
418
-            handler[i](srs, fp, key, domain);
452
+            handler[i](srs, fp, key, domain, excludes);
419
             if (poll(&fds[2], 1, timeout * 1000) <= 0) break;
453
             if (poll(&fds[2], 1, timeout * 1000) <= 0) break;
420
             line = fgets(linebuf, sizeof(linebuf), fp);
454
             line = fgets(linebuf, sizeof(linebuf), fp);
421
           }
455
           }

+ 7
- 0
postsrsd.default View File

6
 #
6
 #
7
 #SRS_DOMAIN=example.com
7
 #SRS_DOMAIN=example.com
8
 
8
 
9
+# Exclude additional domains.
10
+# You may list domains which shall not be subjected to address rewriting.
11
+# If a domain name starts with a dot, it matches all subdomains, but not
12
+# the domain itself. Separate multiple domains by space or comma.
13
+#
14
+#SRS_EXCLUDE_DOMAINS=.example.com,example.org
15
+
9
 # Secret key to sign rewritten addresses.
16
 # Secret key to sign rewritten addresses.
10
 # When postsrsd is installed for the first time, a random secret is generated
17
 # When postsrsd is installed for the first time, a random secret is generated
11
 # and stored in /etc/postsrsd.secret. For most installations, that's just fine.
18
 # and stored in /etc/postsrsd.secret. For most installations, that's just fine.

+ 1
- 1
postsrsd.init.in View File

51
 		--pidfile $PIDFILE \
51
 		--pidfile $PIDFILE \
52
 		--name $NAME \
52
 		--name $NAME \
53
 		--startas $DAEMON \
53
 		--startas $DAEMON \
54
-		-- -4 -f"$SRS_FORWARD_PORT" -r"$SRS_REVERSE_PORT" -d"$SRS_DOMAIN" -s"$SRS_SECRET" -u"$RUN_AS" -p"$PIDFILE" -c"$CHROOT" -D
54
+		-- -4 -f"$SRS_FORWARD_PORT" -r"$SRS_REVERSE_PORT" -d"$SRS_DOMAIN" -s"$SRS_SECRET" -u"$RUN_AS" -p"$PIDFILE" -c"$CHROOT" -X"$SRS_EXCLUDE_DOMAINS" -D
55
 	then
55
 	then
56
 	    log_end_msg 0
56
 	    log_end_msg 0
57
 	else
57
 	else

+ 2
- 1
postsrsd.upstart.in View File

12
 	SRS_FORWARD_PORT=10001
12
 	SRS_FORWARD_PORT=10001
13
 	SRS_REVERSE_PORT=10002
13
 	SRS_REVERSE_PORT=10002
14
 	SRS_SECRET=/etc/@PROJECT_NAME@.secret
14
 	SRS_SECRET=/etc/@PROJECT_NAME@.secret
15
+	SRS_EXCLUDE_DOMAINS=
15
 	RUN_AS=nobody
16
 	RUN_AS=nobody
16
 	CHROOT=@CHROOT_DIR@
17
 	CHROOT=@CHROOT_DIR@
17
 	if [ -r "$DEFAULTFILE" ]; then
18
 	if [ -r "$DEFAULTFILE" ]; then
18
 		. "$DEFAULTFILE"
19
 		. "$DEFAULTFILE"
19
 	fi
20
 	fi
20
-	exec @CMAKE_INSTALL_PREFIX@/sbin/@POSTSRSD@ -4 -f"$SRS_FORWARD_PORT" -r"$SRS_REVERSE_PORT" -d"$SRS_DOMAIN" -s"$SRS_SECRET" -u"$RUN_AS" -c"$CHROOT"
21
+	exec @CMAKE_INSTALL_PREFIX@/sbin/@POSTSRSD@ -4 -f"$SRS_FORWARD_PORT" -r"$SRS_REVERSE_PORT" -d"$SRS_DOMAIN" -s"$SRS_SECRET" -u"$RUN_AS" -c"$CHROOT" -X"$SRS_EXCLUDE_DOMAINS"
21
 end script
22
 end script
22
 
23
 

Loading…
Cancel
Save