Version 1.46.0

Released: 2014-09-14

add roundcube db data to backup/restore new


please update to 1.46.2+ to get the fix for the following bug:

backup_roundcube.php has write error for php 5.3

Include roundcube email account database info in the DA backups.

Restore that data back into roundcube.

With per email backup/restore functionality, we'd likely switch to use RoundCube as the default webmail client, but lack of command line backup/restore prevents us from doing so.

Two new scripts:



They will be called by DA during the bacukp/restore process.

All variables are passed via environment (domain, username, xml_file)

The backup creates an xml file in the backup:


You can shut off the inclusion of the roundcube data by adding this option to the directadmin.conf:


The internal default is:


The restore will always restore the xml file if the xml file exists.

The roundcube xml file falls under the "E-Mail Data" checkbox.

It's contents include essentially everything you can see in Roundcube, contacts, contact groups, identities, and other miscellaneous settings.

Old Info, no longer applicable.

There are 2 or 3 "showstopper" issues with us adding RoundCube data to the backups

  1. Each update of roundcube changes major aspects of the database design. Often, entire tables are dropped, and converted into multiple new different tables.

This makes knowing what data to grab quite difficult, as it moves around for each version, so we'd need to make new backup/restore code for every version of roundcube (where changes are made). (Addition: The table formats seemed to have stabilized recently, but we cannot predict the future)

  1. The user_id values are unique to the database.. so an export one one sever with a specific uid value for an email may already be taken on the restore on the remote server.

This needs DA basically a) know where to get the data (see #1 above) and also b) store all of the data in it's own format, while maintaining all of the proper rows/fields.. but without the uid number.

c) Then the restore would then need to figure out a new id for the user, and reset all of the data in the correct place.

Any new changes/updates to the database with another RoundCube version would break this functionality, and a new DA version would be needed to handle it.

What would be nice (request to the RoundCube developers) would be a script where the email address is passed, which dumps all data (contacts, address books, identities, etc.) into a nice xml file, or something like that, where the only thing that is passed is the email address. And a similar restore script that can accept this backup file, and handle all of the uid inserts, regardless of what changes have been made to the DB.

Solution, if it gets implemented (no longer needed, now that we have the above scripts)

BFM ignore attempts on suspended accounts new

If a DirectAdmin User account, E-Mail or FTP account are suspended, any attempts on those accounts will be ignored by the brute force monitor if this option is enabled:


the internal default value is 1, so it's enabled by default.

The feature knows which service is used, based on the filter match from the brute_fitlers.list, so it can figure out where to check the data.

Namely one of:



or the password crypt from the system call to:

getspnam (FreeBSD: getpwnam)

After coding it, I noticed that Dovecot already accounts for this, so this featue is somewhat redundant/non-applicable for dovecot, as the logs for dovecot for a suspended account looks like this:

imap-login: Aborted login (user disabled)

while a failed password login on a non-suspended account looks like:

imap-login: Aborted login (auth failed, 1 attempts in 4 secs)

so the filter wouldn't pick up the case for the suspended account anyway...

But should you get an "auth failed" (possibly an older version of dovecot), then this feature would work normally for that case, and ignore the entry if suspended.

Aside from that, this will apply to the other areas:

sshd, exim, and proftpd/pure-ftpd.

You may need to use this option to use the !password method of suspension, rather than the domain.com_off suspension:

Global option where suspended domains still allow emails to arrive

pigz for parallel process backup new

Support for pigz, which is used instead of gzip with tar, so it can create backups faster using more cores.

Default internal directadmin.conf value is:


to enable pigz, it must be install, and added to:


and then set the directadmin.conf to the number of cores (CustomBuild will set this for you when pigz is installed)


for example, which would tell pigz to use 4 processes.

If you use a value of 1, there is really no point in using this at all.

CustomBuild 2.0 can install it for you:

cd /usr/local/directadmin/custombuild
./build update
./build pigz

custom config for nginx_proxy editing (SKINS) new

The "Custom httpd Config" tool previously only worked for httpd or nginx.

If you were running nignx_proxy, you could only edit the httpd.conf configs.

This change allowed for editing of the nginx.conf or the httpd.conf for the nginx_proxy setup.

To edit the nginx.conf, the "(nginx_proxy)" link will be next to the domain name on the CMD_CUSTOM_HTTPD page.



add this in the form:

<input type=hidden name=proxy value="|proxy|">

phpMyAdmin added to Brute Force Monitor (MANUAL CHANGE) new

BFM now has the ability to scan the PMA logs, but has a few conditions.

Note that CustomBuild 2.0 will apply this patch with a PMA install, so

with CB2, you'd need only run:

cd /usr/local/directadmin/custombuild
./build update
./build phpmyadmin

Else for CustomBuild 1.1/1.2:

  1. The following patch must be applied to phpMyAdmin:
cd /var/www/html/phpMyAdmin
mkdir -p log
chmod 770 log
chown webapps:apache log
patch -p0 < pma_auth_logging.patch

Note that CustomBuild 2.0 will apply this patch with a PMA install, so with CB2, you'd need only run:

cd /usr/local/directadmin/custombuild
./build update
./build phpmyadmin
  1. phpMyAdmin requires write access to disk, to write to:


for CB2, this is already the default, so no need to worry there.

This patch support both the default http auth type, but should also work with the cookie auth type, if you use that instead.

2 new lines have been added to the brute_filter.list:

phpmyadmin2=ip_after=ip='&ip_until='&text=status='not authenticated'&user_after=user='&user_until='

some sample log entries from the auth.log look like this:

Jul 10 22:26:37:: pma auth user='user_dbuser' status='not authenticated' ip=''
Jul 10 23:05:55:: pma auth user='user_dbuser' status='mysql-denied' ip=''

Allow javascript auto-logout to be cleared (SKINS) new

I've changed the setTimeout from:

setTimeout('log_me_out();', |SESSION_MINUTES|*60*1000);

to be:

var logout_timeout = setTimeout('log_me_out();', |SESSION_MINUTES|*60*1000);

This allows any custom skins or plugins to simply call the javascript function:

if (typeof logout_timeout != 'undefined') {

if the currently loaded page needs to prevent the auto-logout (if the page needs to be open a long time).

Just be sure to keep making regular connections to DA before the sessoin timeout actually hits on the server side, else it would be making unauthorized connections, and your IP will end up getting blacklisted.

XFS quotas new

XFS quota support in DirectAdmin.

The directadmin.conf variable must be enabled:


and DA restarted.

Ensure you have xfs quotas, with uquota,pquota enabled in your /etc/ftab:

Note that it's pquota, not gquota/groupquota.

pquota allows us to setup project quotas.

Domains quotas with XFS:

enabled by default (when use_xfs_quota=1) with:


So you only need to change xfs_on_domains if you don't want quotas to be enabled on the domains.

When domain xfs quotas are enabled, this will create a project called:

with the path /home/user/domains/

and the xfs system will limit the files uploaded to that location for any file ownership, including apache/root as per the limit specified by the User on that domain at:

User Level -> Domain Setup ->

This is useful for cases where:

  • the User has many domains, and does not want any one domain to use up too much space.

  • there are files uploaded under some different username, as the xfs domain quotas are enforced by path, not file ownership.

Translation files for email level password change, ftp, and vacation messages (LANG) new

New internal language file:


Allowing the translation of:




If you need to know exactly what message was generated in an API, a new variable:


will be output, which represents the same string number, as for the pass_change.txt.

This essentially acts like an error code, letting you know what happened, even if you can't read the language.

Ability to include special characters in random password generation (SKINS) new

New directadmin.conf option, this is the internal default:


set it to 1 if you want to have the random password generation include special characters, eg:

\`~!@#$%^&*()_-+=... etc..

basically, all ascii characters:


inclusive, but not 47 or 92 (forward and backwards slashes)

! through ~

This applies to both the javascripts generation, and the internal AJAX password generation.

When enabled, this will also change the difficult password enforcement script (if used) to require those characters.

The difficult_password.php script will have a new token:


so it can use that to decide if the enforce_shift_chars should be used.


This also required the resulting passwords to be displayed in an html encoded string, since some special characters must be encoded anyway.

This applies to email and database user creation/modification.



new function: function has_special_chars(pass)

in the random_pass function, change the "var chars" line, to these lines:

var chars = '';
for (i=33; i<=126; i++)
        if (i == 47) continue;
        if (i == 92) continue;
        chars = chars + String.fromCharCode(i);
var chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";

and add this just before "return pass":

if (!has_special_chars(pass))
        return random_pass();

SSL_TEMPLATE token for all apache/nginx templates new

Previously, there was no easy way for an if-then-else to determine if a current template uses SSL or not.

New token for all virtual_host2*.conf files and nginx_server*.conf files:


where 0 would be for non-SSL port 80, and 1 would be for SSL templates.

Per-User php-fpmXX.conf customization (SKINS) new

Ability for an Admin to edit the per-User php-fpmXX.conf files.

You can access the custom editing page via:

Admin Level -> Custom Httpd Config -> username (php-fpm 5.5)

where you'd like the php-fpm 5.5 link, to the right of the username. (5.5 will show whichever version of php is installed)

Note that it's a per-User config option, and not related to any specific domain.

If you have 2 php-fpm instances, 2 links will show up to the right of the username.

The templates currently have two tokens:



where 1 is at the top, 2 is at the bottom.

The editor will let you insert your own code on a per-domain basis...

Use CUSTOM1 to define tokens to be used in the template.

Use CUSTOM2 to add code to the bottom of the template.

possibly on a per-PHP-version basis, depending on what the interest is.


new file:


new line added to:



Removed HAVE_PHP1_FPM_OLD from templates (TEMPLATES) new

CustomBuild 2.0 now requires Apache 2.4.10 or newer.

This removes the need for the HAVE_PHP1_FPM_OLD tokens in the templates.

The tokens will still be there, and they'll still work, but the output from the templates if you're running an older Apache will be:

#Make sure you're running Apache 2.4.10 or newer.

as new Apache features are used for php-fpm.

This also removes the RewrietEngine, RewriteCond, RewriteRules as well, since a hostname redirect is no longer needed for webapps.

Ability to edit dns zone through Login-As even if User doesn't have access (SKINS) new

With the "Login As" feature, and Admin or Reseller now has the ability to edit the dns zone of a User, as long as that Reseller or Admin has dnscontrol access in their Reseller settings.

To avoid confusion, add this extra text above the table on the User DNS Control Page, so Resellers don't get confused as to why they can edit the zone, if the User option is disabled.




<span class="warning">DNS Control is disabled for this User. You can edit the zone because your master account has DNS Control.</span>


Also notify Resellers of their User\'s email overuage new

Currently only the User and an Admin are notified if a User sends too many emails.

This will also notif the Reseller (duplicates removed if Admin created the User)

Enabled by default:


Better backup tracking for User data new

More tracking log points for User data, allowing the admin to see in more detail where a backup is at.

For example, they'll know if DA is chewing away on a database, or copying email data, etc..

Include php script name is highest send count and ability to automatically chmod to 0 (TEMPLATES) new

On the "E-Mail Usage" page, a new field will be displayed in the first table, if enabled:

Sending Script

where the "Value" will be the path to the php script that has sent the most number of emails.

It will also include the line number of that script which called mail().

This is useful to more quickly track down a compromised account, to figure out which script is sending spam, or too much email.


The internal default for this feature is:


If you set this option to:


then the script will be chmod to 0. Option 2 may be changed in the future to work with BlockCracking, for fewer false positives.

However, as this type of action shouldn't be taken lightly, there are 2 other checks, set by default to:


where disable_php_script_at_limit_threshold is the percentage of total emails sent, of the hit limit, which must be exceeded by that script, in order to be chmod to 0.

As well, the option disable_php_script_at_limit_minimum is the minimum number of emails that script must send to be chmod to 0.

The minimum number is useful in the case where an account might have a limit of 1.. obviously, this wouldn't warrant the disabling of the script for sending 1 email.

So, for example

script.php sends 900 emails, and the limit is 1000.

The total number of emails leaving the account would have been 1000 (since the limit was triggered) but 900... aka 90% of the emails sent, were from the script.

  1. This passes the threshold of 80%.

  2. Also, 900 emails are more than 100 email, so it will also pass.

  3. For this scenario, if:


is set, then because 1, 2 and 3 all are true, script.php will be chmod to 0, and everyone notified.

If any one is not true, the script will not be chmod to 0.



added extra text for the script case, eg:

The top sending script was |TOP_PHP_SCRIPT|, at |TOP_PHP_SCRIPT_COUNT| emails, (|TOP_PHP_SCRIPT_PERCENT|%).|*endif|
|*if TOP_PHP_SCRIPT_PERCENT>DISABLE_PHP_SCRIPT_AT_LIMIT_THRESHOLD|Because the bulk of the emails have been sent by the script, please check it to confirm it has not been compromised.|*endif|

New available tokens are:

TOP_PHP_SCRIPT: name of the offending script, and line number of mail(), eg:


TOP_PHP_SCRIPT_COUNT: how many sends the script made
TOP_PHP_SCRIPT_PERCENT: percentage of all sends the script made
DISABLE_PHP_SCRIPT_AT_LIMIT_THRESHOLD: the directadmin.conf variable, see above.
DISABLE_PHP_SCRIPT_AT_LIMIT_MINIMUM: the directadmin.conf variable, see above.
SCRIPT_CHMOD_RESULT: text to let you know if the chmod was triggered, or attempted to be triggered.

If it's an empty string, "" then the criteria were not met. However if it's a string, the criteria were met.. and would either include the result/success, or an error as to why it didn't work (eg: link, ownership, doesn't exist, chmod error)

DNSSEC: DS records for subdomain delegation & User Level DNSSEC (SKINS) (TEMPLATES) new

DS records can now be added to the zone in the interface.

This is not for the normal DNSSEC zone signing (that's hidden in the signed zone)

The DS records in this context are for subdomain zone delegation.

If you create a value as a full domain, it's DS records need to go up the chain of trust.

The next link in the chain for a subdomain zone is not your domain registrar, it's your zone.

So, the solution to make pass the dnssec validation is to add the DS records from the zone, created with the signing,

and place them into the standard DS records in your zone (aka: this feature).

In the future, I may add a setting to automatically add the subdomain DS/NS values into the master domain zone.

We'll test out this functionality first, to ensure it works.

**** NOTE when you paste in the subdomain DS record into the zone

you must also create NS records for the subdomain in the zone. NS NS

where you'd specify the server that holds the zone. (the subdomain zone can exist on a delegated remote server if you need)

Without the NS records for the subdomain in the domain's zone, the domain will not be able to resign it's keys.

Reported that you only need to add the first DS record into higher-level chain (zone one level up).

For a, you'd use the first DS record, and add it to zone (along with the 2 NS records)

Remember: adding/removing values from a signed zone will try to automatically resign the zone.

To be sure, manually click the "Sign" button after setting up the DS and NS records in the zone.

Related forum thread:

The dnssec info will now be displayed in the User Level zone, if dnssec is enabled.

new directadmin.conf variable, and it's default value:


If this is changed to 1, then the "Generate Keys" and "Sign" buttons will be available for user by the User.

We may change the user_dnssec_control value to 1 in a future release (undecided)




added new form/line for the DS records.





nginx proxy to disable proxy_buffering by default (TEMPLATES) new

Nginx proxy to include proxy_buffering option.

Internal default for the directadmin.conf:


where 0 means the Apache server sends through Nginx, byte by byte, making the connection faster.

However, if you have many slow clients, setting:


will mean that Apache sends all data to Nginx, which stores it in a buffer, which can then disconnect from Apache to let it do other things.

The catch with 1 is that Nginx doesn't start to send all of the data until Apache has finished sending it to Nginx... meaning the first byte is not sent until Nginx receives the last byte from Apache.

In testing on a LAN with a phpinfo(); php file, average client completion time was 120ms with buffering, and and 90ms without buffering, so we've opted to disable the option by default.







added this line within the |*if HAVE_NGINX_PROXY="1"| section:

proxy_buffering |PROXY_BUFFERING|;

where |PROXY_BUFFERING| will be filled with on or off, depending on the directadmin.conf setting.

PHP-fpm: safemode: only main domain control open_basedir new

With CustomBuild 2.0 and php-fpm, the feature:

Admin Level -> PHP Safemode Config

where a User has multiple domains, if any one of the domains has safe-mode disabled, it would be disabled for the entire User, thus all the domains in:


This change is such that only the main domain will actually control the open_basedir value.

The interface will hide the checkboxes for non-default domains.

The ON/OFF tags for open basedir for these non-default domains will be an href, which, if clicked, will filter to show only that Username, so the required checkbox can be easily found.


Add the SpamAssassin Whitelist to the domain filter to also whitelist SPAM Filter (TEMPLATES) new

To prevent confusion, if you add a User to the whitelist in the SpamAssassin settings, DA will now add these email addresses to the file:



        $sender_address contains ""

so that if you've got any "SPAM Filter" words setup to block, the email willl be in the whitelist and won't block the email.





before anything else... meaning it will also whitelist your high-scoring spam.

CB2.0: Move htaccess/user.ini block to webapps.conf (TEMPLATES) new

Removed the code:

        location ~ /\\.ht
                deny all;

from the 4 nginx_server*.conf templates.

CB2 now adds it to:


to save duplicate code.

Also, it looks like this in the webapps.conf:

        location ~ /(\\.ht|\\.user\\.ini) {
                deny all;

so that it also blocks .user.ini files.

Give warning if package inode set between 1-200 new

We've seen a few cases where Reseller/Admins set a limit of 1 inode for a Reseller/User package... causing instant quota limits to be hit upon creation.

The wording of "quota limit reached" for as the system error string causes confusion, as they only look a their quota usage settings, rather than their inode settings.

When creating or changing a package, if the inode limits are set between 1 and 200, the package will still be saved, but a warning is given to the Admin/Reseller.

A typical inode limit can be anywhere from 5000-10000, but can vary greatly, higher or lower, depending on what your needs are.

Also prevent setting 0 bandwidth, 0 quota, or 0 inodes.

If you want unlimited, select unlimited.

Update session time on plugin calls fixed

The timestamp on a session file determines if a current session is active or not.

Only certain areas in DA, when browsed to, will update this time.

Connections to the plugins previously was not one of these areas.

This meant than if you sit idle on a page for a long time, and that page makes many calls to DA (ajax/json), then the session file timestamp is not being updated.

If left long enough (default: 60 minutes), the session would expire and the ajax requests are then considered unauthorized and the brute force count kicks in, eventually blocking that IP.

Simple fix is to touch the timestamp on all plugin calls.

Nginx to have included nginx_php.conf to fix proected directories (TEMPLATES) fixed

Because of the way nginx does it's location matches, any protected directories needed to have all php functionality appear again within that protected location.

This got infinitely messy to try and manage with the old template layout, so we killed two birds with one stone by introducing:


Anywhere the php setup was needed in the user nginx.conf (which was many places), that php setup has simply been replaced with:


which adds this code into it:

include /usr/local/directadmin/data/users/username/nginx_php.conf;

but in the event the php selector is swapping the php versions (which is a on per-domain basis), DA will fill the NGINX_PHP_CONF with the actual nginx code, rather than the include.

The included file is on a per-DA-User basis, hence wouldn't work for the php selector.

New template:


as usual, you can copy it to:


if you need to make changes.

The Admin Level -> Custom Httpd Config area does not have effect on the tokens in the nginx_php.conf.

They're loaded fresh.. however, there are not really any interesting tokens in that file anyway.. mainly just HAVE_PHP1_FPM and USER,

so unless anyone has any urgent need for custom editing of this on a per-User basis, for now customizations will be via template only.

(not to mention it's a per-User file, not a per-domain file)

Changes have been made to essentially all nginx_*.conf templates, in terms of using the "include" line, mentioned above.

Php selector for CB2 mod_php/CLI and suphp (TEMPLATES) fixed

Changes to the apache templates now allow for mod_php/CLI and suPHP to be properly selected with the php selector.

The 4 main virtual_host2* templates consist of the addition of extra code (below) within the <Directory> section.

Note that the HAVE* tokens for CLI/SUPHP will not be filled if no swapping has taken place.

So this only applies to when the php selector is being used, and php modes are being changed.

|*if HAVE_PHP1_CLI="1"|
<FilesMatch "\\.php$">
AddHandler application/x-httpd-php .php
|*if HAVE_PHP2_CLI="1"|
<FilesMatch "\\.php|PHP2_RELEASE|$">
AddHandler application/x-httpd-php .php|PHP2_RELEASE|
|*if HAVE_PHP1_SUPHP="1"|
<FilesMatch "\\.php$">
AddHandler x-httpd-php|PHP1_RELEASE| .php
|*if HAVE_PHP2_SUPHP="1"|
<FilesMatch \\.php|PHP2_RELEASE|$>
AddHandler x-httpd-php|PHP2_RELEASE| .php|PHP2_RELEASE|

Restores to/from different IPv4/IPv6 types cause duplicate dns records (IMPORTANT RESTORE CHANGES) fixed

Cleanup of the restore/merge code for the dns.

  1. If a User account is just created, then the default A and AAAA "local" values are ignored, and only the A and AAAA from the backups are used.

This means that if you need to add special values via custom dns_a.conf or dns_aaaa.conf files, they'll be ignored for restores.

  1. If a backup was IPv6, but it's restored to IPv4, it caused duplicates for the incorrect type: eg, the old IPv6 IPs were still present, as well as the new IPv4 values

  2. Proper IPv6 restore added in that values are now checked and properly swapped. Before this, it caused both the old and new IPv6 values to be present.

Related thread:

Reduce permissions on system files (SECURITY) fixed




from 644 to 640.

This may affect Uebimiau, which is no long support anyway.

These files will change to 640 once they're rewritten by adding, removing or renaming a domain.



to be set to 710

This is set to various values in several areas, which should now be unified to 710.

This will be set if you run the ./ script for logs.



to be set to 710.

./build rewrite_confs

will reset this.

New installs will have:


set to 710

You'll notice I chose 710 instead of 700.

This will allow you, if you need, to set a group to this directory to allow reading.

DA won't change the group on you, but will set it to 710.

Duplicate AuthType Basic in .htaccess fixed

Relating to this previous fix:

Apache 2.4 disabling protected directory causes internal server error

caused 2 AuthType entries to be added when a directory protection was enabled.

Fix includes:

  1. Ensure only 1 is added

  2. Delete both, if present when disabling protection.

Ensure fpm/fastcgi/suphp are disabled with domain php setting fixed

When php was disabled at the domain level, php was only disabled for CLI/mod_php.

This will ensure all PHP token types are set to 0.

SHA-256 requests were generating self-signed certificates & removed 1024 bit keys (SKINS) fixed

Previous code to create a request was incorrect:

openssl req -new -x509 -sha256 -key newkey.key -config ssl.conf -out new.csr

changed to be:

openssl req -new -nodes -sha256 -key newkey.key -config ssl.conf -out new.csr

Also the 1024 bit key creation has been removed as an option.



remove the <option>1024</option>

A DA restore will now respect any manually changed private_html links.

Previously, DA would only notice that it was a link (exepecting it to be pointed to ./public_html), and as such would set it to ./public_html upon restore.

However, some people point the private_html folder elsewhere, so this change will remember, and respect it.

Changes to the backup are:

  • backup/


is now an option, where 2 means custom, 1 plain old ./public_html, and 0, a directory.

If 2 is set, then this is also added:


which is set upon restore.

DNSKEY keys may have different format for CentOS 5 fixed

Newer OSs will have date ID and key info in the zsk/ksk keys, but CentOS 5 may only have the single DNSKEY line.

Fix to allow this single line, but DA will generate "unknown" for the missing values.

Also allows smaller keys.. DA previously only allowed keys larger than 300 bytes. Chanegd to 150 bytes.

Tag: dnssec

Nginx password protected directories and redirects (TEMPLATES) fixed

Nginx now supports redirects.

New template:


Also changed:

  1. With Nginx, both the password protected directories and redirect use a "location /" section.

There cannot be two, so it was decided that if you've got duplicates, the password protected directory would win, and the redirect would be skipped.

If you do need a password protected redirect, then just password protect a directory, and do the redirect with an index.php.

  1. The order of the locations matters.

It was discovered that the / location would trump another /sub location.

As such, both the redirects and password protected directories are going to be sorted (within their types), from the longest location path, to the shortest.

So if you have /, it will be last, for that type (type being password protection vs redirects: they don't be mixed.. it's all sorted redirects listed first, then all sorted password protection)

  1. Password protected directories on Subdomains:

If you protect the folder:


for, the location actually need to be:

location /

and not /subdomain.

The nginx.conf writing code will figure that out and only include location paths that start with /subdomain/ or that are exactly /subdomain, and will swap them to be /.

Eg: ".../public_html/subdomain/folder" becomes "location /folder/".

Note that the protection will still exist as "location /subdomain/folder/" within the server entry for the main domain, for access.

  1. Because the FileManager is chrooted, the rewrite of the nginx.conf cannot happen right away.

A rewrite request is sent to the task.queue before the chroot, and then the protection list files are written immediately after.

Possible race condition, but unlikely that the dataskq would get the task.queue and run it before the list files are written (dataskq checks services before processing requests)

In any case, it means that the rewrite may happen up to 1 minute later.. and the restart, possibly 1 minute after that... so 2 minutes for password protection to show up.

Be patient, as it's not immediate like apache, as that used realtime .htaccess files. Nginx requires config rewrites and a full Nginx service reload.

Duplicate use of internal text in one string caused segfault fixed

recent code changes exposed an old InternalText class bug, where doing something like this:

printf("%s %s", hc.t(75, "Domain Pointer on"), hc.t(75, "Domain Pointer on"));

would cause a segfault, because the 2nd instance of the internal text usage deletes the first one, causing any use of the first %s to be unpredictable.

Fix was to count the number of varables.. and if there are zero (eg: the above has zero %s characters), don't reset the array id 75.. since it's already there, and will never change anyway.

I've also optimized it by doing (this is just an example optimization, not actually used as shown):

char *str = hc.t(75, "Domain Pointer on");

printf("%s %s", str, str);

as, in a loop, it would mean far fewer index look-ups on the InternalText arrays.

It's also decided that using 2 calls of the same text ID in one call is bad practice, so I'll swap them out whenever found (not to mention not as efficient as they could be)

Workaround for Chrome autofill (SKINS) fixed

Chrome is rather persistent about auto-filling your fields for you.

This is usually great is some cases, but is immensely annoying when you're working in an interface that creates and manages user accounts, with passwords.

Chrome also loves to ignore:

<form autocomplete="off">
<input autocomplete="off">

which boggles my mind why they'd do that.

Solution found here:

Credit: Mike Nelson

Where this code is added to the beginning of the form.

Chrome fills it in, thinking it did it's job, but the values filled in are hidden.

<!-- fake fields are a workaround for chrome autofill getting the wrong fields -->
<input style="display:none" type="text" name="fakeusernameremembered"/>
<input style="display:none" type="password" name="fakepasswordremembered"/>


Affected pages in the enhanced skin:











Added the following token:


right after the beginning of <form ..>

files_user.conf, added:


new file to fill the token:


with the code from above.

Reseller to be limited when editing own data without overselling fixed

Previously, a Reseller could set their own User data to any values they wanted via the "Modify your own User data"

The Reseller's personal User allocations are not part of the total allocation count, because the Reseller's user.conf values are defaulted to the same as the reseller.conf limits, so the allocation would be maxed out the moment the Reseller is created. So the allocation count does not include his own User data.

However, the issue is that the allocation check for the Reseller's own User data was skipped, because it wasn't part of the count anyway.

But.. if overselling is off, it's reasonable to assume the Admin really doesn't want the Reseller's User data to be a value higher than this, a a minimum.

So this fix will ensure that, if overselling is not enabled, the Reseller cannot set their own User Level limits to a value higher than the Reseller limits.

So the "actual" allocated max for a reseller is double his max... (again, because his own user allocation is not counted)...

but this at least puts a limit of wht he can give himself.

Reseller restore without overselling and without unlimited domains hits domain limit fixed

If a Reseller has the followin:

  • Overselling disabled

  • Max Domains is not unlimited

a bug existed where upon restoring a User, the Reseller usage/limit check would always throw the error:

Cannot restore, it would exceed your Resellers limit

were the bug was that the check should have been comparing the vdomains variable from the reseller.usage vs reseller.conf, but it was taking both the used and max variables from the reseller.conf, hence comparison was always true, hence the error always happened.

It looks like this bug has been around for a long time, but only recently reported (fix was fairly easy, to change either of the above conditions to bypass the error)

but now.. it's fixed.

Typo in reseller_run_as fixed

Relating to feature:

Plugins to have the ability to run as a specified User

Typo in plugin.conf:


will be changed to:



Last Updated: