Customizing Users

Using the script

You can control what you want to allow or disallow at almost any level you wish using the script:


This script will be run before all /CMD_* accesses to DA. If the script returns 0, then the command is allowed. Anything non-zero returned, the command is refused and the output from the script is shown to the user in DA.

For example, say we want to prevent one particular domain from setting up an email account with a quota larger than 50 meg. DA itself does not prevent this, but you can use the to abort setting it before the command is executed in DA.

The code in the for this example would be:


if [ "$command" = "/CMD_EMAIL_POP" ] && [ "$domain" = "" ]; then
    if [ "$action" = "create" ] || [ "$action" = "modify" ]; then
        if [ "$quota" -eq 0 ]; then
            echo "you cant have unlimited quota";
            exit 1;
        if [ "$quota" -gt 50 ]; then
            echo "you cant have more than a 50 meg quota";
            exit 2;
exit 0;

Remember to make it executable:

chmod 755 /usr/local/directadmin/scripts/custom/

Now when a user tries to set the quota to 0 or anything higher than 50, he'll get an error preventing him from doing so.

This script/concept can be applied pretty much anywhere in DA (I can't think of any exceptions, other than HTM_* files). Certain commands, like the FileManager for example, can be completely shut off for any user you want, or all users, or just users and not admins. Because you can code anything you want, your options are endless.

How to prevent adding a subdomain of your domain

If you wish to prevent any of your users from creating a subdomain on your domain, you can use the to prevent it. This script assumes you don't want them to create "" (anything on

Insert the following code into /usr/local/directadmin/scripts/custom/

$reserved = "";
$domain = getenv("domain");

$res = strstr($domain, ".".$reserved);

if ($res === FALSE) { exit(0); }
       echo "You may not create a sub domain on $reserved";

And make it executable:

chmod 755 /usr/local/directadmin/scripts/custom/

NOTE: this script runs as root. With root, you can also do other things like check the contents of the /etc/virtual/domainowners to ensure that the subdomain he's creating belongs to a domain he owns, etc. (Could also check /usr/local/directadmin/data/users/username/domains.list).

How to limit number of domains per server

If you want to cap the number of domains created on the server, you can use the to do so. In this example, we'll see a maximum number of 10 domains, but you can change this number as desired.

  1. Create the /usr/local/directadmin/scripts/custom/ with content:

#obtains the exact number of domains on the system right now. The tally is delayed, and cannot be used.
CURRENT=`ls -la /etc/virtual/ | grep drwx | grep -v majordomo | grep -v usage | grep -c drwx`

if [ "$CURRENT" -ge "$MAX_DOMAINS" ]; then
       echo "Maximum number of domains ($MAX_DOMAINS) has already been created. Cannot create any more."
       exit 1;
exit 0;
  1. Make it executable:
chmod 755 /usr/local/directadmin/scripts/custom/
  1. The is executed after the user is already created. It is reasonable also to run it before user creation (there is no need to create a user that cannot have any domains because the domain limit has been met), so just symlink it:
cd /usr/local/directadmin/scripts/custom
ln -s

How to change the default index.html for new domain

Whenever a new User or new domain is created, they receive a default index.html file in their public_html directory. If you wish to customize this holder page that they will receive, you can edit the index file in the following directory:


where RESELLERNAME is the name of the account which is creating the User (e.g., "admin").

All files within this default directory (sometimes known as a skeleton directory) are copied to the User's public_html folder and chown'd to that User. You can use an index.php or index.shtml file if you wish (or whatever you want), however only the index.html file (if it exists) will be tokenized. The following tokens are available:


Note that all files in the default directory must be world readable (755) because they're copied over by a process running as the new User. Any directory within the default directory will also be copied.

Related files for running a script before or after the domain is created include the and, respectively.

How to run embedded scripts in the default index.html

If admin is creating User fred, the index.html template is taken from /home/admin/domains/default/index.html.

You can now add scripting to this template, eg:

        echo "This is run from php";

allowing you to add custom data as needed.

The script will run as the User, not as admin.

How to edit all the templates, messages and default index.html

If you're looking to customize the look and feel to the data that is used for your users, this guide will explain where these files are, and how to go about editing them (note that this doesn't apply to skins).

To edit the default index.html placeholder file that new domains will get after being created, you will edit the index.html found in /home/$RESELLER/domains/default/index.html, where $RESELLER is the name of the account that will create the User. If a User creates a secondary domain in his account, this same path still applies (that of the User's creator).

One level above that, when a new Reseller or Admin is being created, this "default" directory is created and filled with defaults. After their account is created, they will use these files as mentioned above. If you want to edit the default files that are copied into /home/$RESELLER/domains/default, you can find these defaults in /usr/local/directadmin/data/templates/default. However, you must ensure to follow the "templates" editing guidelines, which will be discussed next.

Message and templates can be found in /usr/local/directadmin/data/templates.

Files here are read in, usually "tokenized" (variable swapped with real values), and used for their respective purposes. Templates can be edited to customize the look and feel of this data, however there are a few rules that need to be followed to ensure your data stays intact.

The templates directory comes in the DirectAdmin update.tar.gz package, so after each update of DirectAdmin, all files in the templates folder are overwritten. This allows the templates to stay updated to their latest version.

If you wish to make changes to these files, in order to prevent updates from overwriting your changes, you simply first copy the template file that you wish to edit to the custom folder /usr/local/directadmin/data/templates/custom, then edit the copied file that's in the custom folder. Files in the custom folder override the files in the templates folder.

For the first example of directory templates (like the default/index.html), if you want to customize the index.html for new Resellers, then you must copy the whole directory (and its full contents) into the custom folder, e.g.,


Note that the placeholder index.html for the domains owned by a Reseller is taken from his creator, not his own default directory. So if "admin" where to create Reseller "bob", then bob's own personal domains will grab the placeholder index.html from /home/admin/domains/default/index.html, and not his own default or the templates default.

How to create a custom index.html for new subdomains

Since there is no template for the subdomain index.html (will likely change), you can still create your own index.html files for them, but you have to use the file.

Create the /usr/local/directadmin/scripts/custom/ file, and insert the following code:

rm -f $INDEX
cp /your/custom/index.html $INDEX
chown $username:$username $INDEX
exit 0;

And make it executable:

chmod 755 /usr/local/directadmin/scripts/custom/

Obviously, change /your/custom/index.html to where your custom index.html will be taken from.

How to prevent users from changing a password

There are some cases where you do not want to allow Users to change their passwords, but still allow the passwords to be changed via their creator. I believe WHMCS might be one of these cases, where they'd change their passwords from there.

In DA, there are a few ways you could block their access to CMD_PASSWD, but assuming you have 1.51.4+, the simplest would be to create the custom script /usr/local/directadmin/scripts/custom/ with the following code:

if [ "$called_by_self" = "1" ]; then
       echo "You cannot change your own password.";
       exit 1;
exit 0;

And make it executable:

chmod 755 /usr/local/directadmin/scripts/custom/

How to limit the number of backups per user

If you want to limit the number of backups a User can create, let's say to 5, then you can create the following custom script /usr/local/directadmin/scripts/custom/ and add the following code to enforce the limit:

#check filename for /home/user/
U=`echo $file | cut -d/ -f3`
if [ "$U" != "$username" ]; then
   #file is not in our /home, so is Reseller or Admin backup.
   exit 0;
#file is being created below this User.
C=`ls /home/$username/backups | wc -l`
if [ "$C" -ge "$MAX_BACKUPS" ]; then
   echo "Too many backups. Delete some from /home/$username/backups before creating another.";
   exit 1;
exit 0;

And make it executable:

chmod 755 /usr/local/directadmin/scripts/custom/

You can manually test the script like this:

file=/home/fred/backups/backup.tar.gz username=fred ./; echo $?;

Which will either output 0, which means the script allowed creation, or the "Too many backups" error, followed by a 1, where 1 means the script instructs DA to abort the backup.

How to limit quota per email

If you'd like to keep E-Mail quotas in check, you can prevent any User from setting a quota value higher than 50MB by creating the /usr/local/directadmin/scripts/custom/ file with this content:

if [ "$quota" != "" ]; then
   if [ "$quota" -gt "50" ]; then
       echo "Cannot set quota greater than 50MB";
       exit 1;
exit 0;

Make it executable and link to the modification hook:

cd /usr/local/directadmin/scripts/custom/
chmod 755
ln -s

Test it out by both trying to create and also change an E-Mail account to have more than 50MB of quota.

How to prevent adding certain email names

If you wish to prevent users from adding email names like root, webmaster, or postmaster, create the /usr/local/directadmin/scripts/custom/ script with the following content:


   if [ "$user" = "$1" ] || [ "$newuser" = "$1" ]; then
      echo "You cannot create an account named $1";
      exit 1;

if [ "$command" = "/CMD_EMAIL_POP" ]; then
   if [ "$action" = "create" ] || [ "$action" = "modify" ]; then
      blockaccount root;
      blockaccount webmaster;
      blockaccount postmaster;
exit 0;

And make it executable:

chmod 755 /usr/local/directadmin/scripts/custom/

How to change what imap/pop/smtp settings are shown upon email creation

Like other templates, you can alter what DA displays when an email account is created.

To do this, type:

cd /usr/local/directadmin/data/templates/custom
cp ../mail_settings.html .
vi mail_settings.html

to edit the copied mail_settings.html file.

A common use for this would be to replace the two instances of mail.|DOMAIN| with, if you've set up a global ssl certificate with only a single value.

Language tokens for mail_settings.html

When creating an email account, after success, the User will be shown their user/pass, and pop/imap/smtp settings.

This is stored in the template:


The |LANG| token is available, should you want to copy it to the data/templates/custom/mail_settings.html, however this is not a great solution.

You can instead swap all English words with |LANG_*| type tokens.

These tokens are located internally in the /usr/local/directadmin/data/skins/enhanced/lang/en/internal/email.txt file.

This means you'd need only set up your language changes in the email.txt, rather than having to copy the template, which is really only meant for swapping ports or '' records, etc.

How to customize daily user email limit based on package

New Method

Packages now support the User E-Mail in new window

By default, only Admins can view/affect them in packages, unless reseller_can_set_email_limit=1 is enabled, where Resellers can also set the limit in packages.

New variable in the packages file:


where -1 means it will use the system global default (/etc/virtual/limit).

0 is not going to be valid here, but on disk it would imply unlimited.

Should you wish to allow unlimited emails to be sent (not recommended), you'd pass:


similar to other "unlimited" options in packages.

In this event, the package file would store:


Should a User be created with this package, the value is not stored in the user.conf.

Instead, should it not be set to -1, the limit will be stored in /etc/virtual/limit_fred for User 'fred', for example.

After the User is created, this feature essentially has no effect.

It relies on the system already in place for backup/restores of /etc/virtual/limit_fred.

When saving an existing package, where a User is already set to this package, DA will go through all Users with this package and update their /etc/virtual/limit_fred files.

If you update the package to use value -1, then each limit_fred file will be deleted, reverting to the global default.

Old Method

With the addition of the custom package itemsopen in new window, you can now use these items to control other areas of your system. For this example, we'll have these items control the daily email limit of a User (/etc/virtual/limit_username).

  1. The first step is to add a custom package item. See this guideopen in new window on how to do that. For this example, use a 'text' value. Give the variable a name called user_email_limit.

  2. Next, we need to have this option do something. By default, the item is only stored in the user.conf file and won't do anything. To have it do something, create the script /usr/local/directadmin/scripts/custom/ with the code:

if [ "$user_email_limit" != "" ] && [[ $user_email_limit =~ ^-?[0-9]+$ ]] && [ "$user_email_limit" -gt 0 ]; then
    echo -n "$user_email_limit" > /etc/virtual/limit_$username
exit 0;

And make it executable:

chmod 755 /usr/local/directadmin/scripts/custom/

Once the User is created, this package variable will no longer have any effect, meaning changing it from the package won't have any effect (you can if you want by creating a similar

The way to change the per-User email limit setting would be normally through Reseller Level -> List Users -> Username -> E-Mail Limit.

I wish to have an Email-Only system for some of my clients

With the flexibility of the User packagesopen in new window, skinsopen in new window and skin templates, pre/ scripts and the API, you can accomplish essentially any service combination you wish. Regarding email, there are a few methods of accomplishing an email-only system.

Option 1, using DA and its normal login system (easiest):

  1. Copy one of our skins to your own, and remove any the bits you don't want.
cd /usr/local/directadmin/data/skins
cp -Rp enhanced emailonly

Remove links to the FileManager, and any other non-email related areas in the new email-only skin.

  1. Create normal User packages, and set the value 0 for the features you don't want them touching (e.g., ftp, databases, etc). Select the email-only skin you've created.

  2. This step is optional, but in terms of completeness and security, it is recommended. Using the hook script, only allow access to email-related CMD_* functions. You can add these checks only for users who are using the email-only skin (grab this check from /usr/local/directadmin/data/users/$username/user.conf, skin=email-only). Related examples:

Basically, you'll just add all email-related commands to the "ok" list, and then deny everything else (return 0 for 'ok', and return non-zero for 'not ok').

The purpose of the is to ensure that they don't manually try to do things (like access the FileManager) using their own custom forms sent from somewhere else, or an API.

The newer commands.allow and commands.deny would also accomplish the same thing, and would be more efficient than the in new window

Option 2, using the DA API, requiring you to create your own interface using PHP.

With this 2nd option, you'd create your own login system, your own interface with PHP, and then simply have your scripts connect to DA's API to create what you want, how you want, etc. in new window in new window

How to control the user creation path from package

Starting from DirectAdmin 1.52 there is a new feature that automates the user home creation path: in new window

However, you may still want to separate the user home path created, let's say, for a faster SSD packages.

If you have /home and /home2, and want to be able to create Users to either directory via the choice in a package, do as described below.
Note: Assumes CentOS and /etc/default/useradd for default home control.

  1. Create a Custom Packages Item listbox for the homedir, the /usr/local/directadmin/data/admin/custom_package_items.conf file with the following code:
homedir=type=listbox&item1txt=/home&item1val=/home&item2txt=/home2&item2val=/home2&string=Select from List&desc=Select desired home path.&default=/home2

Note the default is set to /home2. Use /home if you wish. Be sure to re-save all of your User packages so they have the homedir set.

  1. Create the script /usr/local/directadmin/scripts/custom/ to change the /etc/default/useradd file and add the following code:
if [ ! -e ${DEF_USERADD} ]; then
   echo "cannot find ${DEF_USERADD}";
   exit 0;
if [ "$homedir" = "" ]; then
   echo "homedir is blank";
   exit 0;
perl -pi -e "s#HOME=.*#HOME=$homedir#" ${DEF_USERADD}
exit 0;

Make it executable:

chmod 755 /usr/local/directadmin/scripts/custom/
  1. Lastly, to set it back after each creation, use the /usr/local/directadmin/scripts/custom/ file and add the following code:
perl -pi -e "s#HOME=.*#HOME=/home#" ${DEF_USERADD}
exit 0;

And also make it executable:

chmod 755 /usr/local/directadmin/scripts/custom/

Using a package to alter user httpd.conf files

If you're trying to add custom features/options into DA packages, and want those to affect certain areas on the system (in this example, the user httpd.conf file), you can do so using a combination of several features in DA.

  1. The first step is to use the custom package item feature to add the checkbox/fields you want into the packages.

  2. Then create the script to grab that info from the /usr/local/directadmin/data/users/$username/user.conf to make decisions as to what to alter, how to alter it, etc. (based on your requirements).

  3. In this example, we want to change the httpd.conf, so have the post script edit/create:


and insert whatever code you need in it. Be sure to run the command:

echo "action=rewrite&value=httpd&user=$username" >> /usr/local/directadmin/data/task.queue

so that the change you make to the $domain.cust_httpd file is applied.

  1. Since this is a package option, any change you make to the package/user will alter the user, not the domain, so you'd need to also create /usr/local/directadmin/scripts/custom/ and have it repeat the same basic idea as for, but instead, in the case that you're disabling the feature, to remove the code from the cust_httpd file for all domains that belong to the user.

How to reset the today's email usage count

The file /etc/virtual/usage/username exists if the /etc/virtual/limit file is set to something other than 0, and email has been sent.

Once the usage file becomes the size of the limit, then emails can no longer be sent out.

A button called Reset Today, located at Show user details page, will appear next to Sent Emails if the usage file exists and the currently logged in user is an Admin (only Admins can use this feature).

For both Resellers and Admins, the "Current Usage" column for "Sent Emails" (to the right of the number) will show:
(Today: 25)
Where 25 is showing the size of the usage file.

When you click the "Reset Today" button, the usage file is deleted. The (Today: 25) text will then disappear, indicating that the count is reset. Once the User starts to send emails again, this number will show up again in realtime (for each page load).

How to customize the user crontab file

Internally, DirectAdmin uses the standard template methods for adding cronjobs. If the file /usr/local/directadmin/data/templates/custom/cron_template.txt exists, it will be used as the template, which allows you to add header/environmental variables, etc.

A sample layout would be as follows:


All tokens available include:

Last Updated: