When integrating CentOS systems with Active Directory via LDAPS, we often encounter UID allocation conflicts between local accounts and domain-authenticated users. The default behavior assigns UIDs starting from 10000 for AD accounts, while local accounts traditionally begin at 500 (or 1000 on newer systems). This creates management challenges when:
- Scripts rely on predictable UID ranges
- File ownership needs clear distinction
- System auditing requires account type identification
The primary configuration files we need to modify:
/etc/login.defs
/etc/nsswitch.conf
/etc/samba/smb.conf (if using Samba)
For CentOS/RHEL systems, here's the optimal configuration approach:
# /etc/login.defs modifications
UID_MIN 500
UID_MAX 9999
SYS_UID_MIN 201
SYS_UID_MAX 499
# AD/LDAP UID range (set higher than local users)
LDAP_UID_MIN 10000
LDAP_UID_MAX 60000
For systems using SSSD (recommended for newer implementations):
# /etc/sssd/sssd.conf
[domain/your.domain]
ldap_id_mapping = True
ldap_idmap_range_min = 10000
ldap_idmap_range_max = 60000
ldap_idmap_default_domain_sid = S-1-5-21-...
Here's a sample Bash script to create local users within our defined range:
#!/bin/bash
# Local user creation script with UID range enforcement
UID_MIN=500
UID_MAX=9999
create_local_user() {
username=$1
next_uid=$(getent passwd | awk -F: -v min=$UID_MIN -v max=$UID_MAX \
'$3 >= min && $3 <= max {print $3}' | sort -n | tail -1)
next_uid=$((next_uid + 1))
[[ $next_uid -lt $UID_MIN ]] && next_uid=$UID_MIN
if [[ $next_uid -le $UID_MAX ]]; then
useradd -u $next_uid $username
echo "Created $username with UID $next_uid"
else
echo "Error: UID range exhausted (max $UID_MAX)"
exit 1
fi
}
# Usage:
create_local_user "webuser1"
Regularly audit your UID assignments:
# List all local users (500-9999 range)
getent passwd | awk -F: '$3 >= 500 && $3 <= 9999 {print}'
# List all AD users (10000+ range)
getent passwd | awk -F: '$3 >= 10000 {print}'
If you encounter problems after implementation:
- Check SELinux contexts:
restorecon -Rv /home/
- Verify nsswitch order: local files should precede LDAP/SSS
- Clear SSSD cache if needed:
sss_cache -E
When integrating CentOS 4 systems with Windows Server 2008 Active Directory via LDAPS, we encountered an interesting UID allocation issue. The system automatically assigns UIDs starting from 10000 for AD-authenticated users, while our local service accounts (webspace owners, daemons, etc.) traditionally used the 500+ range.
The default behavior comes from /etc/login.defs
configuration:
# Min/max values for automatic uid selection in useradd UID_MIN 10000 UID_MAX 60000
Local accounts typically start from UID 500 because of historical Unix conventions, while AD integration tools like sssd
or winbind
use higher ranges by default.
We can implement separation through these methods:
1. Modifying login.defs for Local Accounts
# /etc/login.defs changes UID_MIN 500 UID_MAX 9999
2. Configuring SSSD for AD Accounts
# /etc/sssd/sssd.conf [domain/your.ad.domain] ldap_idmap_range_min = 10000 ldap_idmap_range_max = 60000 ldap_idmap_default_domain_sid = S-1-5-21-...
3. Winbind Alternative Configuration
# /etc/samba/smb.conf [global] idmap config * : backend = tdb idmap config * : range = 10000-60000
For already created accounts, we need to manually adjust UIDs:
# Example script to modify existing local users for user in $(getent passwd | awk -F: '$3 >= 10000 && $3 <= 60000 {print $1}'); do newuid=$(getent passwd | awk -F: '$3 < 500 {print $3}' | sort -n | tail -1) newuid=$((newuid+1)) usermod -u $newuid $user done
To check your current UID allocations:
# Show all users and their UIDs getent passwd | awk -F: '{print $1,$3}' | sort -nk2 # Check for UID collisions getent passwd | cut -d: -f3 | sort | uniq -d
Implement these safeguards in your account creation scripts:
#!/bin/bash # Safe local user creation script MAX_LOCAL_UID=9999 requested_uid=500 # Find next available UID below threshold while getent passwd $requested_uid >/dev/null; do requested_uid=$((requested_uid+1)) [ $requested_uid -gt $MAX_LOCAL_UID ] && { echo "No available UIDs"; exit 1; } done useradd -u $requested_uid "$username"
Remember that some system components may cache UID information, so restart relevant services after making changes:
# For SSSD service sssd restart # For Winbind service winbind restart