diff --git a/mail/sendmail/Makefile b/mail/sendmail/Makefile index 4b68cd6e3f86..d62a78a065cb 100644 --- a/mail/sendmail/Makefile +++ b/mail/sendmail/Makefile @@ -1,372 +1,369 @@ # New ports collection makefile for: sendmail # Date created: 20 Apr 2000 # Whom: dirk.meyer@dinoex.sub.org # # $FreeBSD$ # PORTNAME= sendmail PORTVERSION= 8.13.0 CATEGORIES= mail ipv6 MASTER_SITES= ftp://ftp.sendmail.org/pub/sendmail/ \ ${MASTER_SITE_RINGSERVER:S,%SUBDIR%,net/mail/sendmail/&,} PKGNAMESUFFIX?= ${TLS_SUFFIX}${SASL_SUFFIX}${LDAP_SUFFIX}${PKGNAMESUFFIX2} DISTNAME= ${PORTNAME}.${PORTVERSION} MAINTAINER= dinoex@FreeBSD.org COMMENT= Reliable, highly configurable mail transfer agent with utilities CONFLICTS?= courier-0.* postfix-1.* postfix-2.* smail-3.* zmailer-2.* CONFLICTS+= sendmail-8.11.* sendmail-*-8.11.* sendmail+*-8.11.* CONFLICTS+= sendmail-8.12.* sendmail-*-8.12.* sendmail+*-8.12.* WRKSRC= ${WRKDIR}/${PORTNAME}-${PORTVERSION} WCONF= ${WRKSRC}/devtools/Site SITE= ${FILESDIR}/site.config.m4.pre4 PLIST= ${WRKDIR}/.PLIST.more DOCS= KNOWNBUGS LICENSE PGPKEYS README RELEASE_NOTES \ sendmail/TRACEFLAGS sendmail/SECURITY sendmail/TUNING MAN1= mailq.1 newaliases.1 vacation.1 MAN5= aliases.5 MAN8= sendmail.8 mailstats.8 makemap.8 praliases.8 smrsh.8 \ mail.local.8 rmail.8 editmap.8 SENDMAIL= ${PREFIX}/sbin/sendmail BASEMAIL= /usr/libexec/sendmail/sendmail PLIST_SUB+= PREFIX=${PREFIX:S=${PREFIX}/==} LDAP_PORT?= net/openldap21-client PKGMESSAGE= ${WRKSRC}/pkg-message # Options to define Features: # SENDMAIL_WITHOUT_IPV6=yes # SENDMAIL_WITHOUT_MILTER=yes # SENDMAIL_WITHOUT_SHMEM=yes # SENDMAIL_WITH_TLS=yes # SENDMAIL_WITH_SMTPS=yes # SENDMAIL_WITH_SASL=yes # SENDMAIL_WITH_SASL2=yes # SENDMAIL_WITH_LDAP=yes # SENDMAIL_WITH_SOCKETMAP=yes # SENDMAIL_WITH_CYRUSLOOKUP=yes # SENDMAIL_WITH_PICKY_HELO_CHECK=yes .if defined(SENDMAIL_WITH_SMTPS) && !defined(SENDMAIL_WITH_TLS) && !defined(WITH_TLS) SENDMAIL_WITH_TLS=yes AUTO_ENABLED_TLS=yes .endif .if defined(SENDMAIL_WITH_CYRUSLOOKUP) && !defined(SENDMAIL_WITH_SOCKETMAP) SENDMAIL_WITH_SOCKETMAP=yes AUTO_ENABLED_SOCKETMAP=yes .endif .if defined(SENDMAIL_WITH_LDAP) LDAP_SUFFIX?= +ldap CONFLICTS+= sendmail+tls-8.* \ sendmail+tls+sasl1-8.* \ sendmail+tls+sasl2-8.* \ sendmail+sasl1-8.* \ sendmail+sasl2-8.* CONFLICTS+= sendmail-sasl-8.* sendmail-sasl2-8.* sendmail-tls-8.* LIB_DEPENDS+= ldap.2:${PORTSDIR}/${LDAP_PORT} LIB_DEPENDS+= lber.2:${PORTSDIR}/${LDAP_PORT} .else CONFLICTS+= sendmail*+ldap*-8.* .endif .if defined(SENDMAIL_WITH_SASL) && !defined(SENDMAIL_WITH_SASL2) SASL_SUFFIX?= +sasl1 CONFLICTS+= sendmail+tls-8.* \ sendmail+tls+ldap-8.* \ sendmail+tls+sasl2-8.* \ sendmail+tls+sasl2+ldap-8.* \ sendmail+sasl2-8.* \ sendmail+sasl2+ldap-8.* \ sendmail+ldap-8.* CONFLICTS+= sendmail-ldap-8.* sendmail-sasl2-8.* sendmail-tls-8.* LIB_DEPENDS+= sasl.8:${PORTSDIR}/security/cyrus-sasl .else CONFLICTS+= sendmail*+sasl1*-8.* .endif .if defined(SENDMAIL_WITH_SASL2) SASL_SUFFIX?= +sasl2 CONFLICTS+= sendmail+tls-8.* \ sendmail+tls+ldap-8.* \ sendmail+tls+sasl-8.* \ sendmail+tls+sasl+ldap-8.* \ sendmail+sasl-8.* \ sendmail+sasl+ldap-8.* \ sendmail+ldap-8.* CONFLICTS+= sendmail-ldap-8.* sendmail-sasl-8.* sendmail-tls-8.* LIB_DEPENDS+= sasl2.2:${PORTSDIR}/security/cyrus-sasl2 RUN_DEPENDS+= ${LOCALBASE}/sbin/saslauthd:${PORTSDIR}/security/cyrus-sasl2-saslauthd .else CONFLICTS+= sendmail*+sasl2*-8.* .endif -.if defined(SENDMAIL_WITH_SOCKETMAP) -EXTRA_PATCHES+= ${FILESDIR}/socketmap.patch -.endif .if defined(SENDMAIL_WITH_CYRUSLOOKUP) EXTRA_PATCHES+= ${FILESDIR}/cyruslookup.patch .endif .if defined(SENDMAIL_WITH_TLS) || defined(WITH_TLS) TLS_SUFFIX?= +tls CONFLICTS+= sendmail+sasl-8.* \ sendmail+sasl+ldap-8.* \ sendmail+sasl2-8.* \ sendmail+sasl2+ldap-8.* \ sendmail+ldap-8.* CONFLICTS+= sendmail-ldap-8.* sendmail-sasl-8.* sendmail-sasl2-8.* .else CONFLICTS+= sendmail*+tls*-8.* .endif # Build site.config.m4 .if exists(${DESTDIR}/etc/mail/mailer.conf) SITE+= ${FILESDIR}/site.config.m4 .if ! defined(SENDMAIL_WITHOUT_IPV6) SITE+= ${FILESDIR}/site.config.m4.ipv6 .endif .endif .if defined(SENDMAIL_WITH_SASL) SITE+= ${FILESDIR}/site.config.m4.sasl .endif .if defined(SENDMAIL_WITH_SASL2) SITE+= ${FILESDIR}/site.config.m4.sasl2 .endif .if defined(SENDMAIL_WITH_LDAP) SITE+= ${FILESDIR}/site.config.m4.ldap .endif .if ! defined(SENDMAIL_WITHOUT_MILTER) SITE+= ${FILESDIR}/site.config.m4.milter .endif .if defined(SENDMAIL_WITH_TLS) || defined(WITH_TLS) USE_OPENSSL= yes .endif # install directly if no mailwrapper support .if ! exists(${DESTDIR}/etc/mail/mailer.conf) PREFIX?= ${DESTDIR}/usr MANPREFIX?= ${DESTDIR}/usr/share PLIST_SUB+= ETCPORT="@comment " .else PLIST_SUB+= ETCPORT="" .endif post-extract: @${SED} -e "s=%%PREFIX%%=${PREFIX}=" ${FILESDIR}/sm-client.sh \ > ${WRKSRC}/sm-client.sh @${SED} -e "s=%%PREFIX%%=${PREFIX}=" ${FILESDIR}/sendmail.sh \ > ${WRKSRC}/sendmail.sh @${SED} -e "s=%%PREFIX%%=${PREFIX}=g" \ -e "s=%%LOCALBASE%%=${LOCALBASE}=g" \ -e "s=%%PORTSDIR%%=${PORTSDIR}=g" \ ${PKGDIR}/pkg-message > ${WRKSRC}/pkg-message pre-configure: .if defined(AUTO_ENABLED_TLS) @${ECHO_CMD} "DEPENDENCY NOTE: SENDMAIL_WITH_TLS will be enabled to support SENDMAIL_WITH_SMTPS" .endif .if defined(AUTO_ENABLED_SOCKETMAP) @${ECHO_CMD} "DEPENDENCY NOTE: SENDMAIL_WITH_SOCKETMAP will be enabled to support SENDMAIL_WITH_CYRUSLOOKUP" .endif do-configure: @${MV} ${WRKSRC}/devtools/OS/FreeBSD ${WRKSRC}/devtools/OS/FreeBSD.sed ${SED} -e "s;\`-pthread\';\`${PTHREAD_LIBS}\';" \ -e "s;\`-O\';\`${CFLAGS}\';" \ ${WRKSRC}/devtools/OS/FreeBSD.sed \ > ${WRKSRC}/devtools/OS/FreeBSD ${SED} -e "s=%%PREFIX%%=${PREFIX}=g" \ -e "s=%%LOCALBASE%%=${LOCALBASE}=g" \ ${SITE} > ${WCONF}/site.config.m4 .if defined(SENDMAIL_WITH_SMTPS) ${ECHO_CMD} \ 'APPENDDEF(`conf_sendmail_ENVDEF'\'', `-D_FFR_SMTP_SSL'\'')' \ >> ${WCONF}/site.config.m4 .endif .if defined(SENDMAIL_WITH_SOCKETMAP) ${ECHO_CMD} \ 'APPENDDEF(`conf_sendmail_ENVDEF'\'', `-DSOCKETMAP'\'')' \ >> ${WCONF}/site.config.m4 .endif .if defined(SENDMAIL_WITH_PICKY_HELO_CHECK) ${ECHO_CMD} \ 'APPENDDEF(`conf_sendmail_ENVDEF'\'', `-DPICKY_HELO_CHECK'\'')' \ >> ${WCONF}/site.config.m4 .endif .if defined(SENDMAIL_WITHOUT_SHMEM) ${ECHO_CMD} \ 'APPENDDEF(`confENVDEF'\'', `-DSM_CONF_SHM=0'\'')' \ >> ${WCONF}/site.config.m4 .endif post-build: ( cd ${WRKSRC}/doc/op && ${MAKE} op.txt ) .if ! defined(SENDMAIL_WITHOUT_MILTER) ( cd ${WRKSRC}/libmilter && ${MAKE} ) .endif pre-install: @${CAT} ${PKGDIR}/pkg-plist >${PLIST} .if ! defined(SENDMAIL_WITHOUT_MILTER) @${CAT} ${FILESDIR}/pkg-milter >>${PLIST} .endif if ! pw groupshow smmsp; then pw groupadd smmsp -g 25; fi if ! pw usershow smmsp; then pw useradd smmsp -g smmsp -u 25 \ -h - -d /nonexistent -s /nonexistent -c "Sendmail Queue"; fi @cd ${WRKSRC} && ${FIND} cf -type f | \ ${AWK} '{print "share/sendmail/" $$1}' >>${PLIST} @cd ${WRKSRC} && ${FIND} -d cf -type d | \ ${AWK} '{print "@dirrm share/sendmail/" $$1}' >>${PLIST} @${ECHO_CMD} "@dirrm share/sendmail" >>${PLIST} .if !defined(NOPORTDOCS) .for i in ${DOCS} @${ECHO_CMD} `${BASENAME} ${i}` | \ ${AWK} '{print "%%DOCSDIR%%/" $$1}' >>${PLIST} .endfor .if defined(SENDMAIL_WITH_CYRUSLOOKUP) @${ECHO_CMD} "share/doc/sendmail/CYRUS_LOOKUP" >>${PLIST} .endif @${ECHO_CMD} "@dirrm %%DOCSDIR%%" >>${PLIST} .endif # We want mail.local and rmail for our system. # the build install catmans only, we have to fix this. post-install: ( cd ${WRKSRC}/mail.local && ${MAKE} force-install ) ( cd ${WRKSRC}/rmail && ${MAKE} force-install ) .if ! defined(SENDMAIL_WITHOUT_MILTER) ${MKDIR} ${PREFIX}/include/libmilter ${INSTALL_DATA} ${WRKSRC}/include/libmilter/mfapi.h \ ${WRKSRC}/include/libmilter/mfdef.h \ ${PREFIX}/include/libmilter/ ${INSTALL_DATA} \ ${WRKSRC}/obj.`${WRKSRC}/devtools/bin/Build -A`/libmilter/libmilter.a \ ${PREFIX}/lib/ .endif .if exists(${DESTDIR}/etc/mail/mailer.conf) ${INSTALL_SCRIPT} ${WRKSRC}/sm-client.sh \ ${LOCALBASE}/etc/rc.d/sm-client.sh.sample ${INSTALL_SCRIPT} ${WRKSRC}/sendmail.sh \ ${LOCALBASE}/etc/rc.d/sendmail.sh.sample .endif ${CHOWN} smmsp:smmsp /var/spool/clientmqueue ${CHMOD} 770 /var/spool/clientmqueue .for i in ${MAN8} @${RM} -f ${MANPREFIX}/man/cat8/${i} ${MANPREFIX}/man/cat8/${i}.gz ${INSTALL_MAN} ${WRKSRC}/*/${i} ${MANPREFIX}/man/man8 .endfor .for i in ${MAN5} @${RM} -f ${MANPREFIX}/man/cat5/${i} ${MANPREFIX}/man/cat5/${i}.gz ${INSTALL_MAN} ${WRKSRC}/*/${i} ${MANPREFIX}/man/man5 .endfor .for i in ${MAN1} @${RM} -f ${MANPREFIX}/man/cat1/${i} ${MANPREFIX}/man/cat1/${i}.gz ${INSTALL_MAN} ${WRKSRC}/*/${i} ${MANPREFIX}/man/man1 .endfor ${MKDIR} ${PREFIX}/share/sendmail @${TAR} -C ${WRKSRC} -cf - cf | \ ${TAR} -C ${PREFIX}/share/sendmail -xf - .if !defined(NOPORTDOCS) ${MKDIR} ${DOCSDIR} @cd ${WRKSRC} && ${INSTALL_DATA} ${DOCS} ${DOCSDIR}/ ${INSTALL_DATA} ${WRKSRC}/doc/op/op.ps ${DOCSDIR}/op.ps ${INSTALL_DATA} ${WRKSRC}/doc/op/op.txt ${DOCSDIR}/op.txt ${INSTALL_DATA} ${WRKSRC}/devtools/README ${DOCSDIR}/DEVTOOLS ${INSTALL_DATA} ${WRKSRC}/sendmail/README ${DOCSDIR}/SENDMAIL ${INSTALL_DATA} ${WRKSRC}/mail.local/README ${DOCSDIR}/MAIL.LOCAL ${INSTALL_DATA} ${WRKSRC}/smrsh/README ${DOCSDIR}/SMRSH .if ! defined(SENDMAIL_WITHOUT_MILTER) ${INSTALL_DATA} ${WRKSRC}/libmilter/README ${DOCSDIR}/MILTER ${MKDIR} ${DOCSDIR}/libmilter @${TAR} -C ${WRKSRC}/libmilter/docs -cf - . | \ ${TAR} -C ${DOCSDIR}/libmilter -xf - .endif .if defined(SENDMAIL_WITH_CYRUSLOOKUP) ${INSTALL_DATA} ${FILESDIR}/CYRUS_LOOKUP ${DOCSDIR}/CYRUS_LOOKUP .endif .endif .if exists(${DESTDIR}/etc/mail/mailer.conf) @${CAT} ${PKGMESSAGE} mailer.base: @${SED} \ -e "s=^sendmail[ ]*/.*$$=sendmail ${BASEMAIL}=" \ -e "s=^send-mail[ ]*/.*$$=send-mail ${BASEMAIL}=" \ -e "s=^mailq[ ]*/.*$$=mailq ${BASEMAIL}=" \ -e "s=^newaliases[ ]*/.*$$=newaliases ${BASEMAIL}=" \ -e "s=^hoststat[ ]*/.*$$=hoststat ${BASEMAIL}=" \ -e "s=^purgestat[ ]*/.*$$=purgestat ${BASEMAIL}=" \ ${DESTDIR}/etc/mail/mailer.conf > ${DESTDIR}/etc/mail/mailer.conf.new ${MV} ${DESTDIR}/etc/mail/mailer.conf.new \ ${DESTDIR}/etc/mail/mailer.conf mailer.conf: @${SED} \ -e "s=^sendmail[ ]*/.*$$=sendmail ${SENDMAIL}=" \ -e "s=^send-mail[ ]*/.*$$=send-mail ${SENDMAIL}=" \ -e "s=^mailq[ ]*/.*$$=mailq ${SENDMAIL}=" \ -e "s=^newaliases[ ]*/.*$$=newaliases ${SENDMAIL}=" \ -e "s=^hoststat[ ]*/.*$$=hoststat ${SENDMAIL}=" \ -e "s=^purgestat[ ]*/.*$$=purgestat ${SENDMAIL}=" \ ${DESTDIR}/etc/mail/mailer.conf > ${DESTDIR}/etc/mail/mailer.conf.new ${MV} ${DESTDIR}/etc/mail/mailer.conf.new \ ${DESTDIR}/etc/mail/mailer.conf .endif # create sumbit.cf on older systems # submit.cf: ${DESTDIR}/etc/mail/submit.cf ${DESTDIR}/etc/mail/submit.mc: ${INSTALL_DATA} ${PREFIX}/share/sendmail/cf/cf/submit.mc \ ${DESTDIR}/etc/mail/submit.mc ${DESTDIR}/etc/mail/submit.cf: ${DESTDIR}/etc/mail/submit.mc @( cd ${DESTDIR}/etc/mail && ${MAKE} \ SENDMAIL_CF_DIR=${PREFIX}/share/sendmail/cf \ SENDMAIL_MC=submit ) # create basics for smtp-auth # howto-sasldb: @${ECHO_CMD} "# Links:" @${ECHO_CMD} "#" @${ECHO_CMD} "# http://www.sendmail.org/~gshapiro/" @${ECHO_CMD} "# http://www.sendmail.org/~ca/email/auth.html" @${ECHO_CMD} "# http://www.asp.ogi.edu/people/paja/linux/sendmail/" @${ECHO_CMD} "# http://blue-labs.org/clue/sendmail.php" @${ECHO_CMD} "# http://www.digitalanswers.org/sendmail/" @${ECHO_CMD} "#" # create certificates for TLS/SSL # tls-install: ${SETENV} DESTDIR=${DESTDIR} FILESDIR=${FILESDIR} \ ${SH} ${FILESDIR}/tls-install.sh .include .if defined(SENDMAIL_WITH_TLS) || defined(WITH_TLS) .if ! defined(WITH_OPENSSL_BASE) SITE+= ${FILESDIR}/site.config.m4.ssl .endif SITE+= ${FILESDIR}/site.config.m4.tls .endif .if exists(${FILESDIR}/site.config.m4.local) SITE+= ${FILESDIR}/site.config.m4.local .endif .if exists(${DESTDIR}/etc/mail/mailer.conf) && ${PREFIX} == "/usr" pre-everything:: @${ECHO_CMD} "#" @${ECHO_CMD} "# You can't override the base sendmail this way." @${ECHO_CMD} "# your version FreeBSD use mailwrapper." @${ECHO_CMD} "#" @${ECHO_CMD} "# Please install with normal PREFIX" @${ECHO_CMD} "# and activate the port version with" @${ECHO_CMD} "# cd ${PORTSDIR}/mail/sendmail && make mailer.conf" @${ECHO_CMD} "#" @${FALSE} .endif .include diff --git a/mail/sendmail/files/socketmap.patch b/mail/sendmail/files/socketmap.patch deleted file mode 100644 index ea128dbace71..000000000000 --- a/mail/sendmail/files/socketmap.patch +++ /dev/null @@ -1,798 +0,0 @@ -Index: sendmail/sendmail/sendmail/README -diff -u sendmail/sendmail/sendmail/README:1.1.1.2 sendmail/sendmail/sendmail/README:1.3 ---- sendmail/README Thu Jan 23 11:50:26 2003 -+++ sendmail/README Tue Jan 28 16:55:41 2003 -@@ -127,6 +127,8 @@ - PH_MAP PH map support. You will need the libphclient library from - the nph package (http://www-dev.cso.uiuc.edu/ph/nph/). - MAP_NSD nsd map support (IRIX 6.5 and later). -+SOCKETMAP Support for a trivial query protocol over UNIX domain or TCP -+ sockets. - - >>> NOTE WELL for NEWDB support: If you want to get ndbm support, for - >>> Berkeley DB versions under 2.0, it is CRITICAL that you remove -@@ -180,6 +182,50 @@ - check_* rule-set, you can block a certain range of addresses that would - otherwise be considered valid. - -+The socket map uses a simple request/reply protocol over TCP or UNIX domain -+sockets to query an external server. Both requests and replies are text -+based and encoded as D.J. Bernsteins netstrings. E.g., a string -+"hello there" becomes: -+11:hello there, -+ -+NB. neither requests nor replies end with CRLF. -+ -+The request consists of the database map name and the lookup key separated -+by a space character: -+ -+ ' ' -+ -+The server responds with a status indicator and the result (if any): -+ -+ ' ' -+ -+The status indicator is one of the following upper case words: -+OK (the key was found, result contains the looked up value) -+NOTFOUND (the key was not found, the result is empty) -+TEMP (a temporary failure occured) -+TIMEOUT (a timeout occured on the server side) -+PERM (a permanent failure occured) -+ -+In case of errors (status TEMP, TIMEOUT or PERM) the result fied may -+contain an explanatory message. -+ -+Example replies: -+30:OK resolved.addess@example.com, -+ -+in case of a successful lookup, or: -+7:NOTFOUND, -+ -+in case the key was not found, or: -+54:TEMP this text explains that we had a temporary failure, -+ -+in case of a failure. -+ -+The socket map uses the same syntax as milters the specify the remote -+endpoint. E.g.: -+Ksocket mySocketMap inet:12345@127.0.0.1 -+ -+If multiple socket maps define the same remote endpoint, they will share -+a single connection to this endpoint. - - +---------------+ - | COMPILE FLAGS | -Index: sendmail/sendmail/sendmail/conf.c -diff -u sendmail/sendmail/sendmail/conf.c:1.1.1.2 sendmail/sendmail/sendmail/conf.c:1.6 ---- sendmail/conf.c Thu Jan 23 11:50:27 2003 -+++ sendmail/conf.c Fri Jan 24 15:31:59 2003 -@@ -622,6 +622,13 @@ - dequote_init, null_map_open, null_map_close, - arith_map_lookup, null_map_store); - -+#if SOCKETMAP -+ /* arbitrary daemons */ -+ MAPDEF("socket", NULL, MCF_ALIASOK, -+ map_parseargs, socket_map_open, socket_map_close, -+ socket_map_lookup, null_map_store); -+#endif /* SOCKETMAP */ -+ - if (tTd(38, 2)) - { - /* bogus map -- always return tempfail */ -Index: sendmail/sendmail/sendmail/map.c -diff -u sendmail/sendmail/sendmail/map.c:1.1.1.2 sendmail/sendmail/sendmail/map.c:1.25 ---- sendmail/map.c Thu Jan 23 11:50:27 2003 -+++ sendmail/map.c Tue Feb 25 14:57:14 2003 -@@ -66,6 +66,9 @@ - static bool ni_getcanonname __P((char *, int, int *)); - #endif /* NETINFO */ - static bool text_getcanonname __P((char *, int, int *)); -+#ifdef SOCKETMAP -+static STAB * socket_map_findconn __P((const char*)); -+#endif /* SOCKETMAP */ - - /* default error message for trying to open a map in write mode */ - #ifdef ENOSYS -@@ -7395,3 +7398,646 @@ - *statp = EX_CONFIG; - return NULL; - } -+ -+#ifdef SOCKETMAP -+ -+# if NETINET || NETINET6 -+# include -+# endif /* NETINET || NETINET6 */ -+ -+#define socket_map_next map_stack[0] -+#define socket_map_previous map_stack[1] -+ -+/* -+** SOCKET_MAP_OPEN -- open socket table -+*/ -+ -+bool -+socket_map_open(map, mode) -+ MAP *map; -+ int mode; -+{ -+ STAB *s; -+ -+ int sock = 0; -+ SOCKADDR_LEN_T addrlen = 0; -+ int addrno = 0; -+ int save_errno; -+ char *p; -+ char *colon; -+ char *at; -+ struct hostent *hp = NULL; -+ SOCKADDR addr; -+ -+ if (tTd(38, 2)) -+ sm_dprintf("socket_map_open(%s, %s, %d)\n", -+ map->map_mname, map->map_file, mode); -+ -+ mode &= O_ACCMODE; -+ -+ /* sendmail doesn't have the ability to write to SOCKET (yet) */ -+ if (mode != O_RDONLY) -+ { -+ /* issue a pseudo-error message */ -+ errno = SM_EMAPCANTWRITE; -+ return false; -+ } -+ -+ if (*map->map_file == '\0') -+ { -+ syserr("socket map \"%s\": empty or missing socket information", -+ map->map_mname); -+ return false; -+ } -+ -+ s = socket_map_findconn(map->map_file); -+ if (s->s_socketmap != NULL) -+ { -+ /* Copy open connection */ -+ map->map_db1 = s->s_socketmap->map_db1; -+ -+ /* Add this map as head of linked list */ -+ map->socket_map_next = s->s_socketmap; -+ s->s_socketmap = map; -+ -+ if (tTd(38, 2)) -+ sm_dprintf("using cached connection\n"); -+ return true; -+ } -+ -+ if (tTd(38, 2)) -+ sm_dprintf("opening new connection\n"); -+ -+ -+ -+ /* following code is ripped from milter.c */ -+ -+ /* protocol:filename or protocol:port@host */ -+ memset(&addr, '\0', sizeof addr); -+ p = map->map_file; -+ colon = strchr(p, ':'); -+ if (colon != NULL) -+ { -+ *colon = '\0'; -+ -+ if (*p == '\0') -+ { -+# if NETUNIX -+ /* default to AF_UNIX */ -+ addr.sa.sa_family = AF_UNIX; -+# else /* NETUNIX */ -+# if NETINET -+ /* default to AF_INET */ -+ addr.sa.sa_family = AF_INET; -+# else /* NETINET */ -+# if NETINET6 -+ /* default to AF_INET6 */ -+ addr.sa.sa_family = AF_INET6; -+# else /* NETINET6 */ -+ /* no protocols available */ -+ syserr("socket map \"%s\": no valid socket protocols available", -+ map->map_mname); -+ return false; -+# endif /* NETINET6 */ -+# endif /* NETINET */ -+# endif /* NETUNIX */ -+ } -+# if NETUNIX -+ else if (sm_strcasecmp(p, "unix") == 0 || -+ sm_strcasecmp(p, "local") == 0) -+ addr.sa.sa_family = AF_UNIX; -+# endif /* NETUNIX */ -+# if NETINET -+ else if (sm_strcasecmp(p, "inet") == 0) -+ addr.sa.sa_family = AF_INET; -+# endif /* NETINET */ -+# if NETINET6 -+ else if (sm_strcasecmp(p, "inet6") == 0) -+ addr.sa.sa_family = AF_INET6; -+# endif /* NETINET6 */ -+ else -+ { -+# ifdef EPROTONOSUPPORT -+ errno = EPROTONOSUPPORT; -+# else /* EPROTONOSUPPORT */ -+ errno = EINVAL; -+# endif /* EPROTONOSUPPORT */ -+ syserr("socket map \"%s\": unknown socket type %s", -+ map->map_mname, p); -+ return false; -+ } -+ *colon++ = ':'; -+ } -+ else -+ { -+ /* default to AF_UNIX */ -+ addr.sa.sa_family = AF_UNIX; -+ colon = p; -+ } -+ -+# if NETUNIX -+ if (addr.sa.sa_family == AF_UNIX) -+ { -+ long sff = SFF_SAFEDIRPATH|SFF_OPENASROOT|SFF_NOLINK|SFF_EXECOK; -+ -+ at = colon; -+ if (strlen(colon) >= sizeof addr.sunix.sun_path) -+ { -+ syserr("socket map \"%s\": local socket name %s too long", -+ map->map_mname, colon); -+ return false; -+ } -+ errno = safefile(colon, RunAsUid, RunAsGid, RunAsUserName, sff, -+ S_IRUSR|S_IWUSR, NULL); -+ -+ if (errno != 0) -+ { -+ /* if not safe, don't create */ -+ syserr("socket map \"%s\": local socket name %s unsafe", -+ map->map_mname, colon); -+ return false; -+ } -+ -+ (void) sm_strlcpy(addr.sunix.sun_path, colon, -+ sizeof addr.sunix.sun_path); -+ addrlen = sizeof (struct sockaddr_un); -+ } -+ else -+# endif /* NETUNIX */ -+# if NETINET || NETINET6 -+ if (false -+# if NETINET -+ || addr.sa.sa_family == AF_INET -+# endif /* NETINET */ -+# if NETINET6 -+ || addr.sa.sa_family == AF_INET6 -+# endif /* NETINET6 */ -+ ) -+ { -+ unsigned short port; -+ -+ /* Parse port@host */ -+ at = strchr(colon, '@'); -+ if (at == NULL) -+ { -+ syserr("socket map \"%s\": bad address %s (expected port@host)", -+ map->map_mname, colon); -+ return false; -+ } -+ *at = '\0'; -+ if (isascii(*colon) && isdigit(*colon)) -+ port = htons((unsigned short) atoi(colon)); -+ else -+ { -+# ifdef NO_GETSERVBYNAME -+ syserr("socket map \"%s\": invalid port number %s", -+ map->map_mname, colon); -+ return false; -+# else /* NO_GETSERVBYNAME */ -+ register struct servent *sp; -+ -+ sp = getservbyname(colon, "tcp"); -+ if (sp == NULL) -+ { -+ syserr("socket map \"%s\": unknown port name %s", -+ map->map_mname, colon); -+ return false; -+ } -+ port = sp->s_port; -+# endif /* NO_GETSERVBYNAME */ -+ } -+ *at++ = '@'; -+ if (*at == '[') -+ { -+ char *end; -+ -+ end = strchr(at, ']'); -+ if (end != NULL) -+ { -+ bool found = false; -+# if NETINET -+ unsigned long hid = INADDR_NONE; -+# endif /* NETINET */ -+# if NETINET6 -+ struct sockaddr_in6 hid6; -+# endif /* NETINET6 */ -+ -+ *end = '\0'; -+# if NETINET -+ if (addr.sa.sa_family == AF_INET && -+ (hid = inet_addr(&at[1])) != INADDR_NONE) -+ { -+ addr.sin.sin_addr.s_addr = hid; -+ addr.sin.sin_port = port; -+ found = true; -+ } -+# endif /* NETINET */ -+# if NETINET6 -+ (void) memset(&hid6, '\0', sizeof hid6); -+ if (addr.sa.sa_family == AF_INET6 && -+ anynet_pton(AF_INET6, &at[1], -+ &hid6.sin6_addr) == 1) -+ { -+ addr.sin6.sin6_addr = hid6.sin6_addr; -+ addr.sin6.sin6_port = port; -+ found = true; -+ } -+# endif /* NETINET6 */ -+ *end = ']'; -+ if (!found) -+ { -+ syserr("socket map \"%s\": Invalid numeric domain spec \"%s\"", -+ map->map_mname, at); -+ return false; -+ } -+ } -+ else -+ { -+ syserr("socket map \"%s\": Invalid numeric domain spec \"%s\"", -+ map->map_mname, at); -+ return false; -+ } -+ } -+ else -+ { -+ hp = sm_gethostbyname(at, addr.sa.sa_family); -+ if (hp == NULL) -+ { -+ syserr("socket map \"%s\": Unknown host name %s", -+ map->map_mname, at); -+ return false; -+ } -+ addr.sa.sa_family = hp->h_addrtype; -+ switch (hp->h_addrtype) -+ { -+# if NETINET -+ case AF_INET: -+ memmove(&addr.sin.sin_addr, -+ hp->h_addr, INADDRSZ); -+ addr.sin.sin_port = port; -+ addrlen = sizeof (struct sockaddr_in); -+ addrno = 1; -+ break; -+# endif /* NETINET */ -+ -+# if NETINET6 -+ case AF_INET6: -+ memmove(&addr.sin6.sin6_addr, -+ hp->h_addr, IN6ADDRSZ); -+ addr.sin6.sin6_port = port; -+ addrlen = sizeof (struct sockaddr_in6); -+ addrno = 1; -+ break; -+# endif /* NETINET6 */ -+ -+ default: -+ syserr("socket map \"%s\": Unknown protocol for %s (%d)", -+ map->map_mname, at, hp->h_addrtype); -+# if NETINET6 -+ freehostent(hp); -+# endif /* NETINET6 */ -+ return false; -+ } -+ } -+ } -+ else -+# endif /* NETINET || NETINET6 */ -+ { -+ syserr("socket map \"%s\": unknown socket protocol", map->map_mname); -+ return false; -+ } -+ -+ /* nope, actually connecting */ -+ for (;;) -+ { -+ sock = socket(addr.sa.sa_family, SOCK_STREAM, 0); -+ if (sock < 0) -+ { -+ save_errno = errno; -+ if (tTd(38, 5)) -+ sm_dprintf("socket map \"%s\": error creating socket: %s\n", -+ map->map_mname, -+ sm_errstring(save_errno)); -+# if NETINET6 -+ if (hp != NULL) -+ freehostent(hp); -+# endif /* NETINET6 */ -+ return false; -+ } -+ -+ if (connect(sock, (struct sockaddr *) &addr, addrlen) >= 0) -+ break; -+ -+ /* couldn't connect.... try next address */ -+ save_errno = errno; -+ p = CurHostName; -+ CurHostName = at; -+ if (tTd(38, 5)) -+ sm_dprintf("socket_open (%s): open %s failed: %s\n", -+ map->map_mname, at, sm_errstring(save_errno)); -+ CurHostName = p; -+ (void) close(sock); -+ -+ /* try next address */ -+ if (hp != NULL && hp->h_addr_list[addrno] != NULL) -+ { -+ switch (addr.sa.sa_family) -+ { -+# if NETINET -+ case AF_INET: -+ memmove(&addr.sin.sin_addr, -+ hp->h_addr_list[addrno++], -+ INADDRSZ); -+ break; -+# endif /* NETINET */ -+ -+# if NETINET6 -+ case AF_INET6: -+ memmove(&addr.sin6.sin6_addr, -+ hp->h_addr_list[addrno++], -+ IN6ADDRSZ); -+ break; -+# endif /* NETINET6 */ -+ -+ default: -+ if (tTd(38, 5)) -+ sm_dprintf("socket map \"%s\": Unknown protocol for %s (%d)\n", -+ map->map_mname, at, -+ hp->h_addrtype); -+# if NETINET6 -+ freehostent(hp); -+# endif /* NETINET6 */ -+ return false; -+ } -+ continue; -+ } -+ p = CurHostName; -+ CurHostName = at; -+ if (tTd(38, 5)) -+ sm_dprintf("socket map \"%s\": error connecting to socket map: %s\n", -+ map->map_mname, sm_errstring(save_errno)); -+ CurHostName = p; -+# if NETINET6 -+ if (hp != NULL) -+ freehostent(hp); -+# endif /* NETINET6 */ -+ return false; -+ } -+# if NETINET6 -+ if (hp != NULL) -+ { -+ freehostent(hp); -+ hp = NULL; -+ } -+# endif /* NETINET6 */ -+ if ((map->map_db1 = (ARBPTR_T) sm_io_open(SmFtStdiofd, -+ SM_TIME_DEFAULT, -+ (void *) &sock, -+ SM_IO_RDWR, -+ NULL)) == NULL) -+ { -+ close(sock); -+ if (tTd(38, 2)) -+ sm_dprintf("socket_open (%s): failed to create stream: %s\n", -+ map->map_mname, sm_errstring(errno)); -+ return false; -+ } -+ -+ /* Save connection for reuse */ -+ s->s_socketmap = map; -+ return true; -+} -+ -+/* -+** SOCKET_MAP_FINDCONN -- find a SOCKET connection to the server -+** -+** Cache SOCKET connections based on the connection specifier -+** and PID so we don't have multiple connections open to -+** the same server for different maps. Need a separate connection -+** per PID since a parent process may close the map before the -+** child is done with it. -+** -+** Parameters: -+** conn -- SOCKET map connection specifier -+** -+** Returns: -+** Symbol table entry for the SOCKET connection. -+*/ -+ -+static STAB * -+socket_map_findconn(conn) -+ const char *conn; -+{ -+ char *format; -+ char *nbuf; -+ STAB *SM_NONVOLATILE s = NULL; -+ -+ format = "%s%c%d"; -+ nbuf = sm_stringf_x(format, -+ conn, -+ CONDELSE, -+ (int) CurrentPid); -+ if (tTd(38, 20)) -+ sm_dprintf("socket_find_conn '%s'\n", nbuf); -+ SM_TRY -+ s = stab(nbuf, ST_SOCKETMAP, ST_ENTER); -+ SM_FINALLY -+ sm_free(nbuf); -+ SM_END_TRY -+ return s; -+} -+ -+/* -+** SOCKET_MAP_CLOSE -- close the socket -+*/ -+ -+void -+socket_map_close(map) -+ MAP *map; -+{ -+ STAB *s; -+ MAP *smap; -+ -+ if (tTd(38, 20)) -+ sm_dprintf("socket_map_close(%s), pid=%d\n", map->map_file,(int) CurrentPid); -+ -+ /* Check if already closed */ -+ if (!map->map_db1) -+ { -+ if (tTd(38, 20)) -+ sm_dprintf("socket_map_close(%s) already closed\n", map->map_file); -+ return; -+ } -+ -+ sm_io_close((SM_FILE_T *)map->map_db1, SM_TIME_DEFAULT); -+ -+ /* Mark all the maps that share the connection as closed */ -+ s = socket_map_findconn(map->map_file); -+ -+ smap = s->s_socketmap; -+ -+ while (smap != NULL) -+ { -+ MAP *next; -+ -+ if (tTd(38, 2) && smap != map) -+ sm_dprintf("socket_map_close(%s): closed %s (shared SOCKET connection)\n", -+ map->map_mname, smap->map_mname); -+ -+ smap->map_mflags &= ~(MF_OPEN|MF_WRITABLE); -+ smap->map_db1 = NULL; -+ next = smap->socket_map_next; -+ smap->socket_map_next = NULL; -+ smap = next; -+ } -+ -+ s->s_socketmap = NULL; -+} -+ -+/* -+** SOCKET_MAP_LOOKUP -- look up a datum in a SOCKET table -+*/ -+ -+char * -+socket_map_lookup(map, name, av, statp) -+ MAP *map; -+ char *name; -+ char **av; -+ int *statp; -+{ -+ size_t nettolen; -+ char *rval = NULL; -+ SM_FILE_T *f = (SM_FILE_T *)map->map_db1; -+ -+ if (tTd(38, 20)) -+ sm_dprintf("socket_map_lookup(%s, %s) %s\n", -+ map->map_mname, name, map->map_file); -+ -+ nettolen = strlen(map->map_mname) + 1 + strlen(name); -+ if ((sm_io_fprintf(f, SM_TIME_DEFAULT, "%u:%s %s,", -+ nettolen, map->map_mname, name) == SM_IO_EOF) || (sm_io_flush(f, SM_TIME_DEFAULT) != 0) || -+ (sm_io_error(f))) -+ { -+ syserr("socket_map_lookup(%s): failed to send lookup request", -+ map->map_mname); -+ *statp = EX_TEMPFAIL; -+ socket_map_close(map); -+ } -+ else -+ { -+ size_t replylen; -+ -+ if (sm_io_fscanf(f, SM_TIME_DEFAULT, "%9u", &replylen) != 1) -+ { -+ syserr("socket_map_lookup(%s): failed to read length parameter of reply", -+ map->map_mname); -+ *statp = EX_TEMPFAIL; -+ socket_map_close(map); -+ } -+ else -+ { -+ /* XXX arbitrary limit for sanity */ -+ if (replylen > 1000000) -+ { -+ syserr("socket_map_lookup(%s): reply too long: %u", -+ map->map_mname, replylen); -+ /* *statp = EX_PROTOCOL; */ -+ *statp = EX_TEMPFAIL; -+ socket_map_close(map); -+ } -+ else -+ { -+ if (sm_io_getc(f, SM_TIME_DEFAULT) != ':') -+ { -+ syserr("socket_map_lookup(%s): missing ':' in reply", -+ map->map_mname); -+ /* *statp = EX_PROTOCOL; */ -+ *statp = EX_TEMPFAIL; -+ } -+ else -+ { -+ size_t recvlen; -+ char *replybuf = (char *) sm_malloc(replylen + 1); -+ recvlen = sm_io_read(f, SM_TIME_DEFAULT, -+ replybuf, replylen); -+ if (recvlen < replylen) -+ { -+ syserr("socket_map_lookup(%s): received only %u of %u reply characters", -+ map->map_mname, recvlen, replylen); -+ *statp = EX_TEMPFAIL; -+ socket_map_close(map); -+ } -+ else -+ { -+ if (sm_io_getc(f, SM_TIME_DEFAULT) != ',') -+ { -+ syserr("socket_map_lookup(%s): missing ',' in reply", -+ map->map_mname); -+ /* *statp = EX_PROTOCOL; */ -+ *statp = EX_TEMPFAIL; -+ socket_map_close(map); -+ } -+ else -+ { -+ char *value; -+ char *status = replybuf; -+ -+ replybuf[recvlen] = '\0'; -+ value = strchr(replybuf, ' '); -+ if (value != NULL) -+ { -+ *value = '\0'; -+ value++; -+ } -+ -+ if (strcmp(status, "OK") == 0) -+ { -+ *statp = EX_OK; -+ -+ /* collect the return value */ -+ if (bitset(MF_MATCHONLY, map->map_mflags)) -+ rval = map_rewrite(map, name, strlen(name), NULL); -+ else -+ rval = map_rewrite(map, value, strlen(value), av); -+ } -+ else if(strcmp(status, "NOTFOUND") == 0) -+ { -+ *statp = EX_NOTFOUND; -+ if (tTd(38, 20)) -+ sm_dprintf("socket_map_lookup(%s): %s not found\n", -+ map->map_mname, name); -+ } -+ else -+ { -+ if (tTd(38, 5)) -+ sm_dprintf("socket_map_lookup(%s, %s): server returned error: type=%s, reason=%s\n", -+ map->map_mname, name, status, -+ value ? value : ""); -+ if ((strcmp(status, "TEMP") == 0) || -+ (strcmp(status, "TIMEOUT") == 0)) -+ { -+ *statp = EX_TEMPFAIL; -+ } -+ else if(strcmp(status, "PERM") == 0) -+ { -+ *statp = EX_UNAVAILABLE; -+ } -+ else -+ { -+ *statp = EX_PROTOCOL; -+ } -+ } -+ } -+ } -+ -+ sm_free(replybuf); -+ } -+ } -+ } -+ } -+ -+ return rval; -+} -+ -+ -+#endif /* SOCKETMAP */ -Index: sendmail/sendmail/sendmail/sendmail.h -diff -u sendmail/sendmail/sendmail/sendmail.h:1.1.1.2 sendmail/sendmail/sendmail/sendmail.h:1.3 ---- sendmail/sendmail.h Thu Jan 23 11:50:27 2003 -+++ sendmail/sendmail.h Thu Jan 23 11:51:38 2003 -@@ -1382,6 +1382,9 @@ - #if LDAPMAP - MAP *sv_lmap; /* Maps for LDAP connection */ - #endif /* LDAPMAP */ -+#if SOCKETMAP -+ MAP *sv_socketmap; /* Maps for SOCKET connection */ -+#endif /* SOCKETMAP */ - #if MILTER - struct milter *sv_milter; /* milter filter name */ - #endif /* MILTER */ -@@ -1413,8 +1416,12 @@ - #endif /* MILTER */ - #define ST_QUEUE 15 /* a queue entry */ - -+#if SOCKETMAP -+# define ST_SOCKETMAP 16 /* List head of maps for SOCKET connection */ -+#endif /* SOCKETMAP */ -+ - /* This entry must be last */ --#define ST_MCI 16 /* mailer connection info (offset) */ -+#define ST_MCI 17 /* mailer connection info (offset) */ - - #define s_class s_value.sv_class - #define s_address s_value.sv_addr -@@ -1432,6 +1439,9 @@ - #if LDAPMAP - # define s_lmap s_value.sv_lmap - #endif /* LDAPMAP */ -+#if SOCKETMAP -+# define s_socketmap s_value.sv_socketmap -+#endif /* SOCKETMAP */ - #if MILTER - # define s_milter s_value.sv_milter - #endif /* MILTER */ -Index: sendmail/sendmail/sendmail/stab.c -diff -u sendmail/sendmail/sendmail/stab.c:1.1.1.1 sendmail/sendmail/sendmail/stab.c:1.2 ---- sendmail/stab.c Fri Oct 11 14:44:04 2002 -+++ sendmail/stab.c Wed Jan 22 18:57:22 2003 -@@ -173,6 +173,12 @@ - len = sizeof s->s_quegrp; - break; - -+#if SOCKETMAP -+ case ST_SOCKETMAP: -+ len = sizeof s->s_socketmap; -+ break; -+#endif /* SOCKETMAP */ -+ - default: - /* - ** Each mailer has its own MCI stab entry: