html
Unix UIDs (User Identifiers) are numeric values assigned to system users. While POSIX standards don't explicitly mandate a specific bit size, most modern Unix-like systems use 32-bit unsigned integers (UID_MAX = 2³²-1). However, legacy systems or specific configurations might use 16-bit storage.
Here are reliable ways to determine UID storage size on any Unix system:
1. Using getconf utility
# Check maximum UID value
getconf UID_MAX
# Typical output:
# 32-bit system: 4294967295 (2³²-1)
# 16-bit system: 65535 (2¹⁶-1)
2. Checking system headers
# C program to check UID_MAX definition
#include <stdio.h>
#include <sys/types.h>
int main() {
printf("UID_MAX = %lu\n", (unsigned long)UID_MAX);
return 0;
}
# Compile and run:
# gcc uid_check.c -o uid_check
# ./uid_check
3. Kernel source inspection
For advanced users, examining kernel source reveals the actual storage:
# Check include/linux/uidgid.h in kernel sources
grep -r "typedef.*uid_t" /usr/src/linux/include/
The bit size affects:
- Maximum allowed UID (65535 vs 4294967295)
- Filesystem compatibility (some older FS formats may truncate UIDs)
- Network protocol handling (NFSv2 had 16-bit UID limitations)
Here's a portable shell script to check UID limits:
#!/bin/sh
MAX_UID=$(getconf UID_MAX 2>/dev/null)
if [ -z "$MAX_UID" ]; then
# Fallback method
if [ -f /usr/include/sys/types.h ]; then
MAX_UID=$(grep -E '#define[[:space:]]+UID_MAX' /usr/include/sys/types.h | awk '{print $3}')
fi
fi
case $MAX_UID in
65535) echo "16-bit UID system" ;;
4294967295) echo "32-bit UID system" ;;
*) echo "Unknown UID size (MAX=$MAX_UID)" ;;
esac
Early Unix systems (1970s-1980s) typically used 16-bit UIDs, while modern systems (Linux since 2.4+, *BSD, macOS) switched to 32-bit. The transition became necessary as large organizations exceeded the 16-bit limit.
Unix-like systems store user identifiers as numeric values, but the actual storage size varies across implementations. While most modern systems use 32-bit unsigned integers (allowing values up to 4,294,967,295), some legacy systems or special configurations might use 16-bit (max 65,535). The actual storage size affects system capabilities and compatibility.
Here are several methods to determine UID size on a given system:
# Method 1: Checking maximum UID in system headers
grep -E '^#define[[:space:]]+UID_MAX' /usr/include/*.h /usr/include/*/*.h 2>/dev/null
# Method 2: Using getconf (POSIX compliant)
getconf UID_MAX
# Method 3: Practical test with large UID
sudo useradd -u 999999 testuser 2>&1 | grep -i "invalid"
For more precise information, you can examine kernel parameters:
# Check kernel parameter for max UID
sysctl kernel.overflowuid
# Or check the actual type definition (requires kernel headers)
grep -r "typedef.*uid_t" /usr/include/
Here's a portable shell function to detect UID size:
detect_uid_size() {
local max_uid
if max_uid=$(getconf UID_MAX 2>/dev/null); then
if [ "$max_uid" -ge 4294967295 ]; then
echo "32-bit UID (or larger)"
elif [ "$max_uid" -ge 65535 ]; then
echo "16-bit UID"
else
echo "Unknown UID size (max: $max_uid)"
fi
else
echo "Unable to determine UID size - assuming 32-bit"
fi
}
When writing portable code, you might want to check this programmatically:
// C example
#include <sys/types.h>
#include <stdio.h>
int main() {
printf("UID size: %zu bits\n", sizeof(uid_t) * 8);
return 0;
}
Older Unix systems (particularly pre-POSIX implementations) often used 16-bit UIDs. Modern systems (Linux, BSD variants, macOS) typically use 32-bit. Some specialized systems or containers might impose lower limits. When dealing with legacy systems or embedded environments, it's worth verifying rather than assuming.