Version 1.48.1

Released: 2015-06-22

Add all remaining mysql user privileges options (SKINS)(LANG) new

Remaining User Privilege options added to MySQL User privileges section.

Default directadmin.conf option:


can be set to 0 to hide the options below.

If missing, they'll still be set to "Y" by default.

If you have MySQL 5.1.6, then the token:


will be set to 2.

Setting the database_extended_user_privileges directadmin.conf option to 2 will have no effect on this, only the mysqld version.

Add trigger checkbox to mysql user privileges page if mysql version >= 5.1.6.


The TRIGGER privilege enables trigger operations. You must have this privilege for a table to create, drop, or execute triggers for that table. This privilege was added in MySQL 5.1.6




<tr><td class=list align=right>Show View</td><td class=list>|SHOW_VIEW_PRIV|</td></tr>
<tr><td class=list align=right>Create Routine</td><td class=list>|CREATE_ROUTINE_PRIV|</td></tr>
<tr><td class=list align=right>Alter Routine</td><td class=list>|ALTER_ROUTINE_PRIV|</td></tr>
<tr><td class=list align=right>Execute</td><td class=list>|EXECUTE_PRIV|</td></tr>
<tr><td class=list align=right>Create View</td><td class=list>|CREATE_VIEW_PRIV|</td></tr>
<tr><td class=list align=right>Event</td><td class=list>|EVENT_PRIV|</td></tr>
<tr><td class=list align=right>Trigger</td><td class=list>|TRIGGER_PRIV|</td></tr>




Read optimization for ConfigFile class when only single item needed new

The readFile function in the ConfigFile class now has an extra option where the request can specify the index/name it wants.

If this index is set, during the read, only the matching index will be added to the array, saving a huge amount of memory and sorting.

Main area this will speed things up would be for "does this value exist in the file", such as checks for existing email accounts.

Previously, it would read the whole file, sort it, then do a binary search to find the index, to determine if it exists.

This will now return an array with 1 value, making the sorting and binary search instant.

Prevent Reseller from unsuspending User if Admin suspended it (LANG) new

Often times, the Admin of the server will be monitoring and will suspend User accounts, where needed.

Previously, the Reseller of the account could simply unsuspend this suspended User, contrary to the wishes of the Admin.

New feature, where if an Admin suspends a User account, where the "creator" in the user.conf does not match the name of the Admin caller,

then DA will add the following to the suspend User's user.conf file:


where "admin" can be some other Admin, if you have a different account.

Then, when a Reseller tries to unsuspend the account, if suspended_by_admin is present, the unsuspend will be blocked.

If any Admin tries to unsuspend, it will be allowed regardless of the setting.

Any unsuspend successes will clear the suspended_by_admin value from the user.conf.


new entry in:


24=Account %s was suspended by an Admin and you only have Reseller access. You cannot unsuspend this account.

@reboot for User cronjobs (SKINS) new

Users can now specify the @reboot option for cronjobs.

A new checkbox will be displayed at the top right of the "Add new cron" table.

When checked, the time input fields will be hidden, leaving only the Command.

Edit can be used to edit the command, but cannot switch between @reboot and time types.

If you need to change @reboot to cron times, then delete the whole cron and create a new one.



  1. new javascript function:
function set_cron_display()
    var set_display = '';
    if (document.getElementById('reboot').checked)
        var set_display = 'none';

    document.getElementById('minute_tr').style.display = set_display;
    document.getElementById('hour_tr').style.display = set_display;
    document.getElementById('day_of_month_tr').style.display = set_display;
    document.getElementById('month_tr').style.display = set_display;
    document.getElementById('day_of_week_tr').style.display = set_display;
  1. The <tr> values for the cron times need t have the above respective IDs, eg:
<tr id='minute_tr'>
<tr id='hour_tr'>
<tr id='day_of_month_tr'>
<tr id='month_tr'>
<tr id='day_of_week_tr'>
  1. Checkbox added to the td in a span:
<tr><td class=listtitle colspan=3>Create a New Cron Job <span style='float: right'><input type=checkbox id='reboot' name='reboot' value='yes' onchange="set_cron_display();"> Run on @reboot</span></td></tr>

CustomBuild 2.0 slim-down new

Thanks to Martijn van Duren from for providing a set of patches to reduce the size of CustomBuild 2.0. new

Related to the

This script will run before a cronjob is added by a User.

It will let you scan all provided data to determine if you want to allow it or not.

DA will pass the entire form, so using debug mode and "| grep string" will give you the full list of values:

If you exit with a non-zero value, the cron will not be added.

If you exit with 0, then the cron will be added (assuming all other normal DA checks pass).

This script is call before both creation and cron edits.

For edits, you'll get edit=1. For additions, edit=0.

Two-Step Authentication (SKINS)(LANG) new

This new feature will allow any DirectAdmin account to require the Two-Step Authentication using a time-based code from a smart-phone app (eg: Google Authenticator, FreeOTP, Authy, etc...)

Access this feature from:

Password Icon -> Two-Step Authentication

Once you have a "Secret" created, scan the barcode into your Authenticator App in your smart phone.

Enable the feature, and future logins will require the temporary code generated from the App, entered on a 2nd page after a successful user/password login.

You can also optionally create one-time use "Scratch Codes", which can be printed and kept somewhere safe.

These scratch codes are as a backup, in case your phone is not available to generate the code.

A scratch code is only valid for one use, then is removed from the list of codes.

The scratch code can be entered into the same "Code" field when logging into DA.

Information on the importance of Two-Factor Authentication can be found here:

Similar to the "Security Questions" feature, which can also be enabled at the same time for 3 layers of protection:

Security Questions for extra layer of protection (SKINS)

directadmin.conf settings:

twostep_auth=0|1   default 1
block_ip_after_failed_twostep_auth=0|1|2  default 0

functionality for these 3 variables is identical to id=1439.

The twostep_auth_discrepancy value should be a positive integer representing the number of 30 second time slices you can be off by (before or after).

So the default of 1 allows a code to be valid before 30 seconds before, and 30 second after the phone's timer is done counting down.

DA's "Test Code" button may show you a message about the code being valid, but for a different time.

If, for example, you see the time discrepancy as "-4", that means your code expired 2 minutes ago.

If you can't fix your server's time, then change this setting to be "4" (positive 4), and DA will allow a wider range of -4 to +4 for logins.

Also useful if someone's phone time isn't accurate.

The twostep_auth_trust_days=30 value represents the duration that a trusted cookie is allowed to live in the client's browser.

A trusted device can be un-trusted on the CMD_TWOSTEP_AUTH page. This may make your phone sad, as the server would no longer be it's friend.

DA User files:



DA User settings:








files_user.conf, add:


CMD_ASK_TWOSTEP_AUTH=user/ask_security_question.html (this html file is re-used from Security Questions)



new files:






<a href="CMD_TWOSTEP_AUTH">Two-Step Authentication</a>



.good_twostep_auth_code, .bad_twostep_auth_code
    display: inline-block;
    text-align: center;

    background-repeat: no-repeat;
    background-position: bottom;

    min-width: 50px;
    padding-bottom: 50px;
.good_twostep_auth_code {
    background-image: url(IMG_CHECKBOX);
.bad_twostep_auth_code {
    background-image: url(IMG_INCORRECT);


Related to CMD_COMMENTS, CMD_API_COMMENTS can be used to set and retrieve a basic text file for a User.

Usually, it's just comments by the Reseller, but with the API, it would be possible to store actual data, encoded however you'd like, as it's just a text file.

Accepts both GET and POST.

Save a comment:

comments=the data you want to save

The data can contain n characters, similar to what a textarea generates.

Retrieve a comment:


You can use CMD_COMMENTS for action=view, but will be html encoded.

If you use CMD_API_COMMENTS for actin=view, it will be the raw comment.

Reset Zone now passes USERNAME and PACKAGE tokens fixed

The creation of a zone with a User, or by a User will pass the USERNAME and PACKAGE tokens to the dns_*.conf templates.

Bug was that the DNS Admin tool, "Reset Zone", did not include those tokens, giving you a different result.

Used the new quick lookup tool:

Read optimization for ConfigFile class when only single item needed

to quickly find the username from the domainowners file, and passed it to the dns class before the reset.

Update to addip regarding preferred_lft for IPv6 fixed

Relating to the change in 1.48.0:

addip script to depracate IPv6 IPs upon adding

the addip addIPv6 function has been changed to look like:

    MCOUNT=\`echo $2 | grep -c \`
    if [ "$MCOUNT" -gt 0 ]; then

    ip addr add ${1}${MASK} dev $ETH_DEV preferred_lft 0 >/dev/null 2>&1
    if [ "$?" -ne 0 ]; then
        /sbin/ifconfig $ETH_DEV inet6 add ${1}${MASK}

    exit 0;

This is because the previous method would set the main IPv6 IP as preferred_lft=0, still causing the IPs to be randomly selected by the OS.

This change ensures that only the current IP will have preferred_lft disabled, leaving the defautl IPv6 working as it was set.

Note that on CentOS 5 (and other older OSs), the "ip add add" command will fail with the "preferred_lft 0" option, so we then do a check for success, and fall back to ifconfig, which will always end up being used.

prevent da-popb4smtp from running twice fixed

When the da-popb4smtp is started, it will read the contents of:


if it exits, and check if that pid is running.

If it is, then it will exit 1, show a message and log the failed start to /var/log/directadmin/da-popb4smtp.log

Also, new installs will add:


to the file:


You can manually add this if you want to monitor the service.

WordPress Brute Force Monitor to check redirect status fixed

Related to this feature:

Apache WordPress log scanning in BFM (disabled by default) (SKINS)(LANG)

It was previously thought that we couldn't tell if the WordPress login failed or not, so the BFM was only counting the attempts.

It was reported that the redirect status is a success/failure indicator of success.

If a redirect (code 301) happens, then it's a success.

If it's a non-redirect with code 200, that implies it's showing the login page, thus a login failure happened.

To accomplish this, I've added a "text3" option to the brute_filter.list, now making the 2 entries:

wordpress1=ip_after=&ip_until= -&text=\] "POST /&text2=/wp-login.php&text3=" 200%20
wordpress2=ip_after=&ip_until= -&text=\] "POST /&text2=/xmlrpc.php&text3=" 200%20

Sample log entry for successful login:

... "POST /wp-login.php HTTP/1.1" 302 1151 ...

sample log entry for failed login:

... "POST /wp-login.php HTTP/1.1" 200 2024 ...

I wanted to use the HTTP/1.1 included in text3, but HTTP/1.0 is still valid protocol, so just used " 200 (with a trailing space), as it's a very low likelihood of showing up elsewhere on that line due to " only appearing in a few select areas.

/home/user/imap restore not set to group mail fixed

Relating to this security change in how data is restored (DA-1968):

Security: Various Security improvements

but was that the new copy method didn't correctly set the mail gid when copying the files over, causing them to be set to their user group after the restore.

Workaround for a full system restore is to chgrp that folder to mail, eg:

cd /home

chgrp -R mail */imap

Better input filtering (SECURITY) fixed

Better checking/encoding on values for CMD_MODIFY_USER, CMD_ACCOUNT_USER (package), CMD_SPAMASSASSIN.

Note that as long as you have:


Security check on Referer header

enabled, which it is by default, there is no XSS issue from remote sites.

It would then just become one's own ability to enter invalid values, thus is considered a very low threat, and just a filtering bug.

For anyone using this old feature:

~username/ as default

(related: changing the default ~username public_html link back to old default)

But was that the created:


file was not correctly tokenized.

Set session expiry fixed

With the addition of the Two-Step Authentication feature, we've added a checkbox to allow the current device to be trusted for 30 days.

This uses a cookie.

The change is that any session cookie DA sets will now have a expiry associated with it, updated with each CMD/HTM request.

Previously, the cookie would only be valid for the "session" time, meaning once you close the browser, the session cookie is gone.

It wasn't previously an issue in that DA does track session time on the server side, so if a session is expired on the server, the da_sess_ file is still removed, so there was no issue with anyone ever going over after a long period of inactivity, even though the cookie was still set.

However, with the "trusted device" checkbox, we obviously needed the session to have it's life spanned across many browser closes, to rememeber the setting, hence the change.

The main purpose for making note of this is that if you do not log out of DirectAdmin, you will still be logged in if you closer your browser and re-open it within the session timeout period.

Previously, a browser close would log you out, but not anymore.

So if you need to logout immediately, be sure you actually log out.

But the 60 minute session timeout is still in effect, so you will be logged out if you make no connections for 60 minutes (regardless of an opened/closed browser)

Last Updated: