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 12 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,12 +140,24 @@ static char* url_encode (char* buf, size_t len, const char *input)
140 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 145
   int result;
146
+  size_t addrlen;
146 147
   char value[1024];
147 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 161
   result = srs_forward(srs, value, sizeof(value), address, domain);
150 162
   if (result == SRS_SUCCESS) {
151 163
     output = url_encode(outputbuf, sizeof(outputbuf), value);
@@ -159,7 +171,7 @@ static void handle_forward (srs_t *srs, FILE *fp, const char *address, const cha
159 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 176
   int result;
165 177
   char value[1024];
@@ -197,6 +209,7 @@ static void show_help ()
197 209
     "   -c<dir>        chroot to <dir> (default: none)\n"
198 210
     "   -u<user>       switch user id after port bind (default: none)\n"
199 211
     "   -t<seconds>    timeout for idle client connections (default: 1800)\n"
212
+    "   -X<domain>     exclude additional domain from address rewriting\n"
200 213
     "   -D             fork into background\n"
201 214
     "   -4             force IPv4 socket (default: any)\n"
202 215
     "   -6             force IPv6 socket (default: any)\n"
@@ -207,7 +220,7 @@ static void show_help ()
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 225
 int main (int argc, char **argv)
213 226
 {
@@ -223,12 +236,15 @@ int main (int argc, char **argv)
223 236
   char *tmp;
224 237
   srs_t *srs;
225 238
   struct pollfd fds[3];
239
+  const char **excludes;
240
+  size_t s1 = 0, s2 = 1;
226 241
   handle_t handler[2] = { handle_forward, handle_reverse };
227 242
 
243
+  excludes = (const char**)calloc(1, sizeof(char*));
228 244
   tmp = strrchr(argv[0], '/');
229 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 248
     switch (opt) {
233 249
       case '?':
234 250
         return EXIT_FAILURE;
@@ -268,6 +284,24 @@ int main (int argc, char **argv)
268 284
       case 'h':
269 285
         show_help();
270 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 305
       case 'v':
272 306
         fprintf (stdout, "%s\n", VERSION);
273 307
         return EXIT_SUCCESS;
@@ -415,7 +449,7 @@ int main (int argc, char **argv)
415 449
             }
416 450
             key = url_decode(keybuf, sizeof(keybuf), token);
417 451
             if (!key) break;
418
-            handler[i](srs, fp, key, domain);
452
+            handler[i](srs, fp, key, domain, excludes);
419 453
             if (poll(&fds[2], 1, timeout * 1000) <= 0) break;
420 454
             line = fgets(linebuf, sizeof(linebuf), fp);
421 455
           }

+ 7
- 0
postsrsd.default View File

@@ -6,6 +6,13 @@
6 6
 #
7 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 16
 # Secret key to sign rewritten addresses.
10 17
 # When postsrsd is installed for the first time, a random secret is generated
11 18
 # and stored in /etc/postsrsd.secret. For most installations, that's just fine.

+ 1
- 1
postsrsd.init.in View File

@@ -51,7 +51,7 @@ case "$1" in
51 51
 		--pidfile $PIDFILE \
52 52
 		--name $NAME \
53 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 55
 	then
56 56
 	    log_end_msg 0
57 57
 	else

+ 2
- 1
postsrsd.upstart.in View File

@@ -12,11 +12,12 @@ script
12 12
 	SRS_FORWARD_PORT=10001
13 13
 	SRS_REVERSE_PORT=10002
14 14
 	SRS_SECRET=/etc/@PROJECT_NAME@.secret
15
+	SRS_EXCLUDE_DOMAINS=
15 16
 	RUN_AS=nobody
16 17
 	CHROOT=@CHROOT_DIR@
17 18
 	if [ -r "$DEFAULTFILE" ]; then
18 19
 		. "$DEFAULTFILE"
19 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 22
 end script
22 23
 

Loading…
Cancel
Save