1 diff -urN -x '*~' postfix-2.2.5/src/global/mail_params.h postfix-2.2.5-ident/src/global/mail_params.h
2 --- postfix-2.2.5/src/global/mail_params.h 2006-02-22 16:20:15.000000000 +0100
3 +++ postfix-2.2.5-ident/src/global/mail_params.h 2006-02-22 15:56:31.000000000 +0100
5 #define DEF_SMTP_EHLO_DIS_MAPS ""
6 extern char *var_smtp_ehlo_dis_maps;
8 +#define VAR_SMTPD_IDENT_LOOKUP "smtpd_ident_lookup"
9 +#define DEF_SMTPD_IDENT_LOOKUP ""
10 +extern char *var_smtpd_ident_lookup;
14 diff -urN -x '*~' postfix-2.2.5/src/smtpd/Makefile.in postfix-2.2.5-ident/src/smtpd/Makefile.in
15 --- postfix-2.2.5/src/smtpd/Makefile.in 2005-04-29 23:12:28.000000000 +0200
16 +++ postfix-2.2.5-ident/src/smtpd/Makefile.in 2006-02-22 15:56:31.000000000 +0100
19 SRCS = smtpd.c smtpd_token.c smtpd_check.c smtpd_chat.c smtpd_state.c \
20 smtpd_peer.c smtpd_sasl_proto.c smtpd_sasl_glue.c smtpd_proxy.c \
22 + smtpd_xforward.c smtpd_ident.c
23 OBJS = smtpd.o smtpd_token.o smtpd_check.o smtpd_chat.o smtpd_state.o \
24 smtpd_peer.o smtpd_sasl_proto.o smtpd_sasl_glue.o smtpd_proxy.o \
26 + smtpd_xforward.o smtpd_ident.o
27 HDRS = smtpd_token.h smtpd_check.h smtpd_chat.h smtpd_sasl_proto.h \
28 smtpd_sasl_glue.h smtpd_proxy.h
29 TESTSRC = smtpd_token_test.c
30 diff -urN -x '*~' postfix-2.2.5/src/smtpd/smtpd.c postfix-2.2.5-ident/src/smtpd/smtpd.c
31 --- postfix-2.2.5/src/smtpd/smtpd.c 2006-02-22 16:20:15.000000000 +0100
32 +++ postfix-2.2.5-ident/src/smtpd/smtpd.c 2006-02-22 16:17:23.000000000 +0100
34 char *var_local_rwr_clients;
35 char *var_smtpd_ehlo_dis_words;
36 char *var_smtpd_ehlo_dis_maps;
37 +char *var_smtpd_ident_lookup;
39 bool var_smtpd_use_tls;
40 bool var_smtpd_enforce_tls;
42 int smtpd_input_transp_mask;
45 + * Hosts that should be ident-queried
47 +NAMADR_LIST *smtpd_ident_lookup;
50 * Forward declarations.
52 static void helo_reset(SMTPD_STATE *);
53 @@ -1951,10 +1957,18 @@
56 if (!state->proxy || state->xforward.flags == 0) {
57 - out_fprintf(out_stream, REC_TYPE_NORM,
58 - "Received: from %s (%s [%s])",
59 - state->helo_name ? state->helo_name : state->name,
60 - state->name, state->rfc_addr);
61 + if (namadr_list_match(smtpd_ident_lookup, state->name, state->addr)) {
62 + out_fprintf(out_stream, REC_TYPE_NORM,
63 + "Received: from %s (%s [%s] ident=%s)",
64 + state->helo_name ? state->helo_name : state->name,
65 + state->name, state->rfc_addr,
68 + out_fprintf(out_stream, REC_TYPE_NORM,
69 + "Received: from %s (%s [%s])",
70 + state->helo_name ? state->helo_name : state->name,
71 + state->name, state->rfc_addr);
74 if (var_smtpd_tls_received_header && state->tls_context) {
75 out_fprintf(out_stream, REC_TYPE_NORM,
77 xclient_hosts = namadr_list_init(MATCH_FLAG_NONE, var_xclient_hosts);
78 xforward_hosts = namadr_list_init(MATCH_FLAG_NONE, var_xforward_hosts);
79 hogger_list = namadr_list_init(MATCH_FLAG_NONE, var_smtpd_hoggers);
80 + smtpd_ident_lookup =
81 + namadr_list_init(match_parent_style(VAR_SMTPD_IDENT_LOOKUP),
82 + var_smtpd_ident_lookup);
83 if (getuid() == 0 || getuid() == var_owner_uid)
87 VAR_SMTPD_SASL_TLS_OPTS, DEF_SMTPD_SASL_TLS_OPTS, &var_smtpd_sasl_tls_opts, 0, 0,
89 VAR_REJECT_REPLY_MSG_ACCESS_DENIED, DEF_REJECT_REPLY_MSG_ACCESS_DENIED, &var_reject_reply_msg_access_denied, 1, 0,
90 + VAR_SMTPD_IDENT_LOOKUP, DEF_SMTPD_IDENT_LOOKUP, &var_smtpd_ident_lookup, 0, 0,
93 static CONFIG_RAW_TABLE raw_table[] = {
94 diff -urN -x '*~' postfix-2.2.5/src/smtpd/smtpd.h postfix-2.2.5-ident/src/smtpd/smtpd.h
95 --- postfix-2.2.5/src/smtpd/smtpd.h 2005-01-30 22:45:31.000000000 +0100
96 +++ postfix-2.2.5-ident/src/smtpd/smtpd.h 2006-02-22 15:56:31.000000000 +0100
98 char *addr; /* client host address string */
99 char *namaddr; /* combined name and address */
100 char *rfc_addr; /* address for RFC 2821 */
101 + char *ident_user; /* user name returned by ident RFC 1413 */
102 struct sockaddr_storage sockaddr; /* binary client endpoint */
103 int peer_code; /* 2=ok, 4=soft, 5=hard */
104 int error_count; /* reset after DOT */
106 extern void smtpd_peer_init(SMTPD_STATE *state);
107 extern void smtpd_peer_reset(SMTPD_STATE *state);
109 +extern char *smtpd_ident(struct sockaddr_in *peer_addr, struct sockaddr_in *smtpd_addr);
111 #define SMTPD_PEER_CODE_OK 2
112 #define SMTPD_PEER_CODE_TEMP 4
113 #define SMTPD_PEER_CODE_PERM 5
114 diff -urN -x '*~' postfix-2.2.5/src/smtpd/smtpd_ident.c postfix-2.2.5-ident/src/smtpd/smtpd_ident.c
115 --- postfix-2.2.5/src/smtpd/smtpd_ident.c 1970-01-01 01:00:00.000000000 +0100
116 +++ postfix-2.2.5-ident/src/smtpd/smtpd_ident.c 2006-02-22 15:56:31.000000000 +0100
118 +#include <sys_defs.h>
119 +#include <sys/socket.h>
120 +#include <netinet/in.h>
121 +#include <arpa/inet.h>
122 +#include <stdio.h> /* strerror() */
125 +#include <mymalloc.h>
126 +#include <sys/types.h>
127 +#include <sys/time.h>
129 +#include <vstream.h>
131 +#include <iostuff.h>
134 +#define IDENT_MSGSIZE 256
135 +#define IDENT_TIMEOUT 10
137 +#define CHOMP(STR) { char *tmp; tmp = STR; while (*tmp) { \
138 + if (*tmp == '\n' || *tmp == '\r') *tmp = '\0'; tmp++ ; } }
140 +char *smtpd_ident(struct sockaddr_in *peer_addr, struct sockaddr_in *smtpd_addr)
143 + char ident_msg[IDENT_MSGSIZE + 1], *sp;
144 + char ident_user[IDENT_MSGSIZE + 1];
145 + struct sockaddr_in local_addr;
146 + struct sockaddr_in ident_addr;
148 + VSTREAM *ident_stream;
150 + memset(ident_msg, 0, IDENT_MSGSIZE + 1);
151 + memset(ident_user, 0, IDENT_MSGSIZE + 1);
154 + * Bind the local sockaddr to the same interface as smtpd before
155 + * connecting back to the auth port on the peer. This helps
156 + * with multihomed postfix servers. First, set up the address.
159 + /* Local sockname */
161 + memset((char *) &local_addr, 0, sizeof(local_addr));
162 + local_addr.sin_family = AF_INET;
163 + memcpy((void *) &local_addr.sin_addr, (void *) &smtpd_addr->sin_addr, sizeof(local_addr.sin_addr));
165 + /* Remote sockname + port */
167 + memset((char *) &ident_addr, 0, sizeof(ident_addr));
168 + ident_addr.sin_family = AF_INET;
169 + memcpy((void *) &ident_addr.sin_addr, (void *) &peer_addr->sin_addr, sizeof(ident_addr.sin_addr));
170 + ident_addr.sin_port = htons(113);
175 + if ((ident_sock = socket(ident_addr.sin_family, SOCK_STREAM, 0)) < 0) {
176 + msg_warn("Can't allocate socket for ident lookup: %s", strerror(errno));
180 + /* Now bind the local sock to the interface */
182 + if (bind(ident_sock, (struct sockaddr *)&local_addr, sizeof(local_addr)) < 0) {
183 + msg_warn("local bind of ident sock failed: %s", strerror(errno));
187 + /* connect() back to the smtp client host on port 113 */
189 + if (connect(ident_sock, (struct sockaddr *) &ident_addr, sizeof(ident_addr )) < 0) {
190 + msg_warn( "ident connect to %s: %s", inet_ntoa(peer_addr->sin_addr),
195 + /* Ok, make this a vstream */
197 + ident_stream = vstream_fdopen(ident_sock, O_RDWR);
198 + ident_stream->timeout = IDENT_TIMEOUT;
200 + /* Print the ident message to the remote host */
202 + vstream_fprintf(ident_stream, "%d, %d\n", ntohs(peer_addr->sin_port), ntohs(smtpd_addr->sin_port));
203 + if (vstream_ftimeout(ident_stream)) {
204 + msg_warn( "ident write timed out to %s", inet_ntoa(peer_addr->sin_addr));
208 + /* Read back the result */
210 + vstream_fread(ident_stream, ident_msg, IDENT_MSGSIZE);
211 + if (vstream_ftimeout(ident_stream)) {
212 + msg_warn( "ident read timed out to %s", inet_ntoa(peer_addr->sin_addr));
217 + * Should I even bother with this?
219 + * Even if so, don't worry about this failing, set the timeout low
222 + ident_stream->timeout = 2;
223 + vstream_fwrite(ident_stream, "quit\n", strlen("quit\n"));
225 + if (strlen(ident_msg) == 0) {
226 + msg_warn( "Failed to get ident string from %s", inet_ntoa(peer_addr->sin_addr));
230 + if ((sp = strrchr(ident_msg, ':')) == NULL) {
231 + msg_warn( "Invalid ident string from %s", inet_ntoa(peer_addr->sin_addr));
236 + while (*sp && (*sp == ' ' || *sp == '\t')) {
240 + /* If we break before this line, we know we had some sort of bad error */
242 + strncpy(ident_user, sp, IDENT_MSGSIZE);
243 + msg_info( "Received ident string %s from %s", sp, inet_ntoa(peer_addr->sin_addr));
247 + if (strlen(ident_user) == 0) {
248 + msg_warn( "Failed to get ident user for %s", inet_ntoa(peer_addr->sin_addr));
252 + vstream_fclose(ident_stream);
253 + return_val = mystrdup(ident_user);
256 diff -urN -x '*~' postfix-2.2.5/src/smtpd/smtpd_peer.c postfix-2.2.5-ident/src/smtpd/smtpd_peer.c
257 --- postfix-2.2.5/src/smtpd/smtpd_peer.c 2005-01-30 22:42:18.000000000 +0100
258 +++ postfix-2.2.5-ident/src/smtpd/smtpd_peer.c 2006-02-22 16:21:40.000000000 +0100
261 #include <sys_defs.h>
262 #include <sys/socket.h>
263 +#include <sys/types.h>
264 #include <netinet/in.h>
265 #include <arpa/inet.h>
266 #include <stdio.h> /* strerror() */
269 /* Global library. */
271 +#include <namadr_list.h>
272 #include <mail_proto.h>
273 +#include <mail_params.h>
274 #include <valid_mailhost_addr.h>
276 /* Application-specific. */
280 +extern NAMADR_LIST *smtpd_ident_lookup;
282 /* smtpd_peer_init - initialize peer information */
284 void smtpd_peer_init(SMTPD_STATE *state)
286 char *myname = "smtpd_peer_init";
287 SOCKADDR_SIZE sa_len;
289 + struct sockaddr_in serv_sin;
290 + char *ident_user = NULL;
291 INET_PROTO_INFO *proto_info = inet_proto_info();
293 sa = (struct sockaddr *) & (state->sockaddr);
295 state->addr = mystrdup(CLIENT_ADDR_UNKNOWN);
296 state->rfc_addr = mystrdup(CLIENT_ADDR_UNKNOWN);
297 state->peer_code = SMTPD_PEER_CODE_PERM;
298 + state->ident_user = mystrdup("NO-USER");
304 msg_warn("%s: hostname %s verification failed: %s",
305 state->addr, state->name, MAI_STRERROR(aierr));
306 + state->ident_user = mystrdup("NO-USER");
307 REJECT_PEER_NAME(state, (TEMP_AI_ERROR(aierr) ?
308 SMTPD_PEER_CODE_TEMP : SMTPD_PEER_CODE_PERM));
315 + if (namadr_list_match(smtpd_ident_lookup, state->name, state->addr)) {
316 + /* If getsockname fails, just forget it */
317 + sa_len = sizeof(serv_sin);
318 + if (getsockname(vstream_fileno(state->client), (struct sockaddr *)&serv_sin, &sa_len) >= 0) {
319 + ident_user = smtpd_ident((struct sockaddr_in *)sa, &serv_sin);
320 + if (ident_user == NULL)
321 + state->ident_user = mystrdup("NO-USER");
323 + state->ident_user = ident_user;
325 + msg_warn("getsockname failed while doing ident lookup: %s", strerror(errno));
327 + state->ident_user = mystrdup("NO-USER");
332 state->addr = mystrdup("127.0.0.1"); /* XXX bogus. */
333 state->rfc_addr = mystrdup("127.0.0.1");/* XXX bogus. */
334 state->peer_code = SMTPD_PEER_CODE_OK;
335 + state->ident_user = mystrdup("NO-USER");
341 myfree(state->namaddr);
342 myfree(state->rfc_addr);
343 + myfree(state->ident_user);