User Management

Account Mechanics

  • A user is nothing more than a 32 bit unsigned number
  • The system defines an API (C Lib) that maps UID numbers back and forth
getpwuid()  # accepts a UID as an arg and returns information like login name, home dir
getpwnam()  # looks up the same info by login name

/etc/passwd

Historically, each user’s encrypted password was stored in the /etc/passwd. However computers got to powerful and cracking was trivial. In response UNIX and Linux moved passwords into a separate file (/etc/shadow). As a result /etc/passwd/ contains an x in field where password used to be.

# /etc/passwd
mat:x:1001:1001:Ubuntu:/home/mat:/usr/bin/zsh

# Breakdown
mat          # login name
x            # password (legacy)
1001         # uid
1001         # guid
Ubuntu       # GECOS full name, office, extension, home phoneC
/home/mat    # home directory
/usr/bin/zsh # login shell

Below is a breakdown of the fields

UID User Ids

  • 32 bit integer
  • root has UID 0

GID Group Ids

  • Same as UID a group ID is a 32 bit integer
  • GID 0 is reserved for the group called root, system or wheel

purpose: used to be to charge a group for compute time, minutes logged in. Now its to share file access

The /etc/group file defines the groups, with the GID field in /etc/passwd providing a default (or “effective”) GID at login time

Sharing

The default GID affects only file creation, not access checks. New files inherit your effective group, so sharing with a project group normally requires changing the file’s group ownership.

Setting the setgid bit on a directory (or using the grpid mount option) causes new files and directories to inherit the parent directory’s group automatically.

GECOS

Legacy used to be used to define Fullname and phone number, not really used anymore.

Home directory

  • default directory at user login time
  • login shells look for account specific customizations such as such alias and environment variables, ssh keys, etc.

Login Shell

The login shell is normally a command interpreter, but it can be any program

/etc/shadow

MD5-encrypted password fields in the shadow password file always start with $1$ or $md5$. Blowfish passwords start with $2$, SHA-256 passwords with $5$, and SHA-512 passwords with $6$.

Use vipw to edit this file and vipw -s to edit the shadow file

An example shadow entry

Only the values for the username and password are required

mat:$5$OrMAuk23$3KYdddxwEhugE.utSgmrHeJXRlXRTrOirOg.3rg19:20591:0:99999:7:::

mat                 # login name
# $ is the seperator for the encrypted pw fields
    5               # algorithm id (5 = SHA-256)
    OrMAuk23        # salt
    3KYddd...       # hashed pw
20591               # date of last pw change
0                   # min days between pw change
999999              # max days between pw changes
7                   # days to warn about pw expiration
                    # days after pw expiration to disable acc
                    # account expiration date
                    # unused field

/etc/group

NAME              PW OR PLACEHOLDER  GID    LIST OF MEMBERS
root              x                  0      
adm               x                  4      syslog,ubuntu,mat
nogroup           x                  65534  
mat               x                  1001   
kubeview          x                  988  

If your account has a default group set in /etc/passwd, you’re in that group even if /etc/group doesn’t list you as a member. There’s no point in having a user listed in both it’s redundant

Your final group memberships when you log in = everything from both files combined.

# /etc/passwd
  # default GID 1001 = mat
mat:x:1001:1001:Ubuntu:/home/mat:/usr/bin/zsh

Default Groups

Question

Why do we have default groups with a user’s name as the group name, seems pointless and redundant?

Answer

The UNIX tradition was originally to add new users to a group that represented their general category such as students or finance. However, this convention increases the likelihood that users will be able to read one another’s files because of slipshod permission settings, even if that is not really the intention of the files’ owner.
To avoid this problem, system utilities such as useradd and adduser now default to putting each user in his or her own personal group (that is, a group named after the user and which includes only that user). This convention is much easier to maintain if personal groups’ GIDs match their corresponding users’ UIDs.

Question

How are we supposed to share then?

Answer

To let users share files by way of the group mechanism, create separate groups for that purpose. The idea behind personal groups is not to discourage the use of groups per se—it’s simply to establish a more restrictive default group for each user so that files are not inadvertently shared.

Commands

groupadd
groupmod
groupdel

Pretty print password and other files into a table

# pretty print columns based on dilemeters
column -t -s : /etc/passwd
# root   x  0  0  root    /root      /bin/bash
# daemon x  1  1  daemon  /usr/sbin  /usr/sbin/nologin
# bin    x  2  2  bin     /bin       /usr/sbin/nologin
# sys    x  3  3  sys     /dev       /usr/sbin/nologin

# Same thing, but inject headers
(echo "USERNAME:PASSWORD:UID:GID:GECOS:HOME_DIR:SHELL" && cat /etc/passwd) | column -t -s :
(echo "NAME:PW OR PLACEHOLDER:GID:LIST OF MEMBERS" && cat /etc/group) | column -t -s :

Manually adding a user

Note

A program already exists that does all this: adduser or useradd

  • Edit the passwd and shadow files to define the user’s account.
  • Add the user to the /etc/group file (not really necessary, but nice)
  • Create, chown, and chmod the user’s home directory
  • Copy default startup files to the user’s home directory.
  • Set an initial password adduser/useradd doesn’t do this, use passwd

Setting a passwd

sudo passwd user

Creating home directories

There’s nothing magical about home directories.
If you neglected to include a home directory when setting up a new user, you can create it with a simple mkdir.
You need to set ownership and permissions (700 or 750 for groups) on the new directory as well, but this is most efficiently done after you’ve installed any local startup files.

Startup files traditionally begin with a dot and end with the letters rc, short for “run command,” a relic of the CTSS operating system. The initial dot causes ls to hide these “uninteresting” files from directory listings unless the -a option is used.

  • Sample startup files are traditionally kept in /etc/skel.
  • Linux also keeps fragments in /etc/profile.d for several shells.

typically looks like this:

cp -r /etc/skel/. /home/username/
chown -R username:username /home/username
chmod 700 /home/username

Forcing a pw change

Ensure the user changes their password:

  • Set the password to expire within a short time
  • Or have a script check their hash in /etc/shadow has been changed (could be the same password since salt changes the output but it’s something..)

Scripts for adding users

SystemCommandsConfiguration files
All Linuxuseradd, usermod, userdel/etc/login.defs
/etc/default/useradd
Debian/Ubuntuaadduser, deluser/etc/adduser.conf
/etc/deluser.conf
FreeBSDadduser, rmuser/etc/login.conf

a This suite wraps the standard Linux version and includes a few more features.

parameters stored in /etc/default/useradd include:

  • home directories
  • default shell for new users

This can all be configured via the CLI interface as well but this file sets defaults

useradd disables accounts by default you must configure a passwd.

useradd example

sudo useradd \
  -c "Alice Johnson" \  # full name
  -d /home/ajohnson \   # home directory
  -g developers \       # primary group (/etc/passwd)
  -G sudo \             # addition groups (/etc/groups)
  -m \                  # create home dir
  -s /bin/bash \        # login shell
  ajohnson              # username
sudo passwd ajohnson

# Results
# /etc/passwd
ajohnson:x:1002:1002:Alice Johnson:/home/ajohnson:/bin/bash
# /etc/groups - had to create manually with groupadd
developers:x:1002: 

adduser on Debian and Ubuntu

Pithy

useradd = low-level
adduser = do the right thing wrapper with sensible defaults