Filesystem quota on Roundcube (1.4)
To get “filesystem” quota working on Roundcube(1.4) Webmail we have to make few changes. If we have implemented filesystem quota on Squirrelmail or in any other webmail we will get it more easily.
Here this document we have used Postfix, Apache and Dovecot as IMAP service on CentOS 7.6. If you want to, you can choose any other IMAP service you can do so but you have to remember your IMAP should have this functionality à https://wiki2.dovecot.org/Quota/FS
Now
There can be 2 cases:-
1.
You have your user home directories on the same
machine mounted as a local partition or SAN mounted.
For example:
Filesystem Mounted on
/dev/sdax /userhomedirs
In
this case only configuring your Sudoers and Dovecot will do the job.
2.
You have mounted your user home directories via NFS.
For example:
Filesystem Mounted
on
10.0.1.xx:/userhomedirs /userhomedirs
In
this case along with Sudoers and Dovecot we have to modify functions of
Roundcube also.
To
implement filesystem quota on Roundcube we have to configure/modify three
things.
1.
Sudoers entry to run quota command.
2.
Dovecot to activate the quota showing function in
Roundcube.
3.
Roundcube function modification to display the
filesystem quota.
Let’s
begin with sudoers:-
We
will insert the following line at the very last of /etc/sudoers file
-------------------------------
apache ALL=
PASSWD:ALL, NOPASSWD: /usr/bin/quota -v *, /bin/echo
-------------------------------
This will enable apache to run quota command as root, which will be very much needed.
Now Dovecot:-
In
dovecot.conf we have to insert the following at proper places
-------------------------------
mail_plugins
= " quota imap_quota"
##
## Plugin
settings
##
plugin {
quota = fs:User quota:user
}
-------------------------------
This
will read the filesystem quota and forward it to Rouncube but it will not do so
in case the user home directories are mounted as NFS. For that we have to
modify Roundcube.
Now
Roundcube:-
Go
to the directory
# cd /var/www/html/webmail/program/lib/Roundcube
First
we backup the default file
# cp –p rcube_imap_generic.php
rcube_imap_generic.php-bak
Now open the file in any editor of your choice, here we use nano and search and replace the following function.
#nano rcube_imap_generic.php
Search for following function:-
-----------------------------------
public
function getQuota($mailbox = null)
{
if ($mailbox === null || $mailbox ===
'') {
$mailbox = 'INBOX';
}
// a0001 GETQUOTAROOT INBOX
// * QUOTAROOT INBOX user/sample
// * QUOTA user/sample (STORAGE 654
9765)
// a0001 OK Completed
list($code, $response) =
$this->execute('GETQUOTAROOT', array($this->escape($mailbox)), 0, '/^\* QUOTA
/i');
$result = false;
$min_free = PHP_INT_MAX;
$all = array();
if ($code == self::ERROR_OK) {
foreach (explode("\n",
$response) as $line) {
list(, , $quota_root) =
$this->tokenizeResponse($line, 3);
$quotas =
$this->tokenizeResponse($line, 1);
if (empty($quotas)) {
continue;
}
foreach (array_chunk($quotas,
3) as $quota) {
list($type, $used, $total)
= $quota;
$type = strtolower($type);
if ($type &&
$total) {
$all[$quota_root][$type]['used']
= intval($used);
$all[$quota_root][$type]['total']
= intval($total);
}
}
if
(empty($all[$quota_root]['storage'])) {
continue;
}
$used = $all[$quota_root]['storage']['used'];
$total =
$all[$quota_root]['storage']['total'];
$free = $total - $used;
// calculate lowest available
space from all storage quotas
if ($free < $min_free) {
$min_free = $free;
$result['used'] = $used;
$result['total'] = $total;
$result['percent'] =
min(100, round(($used/max(1,$total))*100));
$result['free'] = 100 - $result['percent'];
}
}
}
if (!empty($result)) {
$result['all'] = $all;
}
return $result;
}
-----------------------------------
And replace
with this new modified function:-
-----------------------------------
public
function getQuota($mailbox = null)
{
if ($mailbox === null || $mailbox ===
'') {
$mailbox = 'INBOX';
}
$rcmail = rcmail::get_instance();
$user = $rcmail->user;
$usern = rcube::Q($user->get_username());
$result = false;
$min_free = PHP_INT_MAX;
$all = array();
$used = exec("/usr/bin/sudo /usr/bin/quota -v
". $usern . "| /usr/bin/tail -n 1 | /usr/bin/awk '{print $1}'");
$total =
exec("/usr/bin/sudo /usr/bin/quota -v ". $usern . "|
/usr/bin/tail -n 1 | /usr/bin/awk '{print $2}'");
$free = $total - $used;
// calculate lowest available
space from all storage quotas
if ($free < $min_free) {
$min_free = $free;
$result['used'] = $used;
$result['total'] = $total;
$result['percent'] =
min(100, round(($used/max(1,$total))*100));
$result['free'] = 100 - $result['percent'];
}
if (!empty($result)) {
$result['all'] = $all;
}
return $result;
}
--------------------------------
Basically
we have to modify a function by which we will be able to see the filesystem/disk
quota in the Roundcube Webmail.
If
you are using earlier versions of Roundcube i.e. 1.3.9, you can take reference
from this document as the file and function is same there are only few changes.
Now
if you look closely
1.
The sudoers modification was previously also
necessary in squirrelmail or so, as it gives apache the authority to run quota
command as root. Which was very much required to get info about user quota’s.
2.
The dovecot (imap) modification is also needed as it
enables dovecot to read the filesystem quota and pass it on. If you are
familiar with “doveadm” we can also see quota through command line using
doveadm, after this modification.
3.
Roundcube is programmed in a way that it uses doveadm
command to get quota from the system. So, here we have identified its function
which is required to capture the user quota and modified it to run “quota”
command. You have to note that in the modified function we have used the
following lines:
------------------------
$used = exec("/usr/bin/sudo /usr/bin/quota -v
". $usern . "| /usr/bin/tail -n 1 | /usr/bin/awk '{print $1}'");
$total = exec("/usr/bin/sudo
/usr/bin/quota -v ". $usern . "| /usr/bin/tail -n 1 | /usr/bin/awk
'{print $2}'");
-----------------------
Here we are doing nothing but in
the variable we are inserting the filtered values which we get running the “quota”
command. You must also notice that we are inserting the values of $1 and $2 in
the variables, this might change to $2 and $3. You must run the command on a
terminal for a user and can check what values $1 and $2 are carrying and you
can modify accordingly.
If you want any help you can
comment below or can mail me at: raiashish20 [at] gmail.com