~6 min read • Updated Mar 1, 2026
1. Completely Rebuilding the /etc/virtual Directory
If your /etc/virtual directory is corrupted or missing important files, you can fully rebuild it using the following procedure.
1.1 Back up the existing directory
cd /etc
cp -Rp virtual virtual.backup
1.2 Ensure the directory exists with correct permissions
mkdir -p /etc/virtual
chmod 755 /etc/virtual
chown mail:mail /etc/virtual
1.3 Create the rebuild script
Create /root/fix.sh with the following content:
#!/bin/sh
echo -n '' > /etc/virtual/domains
echo -n '' > /etc/virtual/domainowners
mkdir -p /etc/virtual/`hostname`
chown mail:mail /etc/virtual/`hostname`
chmod 711 /etc/virtual/`hostname`
echo `hostname` >> /etc/virtual/domains
for u in `ls /usr/local/directadmin/data/users`; do
{
for d in `cat /usr/local/directadmin/data/users/$u/domains.list`; do
{
echo "$d: $u" >> /etc/virtual/domainowners
echo "$d" >> /etc/virtual/domains
DMN=/etc/virtual/$d
mkdir -p $DMN
chmod 711 $DMN
chown mail:mail $DMN
touch $DMN/aliases
if [ ! -s $DMN/aliases ]; then
echo "$u: $u" > $DMN/aliases
fi
touch $DMN/autoresponder.conf
touch $DMN/filter
touch $DMN/filter.conf
touch $DMN/passwd
touch $DMN/quota
touch $DMN/vacation.conf
chown mail:mail $DMN/*
mkdir -p $DMN/majordomo
chmod 751 $DMN/majordomo
chown majordomo:daemon $DMN/majordomo
mkdir -p $DMN/reply
chmod 700 $DMN/reply
chown mail:mail $DMN/reply
for p in `cat /usr/local/directadmin/data/users/$u/domains/$d.pointers | cut -d= -f1 2>/dev/null`; do
{
echo "$p: $u" >> /etc/virtual/domainowners
echo "$p" >> /etc/virtual/domains
ln -s $d /etc/virtual/$p
};
done;
}
done;
}
done;
chown mail:mail /etc/virtual/domains
chown mail:mail /etc/virtual/domainowners
chmod 644 /etc/virtual/domainowners
chmod 644 /etc/virtual/domains
1.4 Run the script
chmod 755 /root/fix.sh
/root/fix.sh
1.5 Rebuild Majordomo
da build majordomo
---
2. Rebuilding /etc/virtual/domains if Missing
Create /etc/virtual/fix_domains.sh:
#!/bin/sh
echo `hostname`
for u in `ls /usr/local/directadmin/data/users`; do
{
for d in `cat /usr/local/directadmin/data/users/$u/domains.list`; do
{
echo "$d"
for p in `cat /usr/local/directadmin/data/users/$u/domains/$d.pointers 2>/dev/null | cut -d= -f1`; do
{
echo "$p"
}
done;
}
done;
}
done;
Run and fix permissions
cd /etc/virtual
chmod 755 fix_domains.sh
./fix_domains.sh > domains
chmod 644 domains
chown mail:mail domains
---
3. Rebuilding /etc/virtual/domainowners if Missing
Create /etc/virtual/fix_domainowners.sh:
#!/bin/sh
for u in `ls /usr/local/directadmin/data/users`; do
{
for d in `cat /usr/local/directadmin/data/users/$u/domains.list`; do
{
echo "$d: $u"
for p in `cat /usr/local/directadmin/data/users/$u/domains/$d.pointers | cut -d= -f1 2>/dev/null`; do
{
echo "$p: $u"
}
done;
}
done;
}
done;
Run and fix permissions
cd /etc/virtual
chmod 755 fix_domainowners.sh
./fix_domainowners.sh > domainowners
chmod 644 domainowners
chown mail:mail domainowners
---
4. Rebuilding a Single Domain Directory
If only one domain folder is empty, you can rebuild it manually:
cd /etc/virtual/domain.com
echo "fred: fred" > aliases
touch autoresponder.conf
touch filter
touch filter.conf
touch passwd
touch quota
touch vacation.conf
echo "*: :fail:" >> aliases
chown mail:mail *
mkdir -p majordomo
chmod 751 majordomo
chown majordomo:daemon majordomo
mkdir -p reply
chmod 700 reply
chown mail:mail reply
chown mail:mail .
Then re-add user mailboxes based on:
ls -la /home/fred/imap/domain.com
---
5. Resetting Permissions on All DirectAdmin System Files
If you migrated data to a new disk and permissions are incorrect, run:
cd /usr/local/directadmin/scripts
./set_permissions.sh all
To reset permissions for a specific domain:
./set_permissions.sh domaindir domain.com
---
6. Preventing useradd Locking Issues During Parallel Restores
When restoring many users in parallel, /etc/passwd may lock. Use a custom lock script.
6.1 Create pre creation lock script
/usr/local/directadmin/scripts/custom/user_create_pre/lock.sh
Content:
#!/bin/bash
LOCK=/etc/passwd.da_lock
ATTEMPTS=100
set -C
while [ $ATTEMPTS -gt 0 ]; do
ATTEMPTS=$(( ATTEMPTS-1 ))
2>/dev/null >$LOCK
RET=$?
if [ "$RET" = "0" ]; then
break
fi
sleep 0.2
done
if [ $ATTEMPTS -eq 0 ]; then
if [ -e /etc/passwd.lock ]; then
echo "Unable to get lock on $LOCK and /etc/passwd.lock still exists. User $username not created"
exit 1
fi
echo "Unable to get lock on $LOCK but /etc/passwd.lock does not exist. Proceeding anyway"
rm -f $LOCK
fi
exit 0
6.2 Create post creation cleanup script
/usr/local/directadmin/scripts/custom/user_create_post/lock.sh
Content:
#!/bin/bash
LOCK=/etc/passwd.da_lock
rm -f $LOCK
exit 0
6.3 Make both scripts executable
chmod 755 /usr/local/directadmin/scripts/custom/user_create_pre/lock.sh
chmod 755 /usr/local/directadmin/scripts/custom/user_create_post/lock.sh
This ensures only one useradd process runs at a time during mass restores.
Written & researched by Dr. Shahin Siami