View | Details | Raw Unified | Return to bug 64566 | Differences between
and this patch

Collapse All | Expand All

(-)sendmail/files/extra-patch-socketmap.patch (+798 lines)
Line 0 Link Here
1
Index: sendmail/sendmail/sendmail/README
2
diff -u sendmail/sendmail/sendmail/README:1.1.1.2
3
--- sendmail/README	Thu Jan 23 11:50:26 2003
4
+++ sendmail/README	Tue Jan 28 16:55:41 2003
5
@@ -127,6 +127,8 @@
6
 PH_MAP		PH map support.  You will need the libphclient library from
7
 		the nph package (http://www-dev.cso.uiuc.edu/ph/nph/).
8
 MAP_NSD		nsd map support (IRIX 6.5 and later).
9
+SOCKETMAP	Support for a trivial query protocol over UNIX domain or TCP
10
+		sockets.
11
12
 >>>  NOTE WELL for NEWDB support: If you want to get ndbm support, for
13
 >>>  Berkeley DB versions under 2.0, it is CRITICAL that you remove
14
@@ -180,6 +182,50 @@
15
 check_* rule-set, you can block a certain range of addresses that would
16
 otherwise be considered valid.
17
18
+The socket map uses a simple request/reply protocol over TCP or UNIX
19
+sockets to query an external server. Both requests and replies are text
20
+based and encoded as D.J. Bernsteins netstrings. E.g., a string
21
+"hello there" becomes:
22
+11:hello there,
23
+
24
+NB. neither requests nor replies end with CRLF.
25
+
26
+The request consists of the database map name and the lookup key separated
27
+by a space character:
28
+
29
+<mapname> ' ' <key>
30
+
31
+The server responds with a status indicator and the result (if any):
32
+
33
+<status> ' ' <result> <LF>
34
+
35
+The status indicator is one of the following upper case words:
36
+OK		(the key was found, result contains the looked up value)
37
+NOTFOUND	(the key was not found, the result is empty)
38
+TEMP		(a temporary failure occured)
39
+TIMEOUT		(a timeout occured on the server side)
40
+PERM		(a permanent failure occured)
41
+
42
+In case of errors (status TEMP, TIMEOUT or PERM) the result fied may
43
+contain an explanatory message.
44
+
45
+Example replies:
46
+30:OK resolved.addess@example.com,
47
+
48
+in case of a successful lookup, or:
49
+7:NOTFOUND,
50
+
51
+in case the key was not found, or:
52
+54:TEMP this text explains that we had a temporary failure,
53
+
54
+in case of a failure.
55
+
56
+The socket map uses the same syntax as milters the specify the remote
57
+endpoint. E.g.:
58
+Ksocket mySocketMap inet:12345@127.0.0.1
59
+
60
+If multiple socket maps define the same remote endpoint, they will share
61
+a single connection to this endpoint.
62
63
 +---------------+
64
 | COMPILE FLAGS |
65
Index: sendmail/sendmail/sendmail/conf.c
66
diff -u sendmail/sendmail/sendmail/conf.c:1.1.1.2
67
--- sendmail/conf.c	Thu Jan 23 11:50:27 2003
68
+++ sendmail/conf.c	Fri Jan 24 15:31:59 2003
69
@@ -622,6 +622,13 @@
70
 		dequote_init, null_map_open, null_map_close,
71
 		arith_map_lookup, null_map_store);
72
73
+#if SOCKETMAP
74
+	/* arbitrary daemons */
75
+	MAPDEF("socket", NULL, MCF_ALIASOK,
76
+		map_parseargs, socket_map_open, socket_map_close,
77
+		socket_map_lookup, null_map_store);
78
+#endif /* SOCKETMAP */
79
+
80
 	if (tTd(38, 2))
81
 	{
82
 		/* bogus map -- always return tempfail */
83
Index: sendmail/sendmail/sendmail/map.c
84
diff -u sendmail/sendmail/sendmail/map.c:1.1.1.2
85
--- sendmail/map.c	Thu Jan 23 11:50:27 2003
86
+++ sendmail/map.c	Tue Feb 25 14:57:14 2003
87
@@ -66,6 +66,9 @@
88
 static bool	ni_getcanonname __P((char *, int, int *));
89
 #endif /* NETINFO */
90
 static bool	text_getcanonname __P((char *, int, int *));
91
+#ifdef SOCKETMAP
92
+static STAB *	socket_map_findconn __P((const char*));
93
+#endif /* SOCKETMAP */
94
95
 /* default error message for trying to open a map in write mode */
96
 #ifdef ENOSYS
97
@@ -7395,3 +7398,646 @@
98
 	*statp = EX_CONFIG;
99
 	return NULL;
100
 }
101
+
102
+#ifdef SOCKETMAP
103
+
104
+# if NETINET || NETINET6
105
+#  include <arpa/inet.h>
106
+# endif /* NETINET || NETINET6 */
107
+
108
+#define socket_map_next map_stack[0]
109
+#define socket_map_previous map_stack[1]
110
+
111
+/*
112
+**  SOCKET_MAP_OPEN -- open socket table
113
+*/
114
+
115
+bool
116
+socket_map_open(map, mode)
117
+	MAP *map;
118
+	int mode;
119
+{
120
+	STAB *s;
121
+
122
+	int sock = 0;
123
+	SOCKADDR_LEN_T addrlen = 0;
124
+	int addrno = 0;
125
+	int save_errno;
126
+	char *p;
127
+	char *colon;
128
+	char *at;
129
+	struct hostent *hp = NULL;
130
+	SOCKADDR addr;
131
+
132
+	if (tTd(38, 2))
133
+		sm_dprintf("socket_map_open(%s, %s, %d)\n",
134
+			map->map_mname, map->map_file, mode);
135
+
136
+	mode &= O_ACCMODE;
137
+
138
+	/* sendmail doesn't have the ability to write to SOCKET (yet) */
139
+	if (mode != O_RDONLY)
140
+	{
141
+		/* issue a pseudo-error message */
142
+		errno = SM_EMAPCANTWRITE;
143
+		return false;
144
+	}
145
+
146
+	if (*map->map_file == '\0')
147
+	{
148
+		syserr("socket map \"%s\": empty or missing socket information",
149
+			map->map_mname);
150
+		return false;
151
+	}
152
+
153
+        s = socket_map_findconn(map->map_file);
154
+	if (s->s_socketmap != NULL)
155
+	{
156
+                /* Copy open connection */
157
+                map->map_db1 = s->s_socketmap->map_db1;
158
+
159
+		/* Add this map as head of linked list */
160
+                map->socket_map_next = s->s_socketmap;
161
+                s->s_socketmap = map;
162
+
163
+		if (tTd(38, 2))
164
+			sm_dprintf("using cached connection\n");
165
+		return true;
166
+	}
167
+
168
+	if (tTd(38, 2))
169
+		sm_dprintf("opening new connection\n");
170
+
171
+
172
+
173
+        /* following code is ripped from milter.c */
174
+
175
+	/* protocol:filename or protocol:port@host */
176
+	memset(&addr, '\0', sizeof addr);
177
+	p = map->map_file;
178
+	colon = strchr(p, ':');
179
+	if (colon != NULL)
180
+	{
181
+		*colon = '\0';
182
+
183
+		if (*p == '\0')
184
+		{
185
+# if NETUNIX
186
+			/* default to AF_UNIX */
187
+			addr.sa.sa_family = AF_UNIX;
188
+# else /* NETUNIX */
189
+#  if NETINET
190
+			/* default to AF_INET */
191
+			addr.sa.sa_family = AF_INET;
192
+#  else /* NETINET */
193
+#   if NETINET6
194
+			/* default to AF_INET6 */
195
+			addr.sa.sa_family = AF_INET6;
196
+#   else /* NETINET6 */
197
+			/* no protocols available */
198
+                        syserr("socket map \"%s\": no valid socket
199
+			map->map_mname);
200
+                        return false;
201
+#   endif /* NETINET6 */
202
+#  endif /* NETINET */
203
+# endif /* NETUNIX */
204
+		}
205
+# if NETUNIX
206
+		else if (sm_strcasecmp(p, "unix") == 0 ||
207
+			 sm_strcasecmp(p, "local") == 0)
208
+			addr.sa.sa_family = AF_UNIX;
209
+# endif /* NETUNIX */
210
+# if NETINET
211
+		else if (sm_strcasecmp(p, "inet") == 0)
212
+			addr.sa.sa_family = AF_INET;
213
+# endif /* NETINET */
214
+# if NETINET6
215
+		else if (sm_strcasecmp(p, "inet6") == 0)
216
+			addr.sa.sa_family = AF_INET6;
217
+# endif /* NETINET6 */
218
+		else
219
+		{
220
+# ifdef EPROTONOSUPPORT
221
+			errno = EPROTONOSUPPORT;
222
+# else /* EPROTONOSUPPORT */
223
+			errno = EINVAL;
224
+# endif /* EPROTONOSUPPORT */
225
+                        syserr("socket map \"%s\": unknown socket type
226
+                               map->map_mname, p);
227
+                        return false;
228
+		}
229
+		*colon++ = ':';
230
+	}
231
+	else
232
+	{
233
+		/* default to AF_UNIX */
234
+		addr.sa.sa_family = AF_UNIX;
235
+		colon = p;
236
+	}
237
+
238
+# if NETUNIX
239
+	if (addr.sa.sa_family == AF_UNIX)
240
+	{
241
+		long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_EXECOK;
242
+
243
+		at = colon;
244
+		if (strlen(colon) >= sizeof addr.sunix.sun_path)
245
+		{
246
+                	syserr("socket map \"%s\": local socket name %s too
247
+                               map->map_mname, colon);
248
+ 			return false;
249
+		}
250
+		errno = safefile(colon, RunAsUid, RunAsGid, RunAsUserName, sff,
251
+				 S_IRUSR|S_IWUSR, NULL);
252
+
253
+		if (errno != 0)
254
+		{
255
+			/* if not safe, don't create */
256
+               		syserr("socket map \"%s\": local socket name %s unsafe",
257
+                               map->map_mname, colon);
258
+ 			return false;
259
+		}
260
+
261
+		(void) sm_strlcpy(addr.sunix.sun_path, colon,
262
+			       sizeof addr.sunix.sun_path);
263
+		addrlen = sizeof (struct sockaddr_un);
264
+	}
265
+	else
266
+# endif /* NETUNIX */
267
+# if NETINET || NETINET6
268
+	if (false
269
+#  if NETINET
270
+		 || addr.sa.sa_family == AF_INET
271
+#  endif /* NETINET */
272
+#  if NETINET6
273
+		 || addr.sa.sa_family == AF_INET6
274
+#  endif /* NETINET6 */
275
+		 )
276
+	{
277
+		unsigned short port;
278
+
279
+		/* Parse port@host */
280
+		at = strchr(colon, '@');
281
+		if (at == NULL)
282
+		{
283
+			syserr("socket map \"%s\": bad address %s (expected port@host)",
284
+				       map->map_mname, colon);
285
+			return false;
286
+		}
287
+		*at = '\0';
288
+		if (isascii(*colon) && isdigit(*colon))
289
+			port = htons((unsigned short) atoi(colon));
290
+		else
291
+		{
292
+#  ifdef NO_GETSERVBYNAME
293
+			syserr("socket map \"%s\": invalid port number %s",
294
+				       map->map_mname, colon);
295
+			return false;
296
+#  else /* NO_GETSERVBYNAME */
297
+			register struct servent *sp;
298
+
299
+			sp = getservbyname(colon, "tcp");
300
+			if (sp == NULL)
301
+			{
302
+				syserr("socket map \"%s\": unknown port name %s",
303
+					       map->map_mname, colon);
304
+				return false;
305
+			}
306
+			port = sp->s_port;
307
+#  endif /* NO_GETSERVBYNAME */
308
+		}
309
+		*at++ = '@';
310
+		if (*at == '[')
311
+		{
312
+			char *end;
313
+
314
+			end = strchr(at, ']');
315
+			if (end != NULL)
316
+			{
317
+				bool found = false;
318
+#  if NETINET
319
+				unsigned long hid = INADDR_NONE;
320
+#  endif /* NETINET */
321
+#  if NETINET6
322
+				struct sockaddr_in6 hid6;
323
+#  endif /* NETINET6 */
324
+
325
+				*end = '\0';
326
+#  if NETINET
327
+				if (addr.sa.sa_family == AF_INET &&
328
+				    (hid = inet_addr(&at[1])) != INADDR_NONE)
329
+				{
330
+					addr.sin.sin_addr.s_addr = hid;
331
+					addr.sin.sin_port = port;
332
+					found = true;
333
+				}
334
+#  endif /* NETINET */
335
+#  if NETINET6
336
+				(void) memset(&hid6, '\0', sizeof hid6);
337
+				if (addr.sa.sa_family == AF_INET6 &&
338
+				    anynet_pton(AF_INET6, &at[1],
339
+						&hid6.sin6_addr) == 1)
340
+				{
341
+					addr.sin6.sin6_addr = hid6.sin6_addr;
342
+					addr.sin6.sin6_port = port;
343
+					found = true;
344
+				}
345
+#  endif /* NETINET6 */
346
+				*end = ']';
347
+				if (!found)
348
+				{
349
+					syserr("socket map \"%s\": Invalid numeric domain spec \"%s\"",
350
+					       map->map_mname, at);
351
+					return false;
352
+				}
353
+			}
354
+			else
355
+			{
356
+				syserr("socket map \"%s\": Invalid numeric domain spec \"%s\"",
357
+				       map->map_mname, at);
358
+				return false;
359
+			}
360
+		}
361
+		else
362
+		{
363
+			hp = sm_gethostbyname(at, addr.sa.sa_family);
364
+			if (hp == NULL)
365
+			{
366
+				syserr("socket map \"%s\": Unknown host name %s",
367
+					map->map_mname, at);
368
+				return false;
369
+			}
370
+			addr.sa.sa_family = hp->h_addrtype;
371
+			switch (hp->h_addrtype)
372
+			{
373
+#  if NETINET
374
+			  case AF_INET:
375
+				memmove(&addr.sin.sin_addr,
376
+					hp->h_addr, INADDRSZ);
377
+				addr.sin.sin_port = port;
378
+				addrlen = sizeof (struct sockaddr_in);
379
+				addrno = 1;
380
+				break;
381
+#  endif /* NETINET */
382
+
383
+#  if NETINET6
384
+			  case AF_INET6:
385
+				memmove(&addr.sin6.sin6_addr,
386
+					hp->h_addr, IN6ADDRSZ);
387
+				addr.sin6.sin6_port = port;
388
+				addrlen = sizeof (struct sockaddr_in6);
389
+				addrno = 1;
390
+				break;
391
+#  endif /* NETINET6 */
392
+
393
+			  default:
394
+				syserr("socket map \"%s\": Unknown protocol for %s (%d)",
395
+					map->map_mname, at, hp->h_addrtype);
396
+#  if NETINET6
397
+				freehostent(hp);
398
+#  endif /* NETINET6 */
399
+				return false;
400
+			}
401
+		}
402
+	}
403
+	else
404
+# endif /* NETINET || NETINET6 */
405
+	{
406
+		syserr("socket map \"%s\": unknown socket protocol", map->map_mname);
407
+		return false;
408
+	}
409
+
410
+	/* nope, actually connecting */
411
+	for (;;)
412
+	{
413
+		sock = socket(addr.sa.sa_family, SOCK_STREAM, 0);
414
+		if (sock < 0)
415
+		{
416
+			save_errno = errno;
417
+			if (tTd(38, 5))
418
+				sm_dprintf("socket map \"%s\": error creating socket: %s\n",
419
+					   map->map_mname,
420
+					   sm_errstring(save_errno));
421
+# if NETINET6
422
+			if (hp != NULL)
423
+				freehostent(hp);
424
+# endif /* NETINET6 */
425
+			return false;
426
+		}
427
+
428
+                if (connect(sock, (struct sockaddr *) &addr, addrlen) >=
429
+                    break;
430
+
431
+		/* couldn't connect.... try next address */
432
+		save_errno = errno;
433
+		p = CurHostName;
434
+		CurHostName = at;
435
+		if (tTd(38, 5))
436
+			sm_dprintf("socket_open (%s): open %s failed: %s\n",
437
+				   map->map_mname, at, sm_errstring(save_errno));
438
+		CurHostName = p;
439
+		(void) close(sock);
440
+
441
+		/* try next address */
442
+		if (hp != NULL && hp->h_addr_list[addrno] != NULL)
443
+		{
444
+			switch (addr.sa.sa_family)
445
+			{
446
+# if NETINET
447
+			  case AF_INET:
448
+				memmove(&addr.sin.sin_addr,
449
+					hp->h_addr_list[addrno++],
450
+					INADDRSZ);
451
+				break;
452
+# endif /* NETINET */
453
+
454
+# if NETINET6
455
+			  case AF_INET6:
456
+				memmove(&addr.sin6.sin6_addr,
457
+					hp->h_addr_list[addrno++],
458
+					IN6ADDRSZ);
459
+				break;
460
+# endif /* NETINET6 */
461
+
462
+			  default:
463
+				if (tTd(38, 5))
464
+					sm_dprintf("socket map \"%s\": Unknown protocol for %s (%d)\n",
465
+						   map->map_mname, at,
466
+						   hp->h_addrtype);
467
+# if NETINET6
468
+				freehostent(hp);
469
+# endif /* NETINET6 */
470
+				return false;
471
+			}
472
+			continue;
473
+		}
474
+		p = CurHostName;
475
+		CurHostName = at;
476
+		if (tTd(38, 5))
477
+			sm_dprintf("socket map \"%s\": error connecting to socket map: %s\n",
478
+				   map->map_mname, sm_errstring(save_errno));
479
+		CurHostName = p;
480
+# if NETINET6
481
+		if (hp != NULL)
482
+			freehostent(hp);
483
+# endif /* NETINET6 */
484
+		return false;
485
+	}
486
+# if NETINET6
487
+	if (hp != NULL)
488
+	{
489
+		freehostent(hp);
490
+		hp = NULL;
491
+	}
492
+# endif /* NETINET6 */
493
+        if ((map->map_db1 = (ARBPTR_T) sm_io_open(SmFtStdiofd,
494
+                                                  SM_TIME_DEFAULT,
495
+                                                  (void *) &sock,
496
+                                                  SM_IO_RDWR,
497
+                                                  NULL)) == NULL)
498
+        {
499
+                close(sock);
500
+		if (tTd(38, 2))
501
+                    sm_dprintf("socket_open (%s): failed to create stream:
502
+                               map->map_mname, sm_errstring(errno));
503
+                return false;
504
+        }
505
+
506
+	/* Save connection for reuse */
507
+	s->s_socketmap = map;
508
+	return true;
509
+}
510
+
511
+/*
512
+**  SOCKET_MAP_FINDCONN -- find a SOCKET connection to the server
513
+**
514
+**	Cache SOCKET connections based on the connection specifier
515
+**      and PID so we don't have multiple connections open to
516
+**	the same server for different maps.  Need a separate connection
517
+**	per PID since a parent process may close the map before the
518
+**	child is done with it.
519
+**
520
+**	Parameters:
521
+**		conn -- SOCKET map connection specifier
522
+**
523
+**	Returns:
524
+**		Symbol table entry for the SOCKET connection.
525
+*/
526
+
527
+static STAB *
528
+socket_map_findconn(conn)
529
+	const char *conn;
530
+{
531
+	char *format;
532
+	char *nbuf;
533
+	STAB *SM_NONVOLATILE s = NULL;
534
+
535
+	format = "%s%c%d";
536
+	nbuf = sm_stringf_x(format,
537
+                            conn,
538
+			    CONDELSE,
539
+			    (int) CurrentPid);
540
+        if (tTd(38, 20))
541
+            sm_dprintf("socket_find_conn '%s'\n", nbuf);
542
+	SM_TRY
543
+		s = stab(nbuf, ST_SOCKETMAP, ST_ENTER);
544
+	SM_FINALLY
545
+		sm_free(nbuf);
546
+	SM_END_TRY
547
+	return s;
548
+}
549
+
550
+/*
551
+**  SOCKET_MAP_CLOSE -- close the socket
552
+*/
553
+
554
+void
555
+socket_map_close(map)
556
+	MAP *map;
557
+{
558
+        STAB *s;
559
+        MAP *smap;
560
+
561
+	if (tTd(38, 20))
562
+		sm_dprintf("socket_map_close(%s), pid=%d\n", map->map_file,(int)
563
+
564
+        /* Check if already closed */
565
+        if (!map->map_db1)
566
+        {
567
+            if (tTd(38, 20))
568
+		sm_dprintf("socket_map_close(%s) already closed\n", map->map_file);
569
+            return;
570
+        }
571
+
572
+        sm_io_close((SM_FILE_T *)map->map_db1, SM_TIME_DEFAULT);
573
+
574
+	/* Mark all the maps that share the connection as closed */
575
+	s = socket_map_findconn(map->map_file);
576
+
577
+        smap = s->s_socketmap;
578
+
579
+	while (smap != NULL)
580
+	{
581
+                MAP *next;
582
+
583
+		if (tTd(38, 2) && smap != map)
584
+			sm_dprintf("socket_map_close(%s): closed %s (shared SOCKET
585
+				   map->map_mname, smap->map_mname);
586
+
587
+		smap->map_mflags &= ~(MF_OPEN|MF_WRITABLE);
588
+                smap->map_db1 = NULL;
589
+                next = smap->socket_map_next;
590
+                smap->socket_map_next = NULL;
591
+                smap = next;
592
+	}
593
+
594
+        s->s_socketmap = NULL;
595
+}
596
+
597
+/*
598
+** SOCKET_MAP_LOOKUP -- look up a datum in a SOCKET table
599
+*/
600
+
601
+char *
602
+socket_map_lookup(map, name, av, statp)
603
+	MAP *map;
604
+	char *name;
605
+	char **av;
606
+	int *statp;
607
+{
608
+        size_t nettolen;
609
+	char *rval = NULL;
610
+        SM_FILE_T *f = (SM_FILE_T *)map->map_db1;
611
+
612
+	if (tTd(38, 20))
613
+		sm_dprintf("socket_map_lookup(%s, %s) %s\n",
614
+			map->map_mname, name, map->map_file);
615
+
616
+        nettolen = strlen(map->map_mname) + 1 + strlen(name);
617
+        if ((sm_io_fprintf(f, SM_TIME_DEFAULT, "%u:%s %s,",
618
+                           nettolen, map->map_mname, name) == SM_IO_EOF)
619
+            (sm_io_error(f)))
620
+        {
621
+		syserr("socket_map_lookup(%s): failed to send lookup request",
622
+		       map->map_mname);
623
+                *statp = EX_TEMPFAIL;
624
+                socket_map_close(map);
625
+        }
626
+        else
627
+        {
628
+            size_t replylen;
629
+
630
+            if (sm_io_fscanf(f, SM_TIME_DEFAULT, "%9u", &replylen) != 1)
631
+            {
632
+		syserr("socket_map_lookup(%s): failed to read length parameter of
633
+		       map->map_mname);
634
+                *statp = EX_TEMPFAIL;
635
+                socket_map_close(map);
636
+            }
637
+            else
638
+            {
639
+                /* XXX arbitrary limit for sanity */
640
+                if (replylen > 1000000)
641
+                {
642
+                    syserr("socket_map_lookup(%s): reply too long: %u",
643
+                           map->map_mname, replylen);
644
+                    /* *statp = EX_PROTOCOL; */
645
+                    *statp = EX_TEMPFAIL;
646
+                    socket_map_close(map);
647
+                }
648
+                else
649
+                {
650
+                    if (sm_io_getc(f, SM_TIME_DEFAULT) != ':')
651
+                    {
652
+                        syserr("socket_map_lookup(%s): missing ':' in
653
+                               map->map_mname);
654
+                        /* *statp = EX_PROTOCOL; */
655
+                        *statp = EX_TEMPFAIL;
656
+                   }
657
+                    else
658
+                    {
659
+                        size_t recvlen;
660
+                        char *replybuf = (char *) sm_malloc(replylen + 1);
661
+                        recvlen = sm_io_read(f, SM_TIME_DEFAULT,
662
+                                             replybuf, replylen);
663
+                        if (recvlen < replylen)
664
+                        {
665
+                            syserr("socket_map_lookup(%s): received only
666
+                                   map->map_mname, recvlen, replylen);
667
+                            *statp = EX_TEMPFAIL;
668
+                            socket_map_close(map);
669
+                        }
670
+                        else
671
+                        {
672
+                            if (sm_io_getc(f, SM_TIME_DEFAULT) != ',')
673
+                            {
674
+                                syserr("socket_map_lookup(%s): missing ','
675
+                                       map->map_mname);
676
+                                /* *statp = EX_PROTOCOL; */
677
+                                *statp = EX_TEMPFAIL;
678
+                                socket_map_close(map);
679
+                            }
680
+                            else
681
+                            {
682
+                                char *value;
683
+                                char *status = replybuf;
684
+
685
+                                replybuf[recvlen] = '\0';
686
+                                value = strchr(replybuf, ' ');
687
+                                if (value != NULL)
688
+                                {
689
+                                    *value = '\0';
690
+                                    value++;
691
+                                }
692
+
693
+                                if (strcmp(status, "OK") == 0)
694
+                                {
695
+                                    *statp = EX_OK;
696
+
697
+                                    /* collect the return value */
698
+                                    if (bitset(MF_MATCHONLY,
699
+                                        rval = map_rewrite(map, name,
700
+                                    else
701
+                                        rval = map_rewrite(map, value,
702
+                                }
703
+                                else if(strcmp(status, "NOTFOUND") == 0)
704
+                                {
705
+                                    *statp = EX_NOTFOUND;
706
+                                    if (tTd(38, 20))
707
+                                        sm_dprintf("socket_map_lookup(%s):
708
+                                                   map->map_mname, name);
709
+                                }
710
+                                else
711
+                                {
712
+                                    if (tTd(38, 5))
713
+                                        sm_dprintf("socket_map_lookup(%s,
714
+                                                   map->map_mname, name,
715
+                                                   value ? value : "");
716
+                                    if ((strcmp(status, "TEMP") == 0) ||
717
+                                        (strcmp(status, "TIMEOUT") == 0))
718
+                                    {
719
+                                        *statp = EX_TEMPFAIL;
720
+                                    }
721
+                                    else if(strcmp(status, "PERM") == 0)
722
+                                    {
723
+                                        *statp = EX_UNAVAILABLE;
724
+                                    }
725
+                                    else
726
+                                    {
727
+                                        *statp = EX_PROTOCOL;
728
+                                    }
729
+                                }
730
+                            }
731
+                        }
732
+
733
+                        sm_free(replybuf);
734
+                    }
735
+                }
736
+            }
737
+        }
738
+
739
+        return rval;
740
+}
741
+
742
+
743
+#endif /* SOCKETMAP */
744
Index: sendmail/sendmail/sendmail/sendmail.h
745
diff -u sendmail/sendmail/sendmail/sendmail.h:1.1.1.2
746
--- sendmail/sendmail.h	Thu Jan 23 11:50:27 2003
747
+++ sendmail/sendmail.h	Thu Jan 23 11:51:38 2003
748
@@ -1382,6 +1382,9 @@
749
 #if LDAPMAP
750
 		MAP		*sv_lmap;	/* Maps for LDAP connection */
751
 #endif /* LDAPMAP */
752
+#if SOCKETMAP
753
+		MAP		*sv_socketmap;	/* Maps for SOCKET connection */
754
+#endif /* SOCKETMAP */
755
 #if MILTER
756
 		struct milter	*sv_milter;	/* milter filter name */
757
 #endif /* MILTER */
758
@@ -1413,8 +1416,12 @@
759
 #endif /* MILTER */
760
 #define ST_QUEUE	15	/* a queue entry */
761
762
+#if SOCKETMAP
763
+# define ST_SOCKETMAP   16      /* List head of maps for SOCKET connection
764
+#endif /* SOCKETMAP */
765
+
766
 /* This entry must be last */
767
-#define ST_MCI		16	/* mailer connection info (offset) */
768
+#define ST_MCI		17	/* mailer connection info (offset) */
769
770
 #define s_class		s_value.sv_class
771
 #define s_address	s_value.sv_addr
772
@@ -1432,6 +1439,9 @@
773
 #if LDAPMAP
774
 # define s_lmap		s_value.sv_lmap
775
 #endif /* LDAPMAP */
776
+#if SOCKETMAP
777
+# define s_socketmap    s_value.sv_socketmap
778
+#endif /* SOCKETMAP */
779
 #if MILTER
780
 # define s_milter	s_value.sv_milter
781
 #endif /* MILTER */
782
Index: sendmail/sendmail/sendmail/stab.c
783
diff -u sendmail/sendmail/sendmail/stab.c:1.1.1.1
784
--- sendmail/stab.c	Fri Oct 11 14:44:04 2002
785
+++ sendmail/stab.c	Wed Jan 22 18:57:22 2003
786
@@ -173,6 +173,12 @@
787
 		len = sizeof s->s_quegrp;
788
 		break;
789
790
+#if SOCKETMAP
791
+	  case ST_SOCKETMAP:
792
+		len = sizeof s->s_socketmap;
793
+		break;
794
+#endif /* SOCKETMAP */
795
+
796
 	  default:
797
 		/*
798
 		**  Each mailer has its own MCI stab entry:
(-)sendmail/files/site.config.m4.socketmap (+1 lines)
Line 0 Link Here
1
APPENDDEF(`conf_sendmail_ENVDEF', `-DSOCKETMAP')

Return to bug 64566