David Mehler
2012-Oct-19 20:11 UTC
[Dovecot] still having difficulties with per-user quotas
Hello,
I am trying to get per-user quotas working. My thanks to all who have
helped so far.
To recap I am running Dovecot 2.1 and Mysql where I've got my virtual
users. All virtual users are under the system user vmail with a UID
and GID of 5000. Looking over the wiki docs I've added a quota table
and got the dict service working, I am not having problems with
permissions or the login username and password, all that is working
fine. Here's my current doveconf -n output it is producing the
following debug error related to the userdb sql query:
# 2.1.10: /etc/dovecot/dovecot.conf
# XXX
dict {
quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext
}
first_valid_gid = 5000
first_valid_uid = 5000
hostname = XXX
last_valid_gid = 5000
last_valid_uid = 5000
mail_location = maildir:/home/vmail/%d/%n:LAYOUT=fs
mail_plugins = " quota"
namespace inbox {
inbox = yes
location prefix }
passdb {
args = /etc/dovecot/dovecot-sql.conf.ext
driver = sql
}
plugin {
quota = dict:User quota::proxy::quota
quota_rule = *:storage=1G
quota_rule2 = Trash:storage=+100M
quota_warning = storage=95%% quota-warning 95 %u
quota_warning2 = storage=80%% quota-warning 80 %u
}
protocols = imap
service auth {
unix_listener /var/spool/postfix/private/auth {
group = postfix
mode = 0660
user = postfix
}
unix_listener auth-userdb {
mode = 0600
user = vmail
}
}
service dict {
unix_listener dict {
mode = 0600
user = vmail
}
}
service imap-login {
inet_listener imap {
address = 127.0.0.1 ::1
}
inet_listener imaps {
address = xxx xxxx
ssl = yes
}
}
service quota-warning {
executable = script /usr/local/bin/quota-warning.sh
user = vmail
}
ssl_cert = </etc/ssl/certs/server.crt
ssl_key = </etc/ssl/private/server.key
userdb {
args = /etc/dovecot/dovecot-sql.conf.ext
driver = sql
}
protocol imap {
mail_plugins = " quota imap_quota"
}
Oct 19 15:23:52 auth-worker(29279): Info:
mysql(/var/run/mysqld/mysqld.sock): Connected to database mail
Oct 19 15:23:52 auth-worker(29279): Debug: sql(xxx,::1): query: SELECT
user as user, password FROM virtual_users WHERE user='xxx at domain';
Oct 19 15:23:52 auth: Debug: client passdb out: OK 1 user=xxx
Oct 19 15:23:52 auth: Debug: master in:
REQUEST 3523346433 29276 1 f5cd16e3f5e078c28d850749e42c86cc
Oct 19 15:23:52 auth-worker(29279): Debug: sql(xxx,::1): SELECT
concat('*:storage=', bytes, 'M') as quota_rule FROM quota WHERE
username='xxx';
Oct 19 15:23:52 auth: Debug: master userdb out:
USER 3523346433 xxx quota_rule=*:storage=368485M
Oct 19 15:23:52 imap-login: Info: Login: user=<xxx>, method=PLAIN,
rip=::1, lip=::1, mpid=29282, secured,
session=</xKpcW7MFgAAAAAAAAAAAAAAAAAAAAAB>
Oct 19 15:23:52 imap(xxx): Error: user xxx: Couldn't drop privileges:
User is missing UID (see mail_uid setting)
Oct 19 15:23:52 imap(xxx): Error: Internal error occurred. Refer to
server log for more information.
I am wanting a majority of my users to have the global 1GB quota, but
the users in the quota table to have given quotas. Here's what the
virtual_users and quota tables look like:
mysql> describe virtual_users;
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| domain_id | int(11) | NO | MUL | NULL | |
| user | varchar(40) | NO | | NULL | |
| password | varchar(128) | NO | | NULL | |
+-----------+--------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> describe quota;
+----------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+--------------+------+-----+---------+-------+
| username | varchar(100) | NO | PRI | NULL | |
| bytes | bigint(20) | NO | | 0 | |
| messages | int(11) | NO | | 0 | |
+----------+--------------+------+-----+---------+-------+
3 rows in set (0.00 sec)
I'd appreciate any help.
Thanks.
Dave.
Daniel Parthey
2012-Oct-20 12:47 UTC
[Dovecot] still having difficulties with per-user quotas
David Mehler wrote:> Oct 19 15:23:52 imap(xxx): Error: user xxx: Couldn't drop privileges: User is missing UID (see mail_uid setting)Set the following options in your dovecot.conf: mail_uid = vmail mail_gid = vmail Also see section "Mail users" at http://wiki2.dovecot.org/UserIds Regards Daniel -- https://plus.google.com/103021802792276734820
Daniel Parthey
2012-Oct-20 20:04 UTC
[Dovecot] still having difficulties with per-user quotas
David Mehler wrote:> Thanks for your reply. So with the extending of the query to return a > default quota rule, do you have an example of that by the way, does > that mean I only have to put the overrided users in the quota table?Assuming that quota values are in the dovecot_users table... # passdb with userdb prefetch and default quota of 1024M for quota=0 rows # The userdb_ prefix is for prefetch userdb entries in password_query password_query = SELECT username AS user, \ password AS password, \ home AS userdb_home, \ uid AS userdb_uid, \ gid AS userdb_gid, \ CASE quota \ WHEN 0 \ THEN '*:bytes=1024M:messages=0' \ ELSE \ CONCAT('*:bytes=', CAST(quota AS CHAR), 'M:messages=', CAST(quota_message AS CHAR)) \ END AS `userdb_quota_rule` \ FROM dovecot_users \ WHERE username='%u'; # user_query with default quota of 1024M for quota=0 rows user_query = SELECT username AS user, \ home AS home, \ uid AS uid, \ gid as gid, \ CASE quota \ WHEN 0 \ THEN '*:bytes=1024M:messages=0' \ ELSE \ CONCAT('*:bytes=', CAST(quota AS CHAR), 'M:messages=', CAST(quota_message AS CHAR)) \ END AS `quota_rule` \ FROM dovecot_users \ WHERE username='%u'; Your user_query needs to return a row if the user exists, otherwise dovecot will assume that the user does not exist and the mail or user will be rejected. Regards Daniel -- https://plus.google.com/103021802792276734820
Daniel Parthey
2012-Oct-21 20:49 UTC
[Dovecot] still having difficulties with per-user quotas
Hi Dave, David Mehler wrote:> Thanks for all your help so far. I have per-user quotas now working, I > had to also alter my dict config file as well. I am having two > outstanding issues, actually one outstanding issue and one question. > > Here's the question, given that the userdb sql query returns a default > quota entry for rows of zero in quota and quota_messages is the > default quota section needed in 90-quota.conf? > > plugin { > quota_rule = *:storage=1G > quota_rule2 = Trash:storage=+100M > }You need quota_rule2 to give the user some additional space in the Trash folder if he/she wants to delete messages when over quota. The dict is also needed for quota lookup from the database. The only thing which might be omitted is the global quota_rule since it is returned by the userdb/passwd in any case, but I'm not sure what happens if you only configure a "quota_rule2" without configuring a "quota_rule".> My outstanding issue is whenever I as the root mysql user update a > user's quota the other user also gets an update, I noticed with one > the messages column on the other user went from 0 to 2, another time > the quota value went up from 0 to 3500 it seems random.You should not be accounting the actual mailbox usage in the same virtual_users table as the quota is read from. Use *different* column or table name in your dict file where dovecot may write the current storage/message count.> dovecot-dict-sql.conf.ext > > map { > pattern = priv/quota/storage > table = virtual_users > username_field = user > value_field = quotavalue_field should be current_quota_storage (writable column)> } > map { > pattern = priv/quota/messages > table = virtual_users > username_field = user > value_field = quota_messagesvalue_field should be current_quota_messages (writable column)> I'd like to know why these columns are updating.Dovecot stores the current storage and mailcount in there. These columns should be different from the columns defining the maximum limit. Regards Daniel
Daniel Parthey
2012-Oct-21 22:22 UTC
[Dovecot] still having difficulties with per-user quotas
David Mehler wrote:> Thanks, so if I understand what your saying the reason I'm getting the > column update issues is Dovecot is reading from and writing to the > quota and quota_messages columns in my virtual_users table? > > My database user I believe only has select permissions on that table. > > So, I either need another table and to adjust my dovecot-dict.sql file > for that table, that's where Dovecot will write to, or two more > columns in the virtual_users table? > > Which way do you recommend?I would recommend to create a new table for dovecot_usage where dovecot is granted write permission. Regards Daniel