> For the complete documentation index, see [llms.txt](https://book.bsdcn.org/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://book.bsdcn.org/ask/flat/chapter-14-user-accounts-and-permissions/di-14.1-jie-yong-hu-he-ji-ben-zhang-hu-guan-li.md).

# 14.1 Users and Basic Account Management

All access to the FreeBSD system is achieved through accounts, and all processes are run by users, therefore user and account management is the foundation of system security.

FreeBSD provides various user management tools. The `adduser` command adds new users interactively, automatically performing operations such as creating passwd entries, constructing new user home directories, and copying default configuration files from **/usr/share/skel**.

adduser(8) is a shell script that internally calls pw(8) to perform the actual user database operations. adduser(8) is not unique to FreeBSD; OpenBSD and DragonFly BSD also have their own implementations of adduser(8), but the options and behaviors differ.

The `pw` command is a lower-level user and group management tool that supports non-interactive batch operations and can directly modify system user database files.

User account information is stored in the master.passwd(5) file, which contains fields such as username, encrypted password, UID, GID, login class, password expiration time, account expiration time, GECOS information, home directory, and login shell.

## Account Types

A valid user account is required to log in to the FreeBSD system.

The following shows users directly observed through the password file **/etc/master.passwd**:

```ini
root:$6$huh5iMfeueumGM3B$ycd9HsGOzKfFq6hbWMxceNBRCLibbSj5Ofjv/ed6Kq60M2F.syaGaxfdfYMqB79DZzqyhQlIiRZ4.D9ST90Gv/:0:0::0:0:Charlie &:/root:/bin/sh
toor:*:0:0::0:0:Bourne-again Superuser:/root:
daemon:*:1:1::0:0:Owner of many system processes:/root:/usr/sbin/nologin
operator:*:2:5::0:0:System &:/:/usr/sbin/nologin

……some entries omitted……

www:*:80:80::0:0:World Wide Web Owner:/nonexistent:/usr/sbin/nologin
ntpd:*:123:123::0:0:NTP Daemon:/var/db/ntp:/usr/sbin/nologin
nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/usr/sbin/nologin
ykla:$6$SqMJXrv5aC6Wq.by$nmbZs078aHNBVyh9noLFouJsGHyFSvQIzH0W4zpdfXuPtGtt.FHgWfXDHVBa.g9P0eZ32UwfByzRKdVnTaO7W.:1001:1001::0:0:User &:/home/ykla:/bin/sh
```

It can be seen that several user accounts exist in the system.

There are three main types of accounts in FreeBSD: system accounts, regular user accounts, and the superuser account.

### System Accounts

System accounts are used to run services such as DNS, mail, and web servers. If all services run as the superuser, their operations will be unrestricted; this is the security rationale for using system accounts.

System accounts are defined by the [main/etc/master.passwd](https://github.com/freebsd/freebsd-src/blob/main/etc/master.passwd) file in the source code, totaling 27 as of this writing (26 accounts with UID < 1000 plus nobody(65534); this number may change with version iterations). `_dhcp` and `ntpd` are examples of such system accounts. System accounts are dedicated accounts with restricted permissions, typically used to run system services and daemons.

`nobody` is a generic unprivileged system account, but the more services use `nobody`, the more files and processes are associated with that user, and the greater its privileges become. Therefore, the best practice is to assign a separate system account to each service rather than sharing `nobody`.

### Regular User Accounts

Regular user accounts are assigned to actual users for logging in and using the system. To facilitate administrators tracking user actions and prevent users from interfering with each other's settings, every person accessing the system should have a unique user account.

`ykla` is a regular user account created during system installation. If you want to switch to the `root` user via the `su` command, you must add this user to the `wheel` group. Additionally, some user accounts are system users automatically created by Ports.

Each user account on the FreeBSD system is associated with several attributes:

| Attribute                   | Description                                                                                                                                                                                                                                         |
| --------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Username**                | The name entered at the `login:` prompt; each user must have a unique username. passwd(5) documents the rules for creating valid usernames. It is recommended to use eight or fewer lowercase characters as the username for backward compatibility |
| **Password**                | Each account has an associated password                                                                                                                                                                                                             |
| **User ID (UID)**           | A number used to uniquely identify a user in the FreeBSD system. Since higher values may cause compatibility issues with some software, it is recommended to use UIDs less than 65535                                                               |
| **Group ID (GID)**          | A number used to uniquely identify the primary group to which a user belongs. It is recommended to use a GID of 65535 or lower                                                                                                                      |
| **Login Class**             | An extension of the group mechanism, providing additional flexibility when customizing the system for different users                                                                                                                               |
| **Password Change Time**    | By default, passwords do not expire, but password expiration can be enabled on a per-user basis                                                                                                                                                     |
| **Account Expiration Time** | By default, FreeBSD does not expire accounts                                                                                                                                                                                                        |
| **Full Name**               | The username uniquely identifies a FreeBSD account, but does not necessarily reflect the user's real name                                                                                                                                           |
| **Home Directory**          | The starting directory when a user logs in. A common convention is to place all user home directories under **/home/username** or **/usr/home/username**                                                                                            |
| **User Shell**              | The shell provides the default environment for user interaction with the system                                                                                                                                                                     |

Note that although regular users have limited privileges, the more software they run, the larger the system's attack surface becomes, providing more vulnerability entry points for attackers to exploit. Attackers can only leverage these processes for privilege escalation if the programs have vulnerabilities or are misconfigured.

### Superuser Account

The superuser account, commonly referred to as root, is used for unrestricted system administration. Unlike regular user accounts, the superuser's operations are unrestricted, and misuse can lead to catastrophic consequences. Regular user accounts cannot damage the operating system through accidental actions, so it is recommended to log in as a regular user and switch to the superuser only when a command requires additional privileges.

In fact, the kernel determines whether an account has root privileges based on whether the account's EUID (Effective User ID) is `0`. See: main/sys/kern/kern\_priv.c\[EB/OL]. \[2026-03-26]. <https://github.com/freebsd/freebsd-src/blob/main/sys/kern/kern_priv.c> in the `if (suser_enabled(cred))` code block.

There are multiple ways to obtain superuser privileges. Although it is possible to log in directly as root, this is not recommended; it is advisable to use the su(1) command to switch to the superuser.

## Account Management

FreeBSD provides several different commands for managing user accounts.

**Tools for Managing User Accounts**

| Command      | Summary                                                                    |
| ------------ | -------------------------------------------------------------------------- |
| adduser(8)   | Recommended command-line application for adding new users.                 |
| rmuser(8)    | Recommended command-line application for removing users.                   |
| chpass(1)    | A flexible tool for changing user database information.                    |
| passwd(1)    | A command-line tool for changing user passwords.                           |
| pw(8)        | A powerful and flexible tool that can modify all aspects of user accounts. |
| bsdconfig(8) | A system configuration tool with account management support.               |

### adduser Creating Users

The recommended program for adding new users is the script adduser(8). When adding a new user, this program automatically updates **/etc/passwd** and **/etc/group**.

adduser also creates a home directory for the new user and copies default configuration files from **/usr/share/skel** (source code path `share/skel`). The source code path for `adduser` is `usr.sbin/adduser/adduser.sh`.

adduser(8) is interactive and guides the creation of new user accounts step by step. As shown below, enter the required information or press **Enter** to accept the default values in brackets.

In this example, the user is invited to join the `wheel` group, enabling them to become the superuser via su(1).

After completion, the tool will prompt whether to create another user or exit.

Example: Create a regular user `ykla` and add it to the `video` group:

```sh
# adduser -G video -s sh -w yes
# Username: ykla
```

Example: Create user test and add it to the wheel group, setting its default shell to sh:

```sh
# adduser # This tool must be run by the superuser
Username: test # Username ①
Full name:  # Full name, can be left empty
Uid (Leave empty for default): # UID setting, can be left empty
Login group [test]: # Login group
Login group is test. Invite test into other groups? []: wheel # Set groups to join, separate multiple with spaces, can be left empty
Login class [default]: # Login class, can be left empty
Shell (sh csh tcsh nologin) [sh]: sh  # Unless the default Shell is manually set, the default Shell is sh
Home directory [/home/test]: # Specify home directory
Home directory permissions (Leave empty for default): # Specify home directory permissions
Enable ZFS encryption? (yes/no) [no]: # Whether to use ZFS encryption
Use password-based authentication? [yes]:  # Whether to use a password
Use an empty password? (yes/no) [no]:   # Whether to use an empty password
Use a random password? (yes/no) [no]:   # Whether to use a random password
Enter password: # Enter password
Enter password again: # Re-enter password
Lock out the account after creation? [no]: # Lock account?
Username   : test
Password   : *****
Full Name  :
Uid        : 1002
ZFS dataset : zroot/home/test
Class      :
Groups     : test wheel
Home       : /home/test
Home Mode  :
Shell      : /bin/sh
Locked     : no
OK? (yes/no): yes # Check for errors
adduser: INFO: Successfully created ZFS dataset (zroot/home/test).
adduser: INFO: Successfully added (test) to the user database.
Add another user? (yes/no): no # Need to create another account?
Goodbye!
```

> **Note**
>
> Since passwords are not printed on the screen when entered, nor displayed as mask characters `*`, please create user accounts carefully.

* ① Login name naming has some restrictions, see passwd(5)\[EB/OL]. \[2026-03-26]. <https://man.freebsd.org/cgi/man.cgi?query=passwd&sektion=5>. However, please note that login names do not support eight-bit encoded character sets, for example Chinese is not supported (i.e., only specific ASCII characters are supported).

Only root can use this command; otherwise, the following error will be displayed:

```sh
$ adduser test
adduser: ERROR: you must be the super-user (uid 0) to use this utility.
```

This indicates that only users with UID 0 (typically root) can invoke the adduser command.

### rmuser Deleting Users

> **Warning**
>
> `rmuser` will permanently delete the user account and all related information including the home directory and mail, and this operation is irreversible. Using the `-y` parameter will skip the confirmation step, so make sure the username is correct.

`rmuser` is used to delete users. Like the `adduser` command, it is also an interactive script. The source code path for `rmuser` is `usr.sbin/adduser/rmuser.sh`.

Example: Delete users test1 test2.

```sh
# rmuser -y test1 test2 # Delete users test1 and test2 simultaneously
Removing user (test1): mailspool home passwd.
Removing user (test2): home passwd.
```

The `-y` parameter is used to skip the confirmation step.

### chpass Changing User Information

All users can use chpass(1) to change their default shell and personal account information. The chpass source code is located at `usr.bin/chpass`.

Example: A regular user opens and modifies current user information using the nvi text editor.

```sh
$ chpass ykla       # Modify ykla's account information database
#Changing user information for ykla.
Shell: /bin/sh      # User shell
Full Name: User &   # User full name
Office Location:    # Office location
Office Phone:       # Office phone
Home Phone: # Home phone
Other information:  # Other information
~
~
~
/etc/pw.ogzb33: unmodified: line 1
```

root can use this tool to change additional account information for any user.

```sh
# chpass ykla       # Modify ykla's account information database
#Changing user information for ykla.
Login: ykla # Specify ykla
Password: $6$SqMJXrv5aC6Wq.by$nmbZs078aHNBVyh9noLFouJsGHyFSvQIzH0W4zpdfXuPtGtt.FHgWfXDHVBa
.g9P0eZ32UwfByzRKdVnTaO7W.  # User password
Uid [#]: 1001
Gid [# or name]: 1001
Change [month day year]:    # Password change date
Expire [month day year]:    # Account expiration date
Class:      # User class
Home directory: /home/ykla  # User home directory
Shell: /bin/sh
Full Name: User &
Office Location:
Office Phone:
Home Phone:
Other information:
~
~
~
/etc/pw.mDp9q3: unmodified: line 1
```

Example: Change user test1's login environment to **/bin/sh**.

```sh
# chpass -s sh test1
chpass: user information updated
```

Commonly used parameter: `-s`, used to modify the login shell.

> **Tip**
>
> chfn(1) and chsh(1) are linked commands to chpass(1), as are ypchpass(1), ypchfn(1), and ypchsh(1). Since NIS support is automatic, there is no need to prefix the command with `yp`. This can be inferred from the source code `usr.bin/chpass/Makefile`:
>
> ```makefile
> SYMLINKS= chpass ${BINDIR}/chfn
> SYMLINKS+=        chpass ${BINDIR}/chsh
> .if ${MK_NIS} != "no"     # If the system has NIS enabled
> SYMLINKS+=        chpass ${BINDIR}/ypchfn
> SYMLINKS+=        chpass ${BINDIR}/ypchpass
> SYMLINKS+=        chpass ${BINDIR}/ypchsh
> .endif
>
> MLINKS=   chpass.1 chfn.1 chpass.1 chsh.1
> .if ${MK_NIS} != "no"
> MLINKS+= chpass.1 ypchpass.1 chpass.1 ypchfn.1 chpass.1 ypchsh.1
> .endif
> ```

### passwd Changing User Password

To change a user's password; if no user is specified, the current user is assumed. Regular users can only change their own passwords; otherwise, the following error will be displayed:

```sh
$ passwd test
passwd: permission denied
```

Example: Use ykla to change its own password.

```sh
$ passwd ykla
Changing local password for ykla
Old Password:       # Enter old password
New Password:       # Enter new password
Retype New Password:        # Re-enter new password
```

The root user can change all users' passwords without requiring the old password.

Example: Use root to change user ykla's password.

```sh
# passwd ykla
Changing local password for ykla
New Password:       # Enter new password
Retype New Password:        # Re-enter new password
```

> **Tip**
>
> FreeBSD's `passwd` options differ from Linux; for locking/unlocking accounts, use `pw lock/unlock`.

## Group Management

A group is a list of users. A group is identified by its group name and GID. In FreeBSD, the kernel uses the process's UID and its group list to determine the range of operations a process can perform. In most cases, the user or process GID usually refers to the first group in the list.

The mapping of group names to GIDs is listed in **/etc/group**. **/etc/group** is a plain text file with four colon-separated fields.

```sh
# cat /etc/group
wheel:*:0:root,ykla #
operator:*:5:root

……partial output omitted……

ykla:*:1001:
test:*:1002:
```

It can be seen that the format of **/etc/group** is like `group_name:encrypted_password:GID:member_list`, separated by colons.

The superuser can modify **/etc/group** using a text editor, but editing errors may cause serious consequences, so this is not recommended. It is recommended to use pw(8) to add and edit groups.

> **Warning**
>
> The `operator` group may grant unexpected superuser-like access privileges, including but not limited to shutdown (`shutdown`) and access to some devices in **/dev** (such as disk devices), so please be careful when using this group. Note that `reboot` and `halt` are restricted to root users only; operator group members cannot execute them.

In FreeBSD, the `pw` command can be used to manage users and groups: it is a front-end to the system user and group files. pw(8) provides very powerful command-line options suitable for shell scripts, but may be more complex for new users than other commands in this section.

### Adding Groups

Use pw(8) to add groups:

```sh
# pw groupadd ykla2
# pw groupshow ykla2
ykla2:*:1002:
```

In this example, 1002 is the GID of ykla2. At this point, ykla2 has no members.

### Adding Users to Groups

Use pw(8) to add users to groups.

Example: Set the members of group test5 to test1.

```sh
# pw groupmod test5 -M test1 # Existing members will be deleted!
```

Example: Add user `ykla` to both `ykla2` and `wheel` groups:

```sh
# pw usermod ykla -G ykla2,wheel
```

`-G` group list, comma-separated.

Verify as follows:

```sh
# id ykla
uid=1001(ykla) gid=1001(ykla) groups=1001(ykla),0(wheel),1002(ykla2)
```

Example: Add user `test` to the `wheel` group (the `wheel` group is a system default group and does not need to be created):

```sh
# pw groupmod wheel -m test
```

In this example, the argument passed to `-m` is a list of users (comma-separated) that are appended to the group and do not replace existing users.

### Deleting Groups

Example: Delete the `admin` group:

```sh
# pw groupdel admin
```

### Removing Users from Groups

Example: Remove user `ykla` from the `admin` group:

```sh
# pw groupmod admin -d ykla
```

### Adding Users

The `pw useradd` command is used to create new users.

Example: Create user test1.

```sh
# pw useradd test1 # uid system default, test1 group, login environment /bin/sh, home directory not created
```

Example: Create user test2.

```sh
# pw useradd test2 -u 1200 -m -d /tmp/test -g test2 -G wheel -s sh -c test2 # Create user test2: UID 1200, create home directory /tmp/test, primary group test2, supplementary wheel group, login shell sh, full name test2
```

### Modifying User Information

The `pw usermod` command is used to modify user information.

Example:

```sh
# pw usermod test1 -l test2 # Rename user test1 to test2
```

The `-l` option modifies the username.

### Deleting Users

The `pw userdel` command is used to delete users.

> **Warning**
>
> `pw userdel -r` will permanently delete the user and their home directory and all related information, and this operation is irreversible. If the home directory is a ZFS dataset, pw(8) only deletes the files within it and does not destroy the dataset; you must manually execute `zfs destroy` to destroy the dataset and its child datasets and snapshots. Please make sure the username is correct.

Example: Delete user test2 and its home directory.

```sh
# pw userdel -r test2
```

Commonly used parameter: `-r` deletes the user along with the home directory and all related information; without this parameter, only the user is deleted and the information is retained. If the home directory is a ZFS dataset, pw(8) only deletes the files within it and does not destroy the dataset; you must manually execute `zfs destroy` to destroy the dataset and its child datasets and snapshots.

### Displaying User Information

The `pw usershow` command is used to display user information.

Example: Display detailed information for user test2.

```sh
# pw usershow test2
test2:$6$FkxPcs2y.Y8cxyuj$kVDoV1LC.IWKGlSitll3oLArF18aHQYID0JYE.TUuD0YFgba.c7MbGs3xLnmpCZyu1nVKHhNqW2X7a57qN0xg/:1201:1201::0:0:User &:/home/test2:/bin/sh
```

### Modifying Group Information

The `pw groupmod` command is used to modify group information.

Example: Change the gid of group test to 1300.

```sh
# pw groupmod test -g 1300
```

Example: Rename group test to test2.

```sh
# pw groupmod test -l test2
```

## References

* FreeBSD Project. pw(8)\[EB/OL]. \[2026-03-26]. <https://man.freebsd.org/cgi/man.cgi?query=pw&sektion=8>. Manual page, introducing user and group management commands.

## Exercises

1. Modify the FreeBSD source code to enable UTF-8 encoding support for usernames.
2. Review the source code implementation of the pw command in FreeBSD and make it more modernized.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://book.bsdcn.org/ask/flat/chapter-14-user-accounts-and-permissions/di-14.1-jie-yong-hu-he-ji-ben-zhang-hu-guan-li.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
