Version 1.40.0

Released: 2011-11-24

Log pop+imap bandwidth for dovecot new

Relating to:

http://help.directadmin.com/item.php?id=253

dovecot recently logs bytes for imap usage, so bandwidth can now be counted.

Example from maillog:

Sep 11 19:43:26 abc dovecot: imap(user@domain.com): Disconnected: Logged out bytes=241/451
Nov 15 02:28:12 abc dovecot: pop3(user@domain.com): Disconnected: Logged out top=1/30, retr=1/2210, del=0/110, size=1638002

For imap, DA will add the bytes=241/451 (in/out) together for the total.

For pop, DA will use retr=1/2210, where 2210 is the sent bytes with the retr command.

If the pop3 line contains a bytes= entry, that will be used instead (even though it doesn't by default, it will be more accurate when we you add it to your dovecot.conf. (new systems will have the new log format for pop, see below)

This will add 2 new columns to the bandwidth breakdown page.

And will add pop and imap values to the bandwidth.tally.cache file.

The file:

/usr/local/directadmin/scripts/rotate_email_usage.sh

has also been updated to rotate the dovecote.bytes files which will be created by the da-popb4smtp binary.

The dovecot.bytes files will exist in 2 locations, depending on the login format.

/etc/virtual/domain.com/dovecot.bytes for @domain email accounts.

/usr/local/directadmin/data/users/username/dovecot.bytes for system email accounts.

The contents of the dovecot.bytes files will be dumped into the bandwidth.tally, then deleted (via rotate_email_usage.sh)

New addition to the dovecot.conf for dovecot 2.0, into the section for protocol pop3:

pop3_logout_format = top=%t/%p, retr=%r/%b, del=%d/%m, size=%s, bytes=%i/%o

adding this line will give a more accurate bandwidth logging.

Not adding it will only rely on the sent bytes frm RETR commands, so will be somewhat short of the truth.

Log delete/rename/copy portions of the CMD_FILE_MANAGER new

Log delete/rename/copy portions of the CMD_FILE_MANAGER, to better track User actions.

Because the filemanager is chrooted, the log to the system.log will happen before the action takes place, so if there are any errors, the logs won't show them.

all_backups_post.sh new

all_backups_post.sh to be called after all backups are finished.

Only applies to backups triggered from:

Admin Level -> Admin Backup/Transfer

Reseller Level -> Manage User Backups

Is not triggered from:

User Level -> Create/Restore Backups

This script is purposed to run after a large number of backups are created, hence it's not called for the User Level backups.

The parameters passed are the same values that are passed to DA via the task.queue for the creation of the backup in question.

This variable can vary, so to see what you'll get, type:

cat /usr/local/directadmin/data/task.queue

after triggering the run of the backup you want.


If you wish to do something after each User backup is called, use this instead:

user_backup_post.sh

user_backup_post.sh

Add Block IP button to IP/User tables for faster blocking (SKINS) new

With the Brute Force Monitor, add the Block IP button (if block_ip.sh exists) right in the tables, so multiple IPs can be blocked at once.

It will call the block_ip.sh once per IP.

SKINS:

admin/brute_force_monitor.html

added:

|*if HAVE_BLOCK_SH="1"|
<input type='button' value='Block IPs' onclick="if (confirm('Are you sure you want to block these IPs?')){document.tableform.action.value = 'block_ips';document.tableform.submit();}">
&nbsp;&nbsp;<b>|</b>&nbsp;&nbsp;
|*endif|

database_user_destroy_post.sh new

Custom script called when deleting a Database User:

database_user_destroy_post.sh

Related to database_user_create_post.sh: custom scripts for databases

environmental variables for script:

username - DA username
database - name of the db
user - name of the user created

Note that database_destroy_user_post.sh will not be called when a database and it's users are being deleted.

It's only called when a single DB user is removed from a database.

This means that any code used in database_user_create_post.sh will have to be doubled in database_delete_post.sh.

EDIT: should really call this for each DB User being removed, when a DB is deleted as well.

IP ranges and reverse IPs in brute_skip.list (SKINS) new

Optional field/value on the Brute Force Monitor (BFM) page which will allow you to manually type in:

  • IPs, IPv4 and IPv6 (use full/expanded form for IPv6)

  • IP ranges: 1.2.3.4-5 and 1:2:3:4:5:6:7:8-9 (make sure to use the range type that the logs will see the IP as. If an IP shows up as IPv6 in the logs, use an IPv6 range)

  • domain.com (reverse IP lookup, exact match)

  • *.domain.com (reverse IP lookup, wildcard match, must start with *. Can also be *irectadmin.com, as it's just a string match)

which will give you more control over skip list with the BFM.

If you leave the field empty, the "Add to Skip List" button will block the check-boxed IPs listed in the table above.

If you add an IP/range/domain to the field, then that value will be added to the skip list as well as any check-boxed IPs.

When entering domain.com or *.domain.com, this will trigger a reverse IP lookup on the IP using a new script:

/usr/local/directadmin/scripts/reverse_ip_lookup.sh

If no domain.com or *.domain.com value is added, then the lookup is not done, which will speed up the process (reverse IP lookups can be slow if there are many IPs to check)

The timing of the lookup is after the logs are parsed for that minute.. so a lookup will only ever be done at most once per minute, per IP.


SKINS:

admin/brute_force_monitor.html

add;

<input type=text name="skip_value" placeholder="Optional IP/Range/Domain" title="Optional IP/Range/Domain" size=24><a target=_blank class=listtitle href="http://www.directadmin.com/features.php?id=1252">?</a>

option to allow underscores in db names and db users new

New directadmin.conf option to allow an override for anyone who needs to backup/restore databases or db users with underscores in their names.

Removed in DirectAdmin 1.666.

Disk Usage Breakdown - CMD_DU_BREAKDOWN (SKINS) new

New button on the stats page of Users, so they can click "Details" next to their total disk usage.

"Details" button also on the User info page viewed by Admins and Resellers.

CMD_API_DU_BREAKDOWN also exists. It will dump the contents of the user's du_breakdown.list file.

User Level -> Site Summary / Statistics / Logs -> Total Disk Usage (MB) -> [Details]

Reseller/Admin Level -> Show All Users -> Total Disk Usage (MB) -> [Details]


SKINS:

files_user.conf:

CMD_DU_BREAKDOWN=user/du_breakdown.html

user/du_breakdown.html - see skin

BFM: show_blocked_ips.sh and unblock_ip.sh (SKINS) new

Two new items for the brute force monitor:

show_blocked_ips.sh

If you create it, it's output should generate a list of IPs which are blocked.

The format will be 1 IP per line, but should also have an = at the end to allow for more data to be associated with the IPs in the future (eg: if we add blocked time or info, etc..)

So for now, make the output like:

havedata=1|0
1.2.3.4=
2.3.4.5=

etc...

or

1.2.3.4=dateblocked=12345678&info=he%20was%20being%20mean
2.3.4.5=dateblocked=12346789&info=definitely%20a%20meany

The havedata=1 value is optional.

If you include in the the output, then DA will expect dateblocked=123456 (unix timestamp) along with the IP, as well as info=.

Note that either "dateblocked" or "info" can be blank. DA will ensure there is something in the variable before chewing on it.

The havedata=1 value simply changes the table to show more cells, ie: the data you're giving it.

  1. unblock_ip.sh

Related for automated unblocking: BFM automated unblock (SKINS)

Called by DA if it exists and will pass the environmental variable:

ip=1.2.3.4

so that you can remove an IP from your block list.

SKINS

admin/brute_force_monitor.html

very top of file:

|*if HAVE_SHOW_BLOCKED_IPS_SH="1"|
|?BODY=onLoad="sizeTheDiv();"|
|*endif|

after the skip list:

|*if HAVE_SHOW_BLOCKED_IPS_SH="1"|
<br>
<form name=tableform5 action='CMD_BRUTE_FORCE_MONITOR' method=POST>
<input type=hidden name=action value="unblock">
<b>Blockd IPs</b>
<div id="blockedipsdiv" style="overflow: auto; height: 450px; width: 300px; border: 1px solid grey;">
|BLOCKED_IPS|
</div>
|*endif|
|*if HAVE_UNBLOCK_SH="1"|
<table id="blockbuttontable" class=list style='width: 50%' cellpadding=3 cellspacing=1>
<tr><td class=listtitle align='right' colspan='5'> <input type='submit' value='UnBlock' name=unblock></td ></tr>
</table>
</form>
|*endif|
|*if HAVE_SHOW_BLOCKED_IPS_SH="1"|
<script type="text/javascript">
<!--
function sizeTheDiv()
{
    var tblwidth=document.getElementById('blockedipstable').offsetWidth;
    if (tblwidth>0)
    {
        if (tblwidth < 300)
        {
            tblwidth = 300;
            document.getElementById('blockedipstable').style.width=tblwidth;
        }

        document.getElementById('blockedipsdiv').style.width=tblwidth+19;
        if (document.getElementById('blockbuttontable'))
            document.getElementById('blockbuttontable').style.width=tblwidth+21;
    }
}
sizeTheDiv();
// -->
</script>
|*endif|

Ability to hide and block "Domain Setup" page (SKINS) new

New global token:

|ALLOWED_CMD_DOMAIN|

will be set to yes or no, depending if the User is allowed to run:

CMD_DOMAIN

The way to control the running of that command is with the commands.allow and/or commands.deny.

For this case, generally, you'd just add:

CMD_DOMAIN
CMD_ADDITIONAL_DOMAINS
CMD_API_DOMAIN
CMD_API_ADDITIONAL_DOMAINS

to the file:

/usr/local/directadmin/data/users/username/commands.deny

Related feature:

commands.allow and commands.deny for per-user control

https://forum.directadmin.com/posts/211408


SKINS:

user/content_main.html

user/show_domain.html

Add this around the href to CMD_ADDITIONAL_DOMAINS to hide the link:

|*if ALLOWED_CMD_DOMAIN!="no"|
 .... url ....
|*endif|

we use "not no" instead of "is yes", to be backwards compatible, in case they use a new skin for an old version of DA.

The old versions of DA would be blank, so "is yes" would fail, but "not no" will succeed if blank.

Suspend reason: user/domain (SKINS) (TEMPLATES) new

When a user/domain is suspended, feature which allows reasons that it was suspended.

Note that the reason is optional. You don't need to pass it, and you don't need to pick something, if you don't want to.

The variable suspended_reason will be stored in both the user.conf and domains/domain.com.conf if either is suspended.

When the user/domain is unsuspended (suspended=no), the variable is deleted.

Uses an environmental variable in the httpd.conf holding the key-word descriptor of why it was suspended. (probably cleaner/simpler), eg:

SetEnv reason bandwidth

which can then be accessed via the /home/reseller/domains/suspended/index.html, index.shtml, or index.php.. whatever works for you which has the ability to read ENV variables.

Variable name is "reason"

Available for Admins/Resellers to use on Users.

Also available for Users to use on Domains.

template:

/usr/local/directadmin/data/templates/suspension_reason.txt

user_bandwidth=id=12&text=User Bandwidth
user_quota=id=13&text=User Disk Quota
domain_bandwidth=id=14&text=Domain Bandwidth
domain_quota=id=15&text=Domain Quota
reseller_bandwidth=id=16&text=Reseller Bandwidth
reseller_quota=id=17&text=Reseller Quota
billing=id=18&text=Billing Issue
abuse=id=19&text=Abuse
spam=id=20&text=Spam
other=id=21&text=Other

where the id values for the key names are internal language pack id numbers set in:

/usr/local/directadmin/data/skins/enhanced/lang/en/internal/suspension.txt

Note, if you just want to set the text, and not make your entries translateable, then simply don't include an id value.

A sample reason without an id:

smelly=text=He Really Smells Bad

Both cases must have a "text" variable, as it will be the fallback for the event that the id cannot be found in the given language file.

If you wish to customize the suspension_reason.txt file, first copy it to the folder:

/usr/local/directadmin/data/templates/custom

and edit the custom copy.


TEMPLATES:

suspension_reason.txt : see above

virtual_host*.conf

added:

|*if SUSPENDED_REASON|
<IfModule mod_env.c>
SetEnv reason |SUSPENDED_REASON|
</IfModule>
|*endif|

SKINS:

Just a minor cosmetic change.

Since Show Admins and Show Resellers now have wider tables, we're changing the header page to be the full path instead of the path with the stats on the right, such that the table doesn't impede on the stats.

admin/show_admins.html

admin/show_resellers.html

Change:

|HTM_ADMIN_TOP|

and:

|HTM_ADMIN_BOTTOM|

to be:

|HTM_HEADER|

|HTM_HEADER_WIDE|

and:

|HTM_FOOTER_WIDE|

|HTM_FOOTER|


Thread containing examples on index.shtml and index.php usage:

https://forum.directadmin.com/posts/212649

Add a whois to reverse IP lookup, and ip_info.sh script new

The IP information page under the Brute Force monitor will now be changed to call a new script:

/usr/local/directadmin/scripts/ip_info.sh 1.2.3.4

The script will call:

dig -x "1.2.3.4" +noshort

but will also include a whois output (if whois exist) for more information on the IP:

whois "1.2.3.4"

Related DA command:

/CMD_BRUTE_FORCE_MONITOR?ipinfo=1.2.3.4

Note that this does add a few seconds to a the lookup time, but IMO worth the few seconds to get more/accurate information on the attacking IP.

domain log rotation to have order new

The tar.gz files in:

/home/user/domains/domain.com/logs

will now be rotated in a similar fashion to all logs in /var/log (but still controlled by DA, and not logrotate)

The format will be:

Nov-2011.tar.gz
Nov-2011.tar.gz.1
Nov-2011.tar.gz.2
Nov-2011.tar.gz.3
Nov-2011.tar.gz.4
Nov-2011.subdomain.tar.gz
Nov-2011.subdomain.tar.gz.1
Nov-2011.subdomain.tar.gz.2
Nov-2011.subdomain.tar.gz.3
Nov-2011.subdomain.tar.gz.4

The old format had no pattern to the numbering. Only the timestamp could be used to determine the newest log.

The numbers would be used in a rotation, but they were not in order.

The new format keeps things much cleaner.

The file that does not end in a number is always going to be the newest.

remove clipboard file upon logout new

When CMD_LOGOUT is called, the file:

/home/user/.clipboard

will be removed, if it exists.

This is done to prevent confusion in the FileManager, where files are still in the clipboard from previous sessions.

Default internal directadmin.conf option will be:

remove_clipboard_on_logout=1

If you do not want the clipboard to be removed on logout, set:

remove_clipboard_on_logout=0

in your directadmin.conf.

Note that this only applies if CMD_LOGOUT is called.

If the client just closes his or her browser, the event will not be triggered.

user_info_modify_post.sh new

Custom script:

/usr/local/directadmin/scripts/custom/user_info_modify_post.sh

used for chaning of User info:

Name

Email

language

skin

Note that the user.conf may or may not have already been written when this is called, so don't rely on it being written already.

Values passed:

username: DA user who's email was changed

only one of following:

email=button's text
name=button's text
language=button's text
skin=button's text

so you'll need to check which variable exists, and go from there.

All of these values will also be passed, where you'd figure out which button was pressed using the above values (email, name, etc) and use on of these values:

evalue=email@domain.com (email)
nvalue=John Doe  (name)
lvalue=en  (the language)
skinvalue=skinname

CMD_API_USER_EXISTS new

Called by an Admin, CMD_API_USER_EXISTS will return exists=1 or exists=0 if the account exists (Any type: Admin, Reseller, User).

error=1|0 is also returned.

If error=1, then text= will be set to the reason.

Multi Server Setup - User Check new

New checkbox in the section:

Admin Level -> Multi Server Setup

which checks the remote boxes for duplicate Usernames.

This is beneficial if you want to prevent duplicate usernames for reasons such as:

  • transfers between boxes to prevent accidental merges

  • you use a single remote MySQL server for multiple boxes

  • long term prediction of full DA clustering, where unique usernames is required (don't ask, distant future)

Feature will use the new API for confirming if a User exists:

CMD_API_USER_EXISTS

Table Row Highlighting (SKINS) new

BETA - disabled by default

only exists in "enhanced" skin at this time.

When your mouse hovers over a row, that entire row will change to a darker background, to more easily track which value you're about to select.

To enable, add the following to your directadmin.conf and restart DA:

table_highlighting=1

The internal default is:

table_highlighting=0

In a future version of DA, this will be enabled by default.

It's disabled for now, for testing purposes.

===================

SKINS:


style.css:

.listhighlight
{
    BACKGROUND: #b8c0e2;
    white-space: nowrap;
}
.list2highlight
{
    BACKGROUND: #b8c0e2;
    white-space: nowrap;
}
.listwraphighlight
{
    BACKGROUND: #b8c0e2;
    white-space: wrap;
}

.listwrap2highlight
{
    BACKGROUND: #b8c0e2;
    white-space: wrap;
}

header.html, in the <head> section:

|*if TABLE_HIGHLIGHTING="1"|
    <script type="text/javascript">
    <!-- // start preload code
    function tr_add_highlight()
    {
        add_highlight(this, 'list','listhighlight','list2','list2highlight','listwrap','listwraphighlight','listwrap2','listwrap2highlight');
    }
    function tr_remove_highlight()
    {
        add_highlight(this, 'listhighlight','list','list2highlight','list2','listwraphighlight','listwrap','listwrap2highlight','listwrap2');
    }
    function add_highlight(ob,h1,l1,h2,l2,h3,l3,h4,l4)
    {
        var tds = ob.getElementsByTagName('td');
        for(var d=0; d<tds.length; d++)
        {
            switch (tds\[d\].className)
            {
                case h1:tds\[d\].className = l1; break;
                case h2:tds\[d\].className = l2; break;
                case h3:tds\[d\].className = l3; break;
                case h4:tds\[d\].className = l4; break;
            }
        }
    }
    function make_tables_highlightable()
    {
        var tables = document.getElementsByTagName('table');
        for (var tbl=0; tbl<tables.length; tbl++)
        {
            if (tables\[tbl\].className.indexOf('table-highlight') != -1)
            {
                var trs = tables\[tbl\].getElementsByTagName('tr');
                for(var tr=0; tr<trs.length; tr++)
                {
                    trs\[tr\].onmouseover = tr_add_highlight;
                    trs\[tr\].onmouseout = tr_remove_highlight;
                }
            }
        }
    }
    // done with preload code -->
    </script>
|*endif|

footer.html, just before </body>:

|*if TABLE_HIGHLIGHTING="1"|
    <script type="text/javascript">
        make_tables_highlightable();
    </script>
|*endif|

move_user_to_reseller.sh not updating IPs fixed

move_user_to_reseller.sh

https://forum.directadmin.com/posts/196796

https://forum.directadmin.com/threads/41787

Updated the move_user_to_reseller.sh script to check if an IP is owned (for each ip in the user_ips.list file).

For any owned IP, owned by that User, the IP will be moved from the old Reseller to the new Reseller's ip.list file.

The data/admin/ips/1.2.3.4 is also updated for reserller=oldreseller to reseller=newreseller

Include multiple forwarder names in forwarder count for pre-check on limit fixed

Forwarders can be used like:

user1,user2,user3 -> somewhere@email.com

Ensure that this 1 entry counts as 3 forwarders and check the limit so it's not created if it shouldn't be.

Related thread:

https://forum.directadmin.com/posts/208135

set_permisisons.sh sets exim to 755 fixed

The script already did make the call correctly to set it to 4755:

set_file /usr/sbin/exim root $RT_GRP 4755

The issue was that the set_file function called the chmod first, then the chown.

The issue was that a 4755 file becomes reset to 755 when a chown is made on the file.

The simple solution was to put the chown first, then chmod.

In exim mainlog error you'd see would look like this if exim is 755 instead of 4755:

unable to set gid=12 or uid=2345 (euid=8): domain_filter router

If you see that error, type:

chmod 4755 /usr/sbin/exim

or run this fixed set_permission.sh:

cd /usr/local/directadmin/scripts
./set_permissions.sh email

but once done either, confirm it's set correctly:

[root@server scripts]# ls -la /usr/sbin/exim
-rwsr-xr-x  1 root root 856823 Mar  9  2011 /usr/sbin/exim
[root@server scripts]#

where you're looking for:

rwsr

and not:

rwxr

Update template filter_userspamfolder not to save to spambox if account doesn't exist fixed

When the option:

"Send the spam to the appropriate users's spam folder."

is used with SpamAssassin, any spam will be saved to the spambox, eg:

/home/username/imap/$domain/$local_part/Maildir/.INBOX.spam/new

However, if spam is sent to a forwarder, where no local mailbox exists, the filter will create that path to save it to the spambox, when it shouldn't.

The fix was to add extra code to the filter template:

/usr/local/directadmin/data/templates/filter_userspamfolder

where it will check for the account to exist, and if not, it will save the spam to the system account's spambox.

Changed:

         save |HOME|/imap/$domain/$local_part/Maildir/.INBOX.spam/new/ 660

to be:

        if "${if exists{|HOME|/imap/${domain}/${local_part}}{yes}{no}}" is "yes"
        then
            save |HOME|/imap/$domain/$local_part/Maildir/.INBOX.spam/new/ 660
        else
            save |HOME|/Maildir/.INBOX.spam/new/ 660
        endif

Note, if the catch-all is enabled (which I never recommend), the system account's spambox will grow quite rapidly.

Apart from not enabling catch-all accounts, I recommend to enable the spambox purge option in the Admin Settings.

Figuring out the syntax for the "exists" check took a while, as it uses double "if's" for string expansion to convert to a yes/no, then a string test for "yes" on that result.

Somewhat obfuscated, but that's why exim is so powerful.

To force a rewrite of all filter files, use this, as the filter files won't be rewritten with the update, but only after a User saves a change:

action=rewrite&value=filter

Also create a new template file:

/usr/local/directadmin/data/templates/filter_filterspamfolder

for when a basic "spam filter" (word filter) is used to redirect to the spambox.

The same rules apply, where the new double-if is used to ensure the folder exists.

If not, it's saved in the main spambox.


Related to the issue: (bottom part about not scanning forwarders)

http://help.directadmin.com/item.php?id=156

however, it wasn't a good solution because spam would then be forwarded to external systems (eg: gmail) without being scanned.

This could potentially cause your server to be blacklisted for sending spam, when it was only forwarding it.

The above fix is good because it allows forwarders to still be scanned, but doesn't save the local copy.

Restore adding duplicate A records if in short vs long form fixed

If the backup stored a full format of the www record (for example):

www.domain.com.  A  4.3.2.1

where 4.3.2.1 was a custom IP which did not match the old IP of the User (eg: an external server)

Then when the restore was done, since it doesn't match the dns_a.conf template which just has:

www  A  1.2.3.4

this caused both to exist in the zone after the restore:

www.domain.com.  A  4.3.2.1
www  A  1.2.3.4

causing an undesired round-robin effect.

Fix was to always shrink the long www.domain.com. format to the short www format when doing comparisons.

Note that if it's decided the value should be added (can't find a duplicate) then the original format used will be added (in this case, the www.domain.com. is added, if that's what was in the backup)

Options +ExecCGI to .htaccess file in cgi-bin by default fixed

Relating to:

http://help.directadmin.com/item.php?id=7

If cgi-bin is enabled when a domain is created, the items from id=7 will be added to the .htaccess file.

Table quicksort was incorrect, plus sort optimizations fixed

The quicksort algorithm for tables (which is only used in the brute force monitor so far) was not sorting correctly.

A rewrite of the algorithm corrected this. Other tables may be changed to use quicksort as well for it's significant performance increase.

Other classes are already using it.

Note that with quicksort, the "subsort" option does not work, so if it's used, those tables will only be able to sorted by 1 column, so it's use will be selective.

(the subsort is the column choice that the data will be sorted by, when the main column sort values match)

Also, optimizations to all quicksorts (configfile, listfile and tables) have been added in the form of inline functions for all of the quicksort function calls (swap, quicksort, compares, etc..)

This has gained roughly a 15% performance improvment on a 100% inverted list. (where it has to flip the list completely to be sorted)

Additional owned IPs had VH in ips.conf fixed

https://forum.directadmin.com/threads/42003

When adding an additional IP to a domain (User Level -> Domain Administration), I've added code to DA to issue a rewrite to the ips.conf.

This will get rid of the VH for the IP.. as it doesn't belong there if the IP is owned. (needs to go away in order to have SSL work correctly for the additional IP)

Allow tar exit code 1 fixed

As of tar 1.16, if a file is being changed as it's being included into a tar.gz file, tar will return exit code 1.

DA previously only accepted error code 0 as valid.

This change will allow the exit code of 1 to be valid and to not stop the backup process.

The usual causes of this error could be things such as incoming, or deleting email as the backup is being created, or changing files mid-backup.

Related:

http://www.mail-archive.com/bug-tar@gnu.org/msg01215.html

http://www.gnu.org/software/tar/manual/html_section/Synopsis.html

Related error:

Error Compressing the backup file user.reseller.username.tar.gz : /bin/tar: some/file/name.txt: file changed as we read it

Bug with database names in change_database_username.php fixed

Resolved an issues with the change_database_username.php script.

The mysql.db and mysql.user tables were being corrected updated, however, the issue was that MySQL doesn't actually have a rename option.

(They used to have RENAME DATABASE dbname, but it was dropped due to potential loss of data)

Added a rename() call to change /var/lib/mysql/dbname to then new dbname.

The side-effect of this issue, was that if you change the username again, it wouldn't find the DB, since it was never renamed in the first place.

Also, this means that the change_username.sh script will not work if you've got databases on an external box, since a MySQL query won't be able to rename the directory.

Last Updated: