Configuring UID Ranges for Local vs AD Accounts in CentOS/Linux LDAP Integration


3 views

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:

  1. Check SELinux contexts: restorecon -Rv /home/
  2. Verify nsswitch order: local files should precede LDAP/SSS
  3. 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