summaryrefslogtreecommitdiffstats
path: root/doc/wiki/Authentication.MasterUsers.txt
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:51:24 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 09:51:24 +0000
commitf7548d6d28c313cf80e6f3ef89aed16a19815df1 (patch)
treea3f6f2a3f247293bee59ecd28e8cd8ceb6ca064a /doc/wiki/Authentication.MasterUsers.txt
parentInitial commit. (diff)
downloaddovecot-f7548d6d28c313cf80e6f3ef89aed16a19815df1.tar.xz
dovecot-f7548d6d28c313cf80e6f3ef89aed16a19815df1.zip
Adding upstream version 1:2.3.19.1+dfsg1.upstream/1%2.3.19.1+dfsg1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'doc/wiki/Authentication.MasterUsers.txt')
-rw-r--r--doc/wiki/Authentication.MasterUsers.txt294
1 files changed, 294 insertions, 0 deletions
diff --git a/doc/wiki/Authentication.MasterUsers.txt b/doc/wiki/Authentication.MasterUsers.txt
new file mode 100644
index 0000000..2374cf7
--- /dev/null
+++ b/doc/wiki/Authentication.MasterUsers.txt
@@ -0,0 +1,294 @@
+Master users/passwords
+======================
+
+It's possible to configure master users who are able to log in as other users.
+It's also possible to directly log in as any user using a master password.
+
+Master users
+------------
+
+There are two ways for master users to log in as other users:
+
+ 1. Give the login username in the <SASL mechanism's>
+ [Authentication.Mechanisms.txt] authorization ID field.
+ 2. Specify both the master username and the login username in the same
+ username field. The usernames are separated by a string configured by the
+ 'auth_master_user_separator' setting. UW-IMAP uses "*" as the separator, so
+ that could be a good choice. Using "*" as the separator, the master user
+ would log in as "login_user*master_user".
+
+Master users are configured by adding a new <passdb> [PasswordDatabase.txt]
+with 'master=yes' setting. The users in the master passdb cannot log in as
+themselves, only as other people. That means they don't need to exist in the
+<userdb> [UserDatabase.txt], because the userdb lookup is done only for the
+user they're logging in as.
+
+You should also add the 'pass=yes' setting to the master passdb if possible. It
+means that Dovecot verifies that the login user really exists before allowing
+the master user to log in. Without the setting if a nonexistent login username
+is given, depending on the configuration, it could either return an internal
+login error (the userdb lookup failed) or create a whole new user (with eg.
+<static userdb> [UserDatabase.Static.txt]). 'pass=yes' doesn't work with PAM or
+LDAP with 'auth_bind=yes', because both of them require knowing the user's
+password.
+
+'pass=yes' is especially useful with a <Checkpassword>
+[PasswordDatabase.CheckPassword.txt] passdb because the script gets both the
+login and the master username as environment variables. Other passdbs see only
+the login username in '%u'. In the future there will probably be another
+setting to make the user verification to be done from userdb.
+
+If you want master users to be able to log in as themselves, you'll need to
+either add the user to the normal passdb or add the passdb to 'dovecot.conf'
+twice, with and without 'master=yes'. Note that if the passdbs point to
+different locations, the user can have a different password when logging in as
+other users than when logging in as himself. This is a good idea since it can
+avoid accidentally logging in as someone else.
+
+Usually it's better to have only a few special master users that are used
+*only* to log in as other people. One example could be a special "spam" master
+user that trains the users' spam filters by reading the messages from the
+user's spam mailbox.
+
+ACLs
+----
+
+If <ACL.txt> plugin is enabled, the Master user is still subject to ACLs just
+like any other user, which means that by default the master user has no access
+to any mailboxes of the user. The options for handling this are:
+
+ 1. Adding a global <ACL.txt> for the master user. You can create a "default
+ ACL", that applies to all mailboxes. See example below.
+ 2. Set 'plugin { acl_user=%u } ' This preserves the master_user for other
+ purposes (e.g. %{master_user} variable).
+ 3. Set 'plugin { master_user=%u } ' This fully hides that master user login is
+ being used.
+
+Example configuration
+---------------------
+
+---%<-------------------------------------------------------------------------
+auth_master_user_separator = *
+passdb {
+ driver = passwd-file
+ args = /etc/dovecot/passwd.masterusers
+ master = yes
+ pass = yes
+}
+passdb {
+ driver = shadow
+}
+userdb {
+ driver = passwd
+}
+---%<-------------------------------------------------------------------------
+
+To grant the masteruser access to all Mailboxes, the 'dovecot-acl' file can
+contain:
+
+---%<-------------------------------------------------------------------------
+* user=masteruser lr
+---%<-------------------------------------------------------------------------
+
+Where the 'passwd.masterusers' file would contain the master usernames and
+passwords:
+
+---%<-------------------------------------------------------------------------
+admin:{SHA1}nU4eI71bcnBGqeO0t9tXvY1u5oQ=
+admin2:{SHA1}i+UhJqb95FCnFio2UdWJu1HpV50=
+---%<-------------------------------------------------------------------------
+
+One way to create this master file is to use the htaccess program as follows:
+
+---%<-------------------------------------------------------------------------
+htpasswd -b -c -s passwd.masterusers user password
+---%<-------------------------------------------------------------------------
+
+SQL Example
+-----------
+
+The master passdb doesn't have to be passwd-file, it could be an SQL query as
+well:
+
+---%<-------------------------------------------------------------------------
+auth_master_user_separator = *
+passdb {
+ driver = sql
+ args = /etc/dovecot/dovecot-sql-master.conf.ext
+ master = yes
+ pass = yes
+}
+passdb {
+ driver = sql
+ args = /etc/dovecot/dovecot-sql.conf.ext
+}
+userdb {
+ driver = sql
+ args = /etc/dovecot/dovecot-sql.conf.ext
+}
+}
+---%<-------------------------------------------------------------------------
+
+'dovecot-sql-master.conf.ext' would contain all the normal connection settings
+and a 'password_query':
+
+---%<-------------------------------------------------------------------------
+password_query = SELECT password FROM users WHERE userid = '%u' and master_user
+= true
+---%<-------------------------------------------------------------------------
+
+Testing
+-------
+
+---%<-------------------------------------------------------------------------
+# telnet localhost 143
+* OK Dovecot ready.
+1 login loginuser*masteruser masterpass
+1 OK Logged in.
+---%<-------------------------------------------------------------------------
+
+If you had any problems, set 'auth_debug=yes' and look at the logs.
+
+Master passwords
+----------------
+
+You can configure a passdb which first performs authentication using the master
+password. Then it continues to the primary passdb to verify that the user
+exists and get other extra fields.
+
+---%<-------------------------------------------------------------------------
+# master password passdb
+passdb {
+ driver = static
+ default_fields = password=master-password
+ result_success = continue
+}
+# primary passdb
+passdb {
+ driver = pam
+}
+---%<-------------------------------------------------------------------------
+
+Advanced SQL Examples
+---------------------
+
+In these example we will create 3 kinds of master users. The first will be
+users who can read all email for all domains. The next example will be users
+who can read all email for their domain only. The third example will be users
+who can read email of domains listed in a separate ownership table. We will use
+MySQL and create 2 tables with the following structure.
+
+---%<-------------------------------------------------------------------------
+CREATE TABLE `users` (
+ `uid` int(4) NOT NULL AUTO_INCREMENT,
+ `user_name` varchar(80) NOT NULL,
+ `domain_name` varchar(80) NOT NULL,
+ `password` varchar(60) DEFAULT NULL,
+ `last_login` datetime DEFAULT NULL,
+ `masteradmin` tinyint(1) NOT NULL DEFAULT '0',
+ `owns_domain` tinyint(1) NOT NULL DEFAULT '0',
+ UNIQUE KEY `emaillookup` (`domain_name`,`user_name`),
+ UNIQUE KEY `uid` (`uid`)
+) ENGINE=MyISAM AUTO_INCREMENT=995 DEFAULT CHARSET=latin
+
+CREATE TABLE `ownership` (
+ `login_id` varchar(128) NOT NULL,
+ `owned_object` varchar(128) NOT NULL,
+ UNIQUE KEY `login_id_full` (`login_id`,`owned_object`),
+ KEY `login_id` (`login_id`),
+ KEY `owned_object` (`owned_object`),
+ KEY `login_id_index` (`login_id`),
+ KEY `owned_object_index` (`owned_object`)
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+---%<-------------------------------------------------------------------------
+
+The dovecot.conf file for all 3 master user configurations will be as follows:
+
+---%<-------------------------------------------------------------------------
+passdb {
+ driver = sql
+ args = /etc/dovecot/ownership-sql.conf
+ master = yes
+ pass = yes
+}
+
+passdb {
+ driver = sql
+ args = /etc/dovecot/domain-owner-sql.conf
+ master = yes
+ pass = yes
+}
+
+passdb {
+ driver = sql
+ args = /etc/dovecot/masteradmin-sql.conf
+ master = yes
+ pass = yes
+}
+passdb {
+ args = /etc/dovecot/sql.conf
+ driver = sql
+}
+---%<-------------------------------------------------------------------------
+
+Before we get into the master user tricks, we start with normal email
+authentication. The query for that is as follows:
+
+---%<-------------------------------------------------------------------------
+password_query = SELECT user_name, domain_name, password FROM users WHERE
+user_name = '%n' AND domain_name = '%d'
+---%<-------------------------------------------------------------------------
+
+In this first example master admin suppose you want to allow a few people to be
+master users over all domains. These users will have the "masteradmin" field
+set to 1. The query would be:
+
+---%<-------------------------------------------------------------------------
+password_query = SELECT user_name, domain_name, password FROM users WHERE
+user_name = '%n' AND domain_name = '%d' AND masteradmin='1'
+---%<-------------------------------------------------------------------------
+
+In the second example suppose you are hosting multiple domains and you want to
+allow a few users to become master users of their domain only.
+
+Your query would be as follows:
+
+---%<-------------------------------------------------------------------------
+password_query = SELECT user_name, domain_name, password FROM users WHERE
+user_name = '%n' \
+AND domain_name = '%d' AND owns_domain='1' AND '%d'='%{login_domain}'
+---%<-------------------------------------------------------------------------
+
+This will allow you to log in using the following to read Joe's email if
+master@dovecot.org is flagged as the domain_owner.
+
+---%<-------------------------------------------------------------------------
+joe@dovecot.org*master@dovecot.org
+---%<-------------------------------------------------------------------------
+
+In this third example we have a table of owners. There are a list of pairs
+between owner email addresses and domains that are owned. That way if a person
+controls a lot of domains then they can view all the users in all the domains
+they control. The query would be as follows:
+
+---%<-------------------------------------------------------------------------
+password_query = SELECT user_name, domain_name, password FROM users, ownership
+WHERE \
+user_name = '%n' AND domain_name = '%d' AND login_id='%u' AND
+owned_object='%{login_domain}'
+---%<-------------------------------------------------------------------------
+
+If you really want to get tricky and efficient you can combine all 3 queries
+into one giant query that does everything.
+
+---%<-------------------------------------------------------------------------
+password_query = SELECT user_name, domain_name, password FROM users, ownership
+WHERE \
+user_name = '%n' AND domain_name = '%d' AND ( \
+(masteradmin='1') OR \
+(owns_domain='1' AND '%d'='%{login_domain}') OR \
+(login_id='%u' and owned_object='%{login_domain}')) \
+group by uid
+---%<-------------------------------------------------------------------------
+
+(This file was created from the wiki on 2019-06-19 12:42)