System Databases
UNIX systems maintain several databases that store information about users, groups, passwords, login sessions, and other system resources. Instead of reading these files directly, applications should use the standard library interfaces provided by the operating system. These interfaces provide portability, improve reliability, and isolate applications from implementation-specific file formats.
Learning Objectives
- Understand UNIX system databases.
- Learn why applications use database APIs.
- Study user and group databases.
- Understand database lookup functions.
- Prepare for practical programming examples.
1. What are System Databases?
System databases are collections of information maintained by the operating system to describe users, groups, login accounts, network configuration, and other system resources. Applications retrieve this information through standardized library functions instead of directly reading database files.
2. Why are System Databases Needed?
- Store user account information.
- Store group membership information.
- Support authentication mechanisms.
- Provide standardized access to system information.
- Improve application portability.
- Hide implementation-specific storage details.
3. Common UNIX System Databases
| Database | Typical File | Purpose |
|---|---|---|
| User Database | /etc/passwd |
User account information. |
| Group Database | /etc/group |
Group definitions. |
| Shadow Password Database* | /etc/shadow |
Password information (implementation-specific). |
| Login Accounting* | Implementation dependent | Login session records. |
*Availability and format depend on the operating system.
4. Why Use Database APIs?
Directly parsing system database files ties an application to a particular file format. Using the standard APIs allows applications to work correctly even if the underlying storage mechanism changes.
5. User Database
The user database stores information about user accounts, including user names, user identifiers, home directories, login shells, and related account information. Applications normally access this information using password database functions.
6. Group Database
The group database stores information about groups, including group names, group identifiers, and group membership. Applications use group database functions to retrieve this information.
7. Database Access Workflow
8. Advantages of Standard APIs
- Portable applications.
- Consistent programming interface.
- Improved maintainability.
- Reduced dependency on file formats.
- Simplified application development.
9. Applications Using System Databases
| Application | Purpose |
|---|---|
| Login Programs | Retrieve user account information. |
| Shells | Determine the user's login shell. |
| File Managers | Display user and group ownership. |
| System Utilities | Lookup user and group details. |
| Administrative Tools | Manage accounts and permissions. |
10. Interview Questions
- What are system databases?
- Why should applications use database APIs instead of parsing files directly?
- Name two common UNIX system databases.
- What information is stored in the user database?
- What information is stored in the group database?
- Why do standard APIs improve portability?
- Which file commonly stores user account information?
- Which file commonly stores group information?
- Why can the underlying storage implementation change without affecting applications?
- What types of applications commonly use system databases?
11. Password Database
The password database contains information describing user accounts. Applications use password database functions to retrieve user information without directly parsing the database file.
12. struct passwd
The password database functions return information using the
struct passwd structure.
13. Members of struct passwd
| Member | Description |
|---|---|
pw_name |
User login name. |
pw_passwd |
Password field (implementation dependent). |
pw_uid |
User ID. |
pw_gid |
Primary group ID. |
pw_gecos |
User description or account information. |
pw_dir |
Home directory. |
pw_shell |
Login shell. |
14. getpwuid()
The getpwuid() function searches the password database
using a user identifier (UID).
15. Example Using getpwuid()
16. getpwnam()
The getpwnam() function searches the password database
using a user name.
17. getpwent()
The getpwent() function sequentially returns entries from
the password database.
It is commonly used when every user entry needs to be examined.
18. Password Database Iteration
19. Related Password Database Functions
| Function | Purpose |
|---|---|
setpwent() |
Rewind the password database. |
endpwent() |
Close the password database. |
getpwent() |
Read the next password entry. |
getpwnam() |
Search by user name. |
getpwuid() |
Search by user ID. |
20. Interview Questions
- What information does the password database contain?
- Why should applications use
getpwuid()instead of parsing/etc/passwd? - What does
pw_uidrepresent? - What is stored in
pw_shell? - How does
getpwnam()differ fromgetpwuid()? - When is
getpwent()useful? - What is the purpose of
setpwent()? - Why should
endpwent()be called after iteration? - Which structure stores password database information?
- What header file declares password database functions?
21. Group Database
The group database stores information about system groups. Each group has a unique group identifier (GID), a group name, and a list of users who belong to that group. Applications access this information using the group database functions provided by the operating system.
22. struct group
Group database functions return information using the
struct group structure.
23. Members of struct group
| Member | Description |
|---|---|
gr_name |
Group name. |
gr_passwd |
Group password field (implementation dependent). |
gr_gid |
Group ID. |
gr_mem |
NULL-terminated array of member names. |
24. getgrgid()
The getgrgid() function searches the group database
using a group identifier (GID).
25. Example Using getgrgid()
26. getgrnam()
The getgrnam() function searches the group database
using a group name.
27. getgrent()
The getgrent() function returns successive entries
from the group database.
It is commonly used when every group entry must be examined.
28. Group Database Iteration
29. Related Group Database Functions
| Function | Purpose |
|---|---|
setgrent() |
Rewind the group database. |
endgrent() |
Close the group database. |
getgrent() |
Read the next group entry. |
getgrnam() |
Search by group name. |
getgrgid() |
Search by group ID. |
30. Interview Questions
- What information does the group database contain?
- Why should applications use
getgrgid()instead of reading/etc/groupdirectly? - What is stored in
gr_gid? - What is the purpose of
gr_mem? - How does
getgrnam()differ fromgetgrgid()? - When should
getgrent()be used? - What is the purpose of
setgrent()? - Why should
endgrent()be called? - Which header file declares the group database functions?
- Which structure represents a group database entry?
31. Shadow Password Database
Many UNIX and Linux systems store encrypted password information separately from the public password database. This improves system security because ordinary users can read the password database but cannot access encrypted password information. The exact implementation varies between operating systems.
32. Login Accounting Databases
Some UNIX systems maintain login accounting databases that record user login sessions, logout times, and system activity. The location and format of these databases are implementation-specific. Applications should use operating system interfaces instead of directly parsing database files.
33. Reentrant Database Functions
Traditional database lookup functions return pointers to static storage. For multithreaded programs, POSIX provides reentrant versions that store results in user-supplied buffers.
| Standard Function | Reentrant Version |
|---|---|
getpwnam() |
getpwnam_r() |
getpwuid() |
getpwuid_r() |
getgrnam() |
getgrnam_r() |
getgrgid() |
getgrgid_r() |
34. Why Use Reentrant APIs?
- Safe for multithreaded applications.
- Avoid shared static storage.
- Allow multiple concurrent lookups.
- Reduce race conditions.
- Improve application reliability.
35. Example Using getpwuid_r()
36. Useful Linux Commands
| Command | Purpose |
|---|---|
id |
Display user and group IDs. |
whoami |
Display current user name. |
groups |
Display group memberships. |
getent passwd |
Display password database entries. |
getent group |
Display group database entries. |
37. Complete Database Lookup Workflow
38. Best Practices
- Use standard library functions instead of parsing database files.
- Check return values for
NULL. - Use reentrant functions in multithreaded applications.
- Close sequential database access using
endpwent()andendgrent(). - Do not assume implementation-specific databases exist on every UNIX system.
39. Common Mistakes
- Reading
/etc/passwddirectly. - Ignoring API return values.
- Using non-reentrant functions in multithreaded code.
- Forgetting to terminate database iteration.
- Assuming identical database formats across UNIX implementations.
40. Interview Questions
- Why are shadow password databases used?
- Why are shadow databases considered implementation-dependent?
- What problem do reentrant database functions solve?
- How does
getpwuid_r()differ fromgetpwuid()? - Which functions should be used in multithreaded applications?
- What does the
idcommand display? - What information does the
groupscommand provide? - What is the purpose of the
getentcommand? - Why should applications avoid reading database files directly?
- Why is checking for
NULLimportant when performing database lookups?
41. Complete Practical Example
42. Password and Group API Comparison
| Password API | Group API | Purpose |
|---|---|---|
getpwuid() |
getgrgid() |
Lookup by numeric ID. |
getpwnam() |
getgrnam() |
Lookup by name. |
getpwent() |
getgrent() |
Sequential iteration. |
setpwent() |
setgrent() |
Restart iteration. |
endpwent() |
endgrent() |
Close database access. |
43. Complete Database Access Lifecycle
44. Key Takeaways
- Use standard database APIs instead of reading system database files.
- Password and group databases provide account information.
- Use lookup functions for specific users or groups.
- Use iteration functions when processing all entries.
- Use reentrant APIs in multithreaded programs.
- Always verify returned pointers before accessing structure members.
45. Advanced Interview Questions
- Why does UNIX provide database APIs instead of requiring applications to read database files directly?
- Explain the difference between
getpwuid()andgetpwnam(). - When would you use
getpwent()? - How does
struct passwddiffer fromstruct group? - Why are reentrant functions preferred in multithreaded applications?
- What is the purpose of
setpwent()andendpwent()? - What happens when a requested user or group does not exist?
- Why is the shadow password database considered implementation-specific?
- How do password and group database APIs improve portability?
- Which APIs are commonly used to obtain the current user's account information?
46. Common Programming Mistakes
- Dereferencing a NULL pointer returned by a lookup function.
- Reading implementation-specific database files directly.
- Using non-reentrant APIs in multithreaded programs.
- Ignoring failures returned by lookup functions.
- Forgetting to call
endpwent()orendgrent()after sequential access.
47. Module Summary
This module introduced the UNIX system databases used to store user and group information. It covered the password and group database structures, lookup functions, sequential access functions, reentrant interfaces, implementation-dependent databases, practical programming examples, Linux commands, and recommended programming practices. Understanding these interfaces allows applications to retrieve account information in a portable and reliable manner without depending on implementation-specific database formats.
Concept Mastery Assessment — Module 31
Verify your conceptual understanding with 12 targeted technical assessment questions. Instant feedback and explanations are provided for every choice.