On 10/9/20 1:06 PM, Demi M. Obenour wrote: > On 10/8/20 3:19 PM, Wietse Venema wrote: >> Demi M. Obenour: >>> On 10/8/20 8:25 AM, Wietse Venema wrote: >>>> Demi M. Obenour: >>>>> On 10/6/20 4:23 PM, Wietse Venema wrote: >>>>>> If the feature is turned on then there should probably be a >>>>>> default action for users not listed in the table (deny or allow). >>>>>> Its not going to be pretty when only the numerical UID is avaialble >>>>>> (a 1:1 mapping username->sender would not make sense). >>>>> >>>>> What about defaulting to allow if local_sender_login_maps has its >>>>> default value, and deny otherwise? That keeps the current default >>>>> behavior, while still allowing administrators to lock it down. >>>> >>>> The action (deny) for unmatched users should not depend on the >>>> (non-empty) local_sender_login_maps value. >>> >>> Should this be a configuration option? >> >> It is not needed. If someone wants unmatched users to allow all, >> just say so: >> >> local_sender_login_maps = <real login->address map> static:* >> >> This still enforces the allowed email addressesfor users that have >> an entry. >> >> If local_sender_login_maps is turned on, indexing with "#" plus the >> UID as a string would do the job. It is not like users can arbitrarily >> remove their login name from the password file. > > Here is an updated diff which implements this idea. It also splits out > the FROM access check into its own function, and uses var_rcpt_delim > instead of hard-coding "+". $mail_owner is now allowed to send mail > as any user.
Looks like Thunderbird mangled the whitespace. Here is another attempt:
diff -ur ../postfix-3.5.7-old/src/global/mail_params.h
../postfix-3.5.7/src/global/mail_params.h
--- ../postfix-3.5.7-old/src/global/mail_params.h 2020-10-05
18:52:49.518000000 -0400
+++ ../postfix-3.5.7/src/global/mail_params.h 2020-10-05 18:10:32.641000000
-0400
@@ -1667,6 +1667,10 @@
#define DEF_SMTPD_SASL_TYPE DEF_SERVER_SASL_TYPE
extern char *var_smtpd_sasl_type;
+#define VAR_LOCAL_SND_AUTH_MAPS "local_sender_login_maps"
+#define DEF_LOCAL_SND_AUTH_MAPS "static:*"
+extern char *var_local_snd_auth_maps;
+
#define VAR_SMTPD_SND_AUTH_MAPS "smtpd_sender_login_maps"
#define DEF_SMTPD_SND_AUTH_MAPS ""
extern char *var_smtpd_snd_auth_maps;
diff -ur ../postfix-3.5.7-old/src/postdrop/postdrop.c
../postfix-3.5.7/src/postdrop/postdrop.c
--- ../postfix-3.5.7-old/src/postdrop/postdrop.c 2020-10-05
18:52:49.518000000 -0400
+++ ../postfix-3.5.7/src/postdrop/postdrop.c 2020-10-09 12:53:43.249000000
-0400
@@ -114,6 +114,7 @@
#include <stdio.h> /* remove() */
#include <string.h>
#include <stdlib.h>
+#include <inttypes.h>
#include <signal.h>
#include <errno.h>
#include <warn_stat.h>
@@ -147,6 +148,10 @@
#include <rec_attr_map.h>
#include <mail_parm_split.h>
#include <maillog_client.h>
+#include <maps.h>
+#include <mail_addr_find.h>
+#include <strip_addr.h>
+#include <mypwd.h>
/* Application-specific. */
@@ -167,9 +172,13 @@
* Local mail submission access list.
*/
char *var_submit_acl;
+char *var_local_snd_auth_maps;
+char *var_rcpt_delim;
static const CONFIG_STR_TABLE str_table[] = {
VAR_SUBMIT_ACL, DEF_SUBMIT_ACL, &var_submit_acl, 0, 0,
+ VAR_LOCAL_SND_AUTH_MAPS, DEF_LOCAL_SND_AUTH_MAPS,
&var_local_snd_auth_maps, 0, 0,
+ VAR_RCPT_DELIM, DEF_RCPT_DELIM, &var_rcpt_delim, 0, 0,
0,
};
@@ -220,6 +229,65 @@
postdrop_sig(0);
}
+/*
+ * postdrop_check_access - check if a user is authorized to send mail as
+ * the envelope sender
+ */
+static void postdrop_check_access(VSTRING *const buf, uid_t const uid) {
+ MAPS *local_sender_login_maps;
+ struct mypasswd *username;
+ const char *owners;
+ char *saved_owners, *cp, *name, *stripped, *stripped_copy,
username_buf[22];
+ char *pw_name;
+ int found = 0;
+
+ /* Root and $mail_owner are always allowed to send as anyone. */
+ if (uid == 0 || uid == var_owner_uid)
+ return;
+
+ /*
+ * Get the username.
+ */
+ if ((username = mypwuid(uid)) != NULL)
+ pw_name = username->pw_name;
+ else {
+ int status = snprintf(username_buf, sizeof username_buf, "#%"PRIu64,
(uint64_t)uid);
+ if (status < 0 || status >= sizeof username_buf)
+ msg_fatal("snprintf");
+ pw_name = username_buf;
+ }
+
+ local_sender_login_maps = maps_create(VAR_SMTPD_SND_AUTH_MAPS,
+ var_local_snd_auth_maps,
+ DICT_FLAG_FOLD_FIX |
+ DICT_FLAG_UTF8_REQUEST |
+ DICT_FLAG_NO_PROXY |
+ DICT_FLAG_NO_UNAUTH);
+
+ if (vstring_memchr(buf, '\0') != NULL)
+ msg_fatal("uid=%ld: NUL in FROM", (long) uid);
+ if ((owners = maps_find(local_sender_login_maps, pw_name, 0)) == NULL)
+ msg_fatal("uid=%ld: not found in local_sender_login_maps", (long) uid);
+ if (local_sender_login_maps->error != 0)
+ msg_fatal("map lookup succeeded, but error set");
+ if (strcmp(owners, "*") == 0)
+ return;
+ if ((stripped = stripped_copy = strip_addr_internal(vstring_str(buf),
NULL, var_rcpt_delim)) == NULL)
+ stripped = vstring_str(buf);
+ cp = saved_owners = mystrdup(owners);
+ while ((name = mystrtok(&saved_owners, CHARS_COMMA_SP)) != 0) {
+ if (strcmp(stripped, name) == 0) {
+ found = 1;
+ break;
+ }
+ }
+ if (!found)
+ msg_fatal("uid=%ld: does not own address %s", (long) uid,
vstring_str(buf));
+ if (stripped_copy != NULL)
+ myfree(stripped_copy);
+ myfree(cp);
+}
+
MAIL_VERSION_STAMP_DECLARE;
/* main - the main program */
@@ -316,16 +384,6 @@
get_mail_conf_str_table(str_table);
/*
- * Mail submission access control. Should this be in the user-land gate,
- * or in the daemon process?
- */
- mail_dict_init();
- if ((errstr = check_user_acl_byuid(VAR_SUBMIT_ACL, var_submit_acl,
- uid)) != 0)
- msg_fatal("User %s(%ld) is not allowed to submit mail",
- errstr, (long) uid);
-
- /*
* Stop run-away process accidents by limiting the queue file size. This
* is not a defense against DOS attack.
*/
@@ -369,6 +427,16 @@
/* End of initializations. */
/*
+ * Mail submission access control. Should this be in the user-land gate,
+ * or in the daemon process?
+ */
+ mail_dict_init();
+ if ((errstr = check_user_acl_byuid(VAR_SUBMIT_ACL, var_submit_acl,
+ uid)) != 0)
+ msg_fatal("User %s(%ld) is not allowed to submit mail",
+ errstr, (long) uid);
+
+ /*
* Don't trust the caller's time information.
*/
GETTIMEOFDAY(&start);
@@ -429,8 +497,10 @@
if (rec_type == REC_TYPE_TIME)
continue;
/* Check these at submission time instead of pickup time. */
- if (rec_type == REC_TYPE_FROM)
+ if (rec_type == REC_TYPE_FROM) {
+ postdrop_check_access(buf, uid);
from_count++;
+ }
if (rec_type == REC_TYPE_RCPT)
rcpt_count++;
/* Limit the attribute types that users may specify. */
@@ -477,7 +547,7 @@
if (rec_type == REC_TYPE_END)
break;
}
- vstring_free(buf);
+ buf = vstring_free(buf);
/*
* As of Postfix 2.7 the pickup daemon discards mail without recipients.
OpenPGP_0xB288B55FFF9C22C1.asc
Description: application/pgp-keys
OpenPGP_signature
Description: OpenPGP digital signature
