Is there a standardized mechanism in Linux which can be used to tie usernames to user IDs without actually creating a system account that can log in?

It would seem something like this is possible, given that there is the ability to connect to a Windows server and give UIDs to the users. Usually in a high number range.

What I need/want this for is to be able to assign meaningful names to groups and users that only exist as subordinate IDs ().

I would think this could be accomplished with something related to nss(5) but came up empty-handed.

A bit of background

Visual representation of userns

On the host system usually 64k UIDs (and GIDs) are in use, however 0..2^32-1 is the range of available user IDs. So we can assign sub-ranges from that overall range as subordinate IDs for given users. E.g. we could say that the range 100000..2^32-1 is assigned to user root in the root namespace.

In terms of LXC (), which makes use of userns, the root namespace lives on the host and subordinate IDs are mapped into child namespaces, such that a range of UIDs on the host 100000..165535 inside the child namespace will appear as 0..65535.

Accordingly files owned by root inside the child namespace will appear to be owned by UID 100000 on the host.

Therefore it would be useful if I could assign a meaningful name to this "virtual" UID 100000 in the host system without actually having to create a user account.

This is what I am looking for.

Right now I am using this helper script as a workaround. Feel free to use it under the terms prescribed by StackExchange or Public Domain/CC0 terms:

#!/usr/bin/env bash
LXCPATH=$(lxc-config lxc.lxcpath)

function create-group
        local NAME=$1
        local GUEST=$3
        local GUESTCONF="/etc/lxc/guests/lxc.$GUEST.conf"
        local BASEID=$(awk '$1 ~ /^lxc\.id_map$/ && $3 ~ /^g$/ {print $5}' "$GUESTCONF" || echo "0")
        local ID=$(($2+$BASEID))
        echo "groupadd -g $ID $NAME"

function create-user
        local NAME=$1
        local GUEST=$3
        local GUESTCONF="/etc/lxc/guests/lxc.$GUEST.conf"
        local BASEID=$(awk '$1 ~ /^lxc\.id_map$/ && $3 ~ /^u$/ {print $5}' "$GUESTCONF" || echo "0")
        local ID=$(($2+$BASEID))
        echo "useradd -M -N -u $ID -s /usr/sbin/nologin $NAME"

function create-entry
        local GUEST=$1
        local DATABASE=$2
        local FUNCTION=$3
        local entry; local NAME; local ID
        for entry in $(awk -F : '{print $1 ":" $3}' "$DATABASE"); do
                if getent ${DATABASE##*/} $NAME; then
                        echo "Entry $NAME (${DATABASE##*/}) already exists"
                        $FUNCTION $NAME ${entry#*:} $GUEST

for guest in $(lxc-ls -1); do
        create-entry $guest "$LXCPATH/$guest/rootfs/etc/group"  create-group
        create-entry $guest "$LXCPATH/$guest/rootfs/etc/passwd" create-user
done|sort -u|while read cmd; do
        echo "$cmd"

It requires awk (mawk or gawk), bash, getent, groupadd, useradd. If you comment out the line:


you will simply get the output of all the commands it would otherwise run. It adds the user and group IDs in ascending order. However, it does assume that the lxc.id_map entry is in a file named after the LXC guest with the file name following the scheme /etc/lxc/guests/lxc.${guestname}.conf. You may want to adjust that setting.

You can re-run the script if you add users inside your guests.

This will

  • An answer should contain a reference to authoritative documentation about such mechanism. I'll add a 50 or 100 rep reward for answers that provide a method that is purely script-driven (no compilation of code required). – 0xC0000022L Feb 28 '15 at 21:33
  • You can create an account that can't log in by specifying /sbin/nologin or /bin/false or similar as a shell, but I'm not sure if that's what you're asking. Are you trying to make users from one namespace visible outside that namespace? – Gilles Mar 1 '15 at 1:15
  • @Gilles: in a sense, yes. The subordinate IDs are visible in the parent ns; and file ownership is accordingly. So it'd be nice if for the different sub-ID ranges, say 100000..165535 for a container foo I could somehow make sure that lookup of the UID 100000 yields foo-root. Of course I know I could create actual accounts in shadow which have login disabled (however PAM may still allow them in, e.g. for SSH with keys). With Samba it would be possible to get users from the AD without actually creating them in shadow. I'll amend my question. – 0xC0000022L Mar 1 '15 at 10:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.