Linux/Unix System Programming Manual Reading Notes
Chapter 2
This chapter describes users and groups, including the/etc/passwd, shadow,/etc/shadow, and/etc/group.
Each user has a user name and a user ID (UID ). A user can belong to a group. Each group has a unique group name and associated Group Identifier (GID ).
Users and groups are used as follows: 1. Ownership of various system resources can be determined; 2. permissions granted to processes to access these resources are controlled.
First, let's take a look at the password file/etc/passwd.
lancelot@debian:~$ /etc/::root:/root:/bin/::daemon:/usr/sbin:/bin/::bin:/bin:/bin/::sys:/dev:/bin/:x::::/bin:/bin/::games:/usr/games:/bin/:x::::/var/cache/:/bin/:x::::/var/spool/lpd:/bin/::mail:/var/mail:/bin/::news:/var/spool/news:/bin/::uucp:/var/spool/uucp:/bin/::proxy:/bin:/bin/-data:x:::www-data:/var/www:/bin/::backup:/var/backups:/bin/::Mailing List Manager:/var/list:/bin/::ircd:/var/run/ircd:/bin/::Gnats Bug-Reporting System (admin):/var/lib/gnats:/bin/::nobody:/nonexistent:/bin/:::/var/lib/libuuid:/bin/:::/var/run/dbus:/bin/::colord colour management daemon,,,:/var/lib/colord:/bin/::usbmux daemon,,,:/home/usbmux:/bin/-exim:x::::/var/spool/exim4:/bin/::Avahi mDNS daemon,,,:/var/run/avahi-daemon:/bin/::PulseAudio daemon,,,:/var/run/pulse:/bin/-dispatcher:x:::Speech Dispatcher,,,:/var/run/speech-dispatcher:/bin/::HPLIP system user,,,:/var/run/hplip:/bin/:::/var/run/sshd:/usr/sbin/::RealtimeKit,,,:/proc:/bin/:::/var/lib/nfs:/bin/:::/home/saned:/bin/-gdm:x:::Gnome Display Manager:/var/lib/gdm3:/bin/::lancelot,,,:/home/lancelot:/bin/::MySQL Server,,,:/nonexistent:/bin/:x::: daemon,,,:/srv/:/bin/:::/nonexistent:/bin/
The first field is the login name; the second field is the encrypted password (x). In fact, the encrypted password is stored in the shadow password file;
The third field is the user ID (UID); the fourth field is the group ID (GID); the fifth field is the comment;
The sixth field is the main directory, which is the initial path after the user logs on. The seventh field is the logon shell.
Next let's look at the shadow password file that stores the actual password/etc/shadow
The format is as follows:
lancelot:$$tnTgvJYU$OhoUNZNIeNU7rlZf/f14oD2g.Uz8SbrnWeZbR4yL4XXRvzbCeijsAZE7Y9HlzU4thKVBVcqucwntJBi/4BoY60::::!:::::*::::*:::::::
Obviously, the first field is the user login name, the second field is the encrypted password, and the following field is the security-related field.
After reading the user, let's look at the group file/etc/group
lancelot@debian:~$ /etc/:x::x::x:-data:x:-cert:x:-exim:x::x:-access:x:-gdm:x::x::
The first field is the group name, the second field is the encrypted password, the third field is the group ID (GID), and the fourth field is the user list.
The encrypted password is stored in a file (/etc/gshadow) similar to/etc/shadow. The format is as follows:
cdrom:***:***-data:**********::lancelot
The last field is obviously a user list.
Next, let's look at how to get the information mentioned above through the library function.
1. Obtain records from/etc/shadow:
#include <pwd.h> passwd *getpwnam( * passwd *getpwuid(uid_t uid);
Getpwnam () returns a pointer to the corresponding password Record Based on the provided login name. Getpwuid () is a pointer to the corresponding password Record Based on the provided uid.
If an error occurs, NULL is returned.
PS:
This should be the answer to Exercise 8-1.
8-1: When you execute the following code, you will find that although the two users correspond to different IDs in the password file, however, the output of this program will display the same number twice. Why?
Printf ("% ld \ n", (long) (getpwnam ("avr")-> pw_uid), (long) (getpwnam ("tsr ") -> pw_uid ));
Then I tested the Code as follows:
# Include <stdio. h> # include <pwd. h> main (argc, * printf (, () (getpwnam ()-> pw_uid), () (getpwnam ()->}View Code
Test results:
lancelot@debian:~/Code/tlpi$ ./
Then the whole person is messy ..............
Later, I changed the program to the following:
#include <stdio.h> #include <pwd.h> main( argc, * passwd *p1, * p1 = getpwnam( p2 = getpwnam( printf(, p1->pw_uid, p2-> }
To output the same value, because the two pointer variables point to the same address. But the previous one is correct, because the function parameters are transmitted in a value-based manner, so there is no question that the two values are the same.
Later I looked for the author's website's incorrect: http://www.man7.org/tlpi/errata/index.html
I found that the question of this question has been modified !!!!!!
In this way, the pointer is passed, and the names of the two outputs are the same ..............
The author's explanation is as follows:
Okay, I will modify the errors in the book later .......
PS: Try again to prove that no matter how simple the example is .....
2. Obtain records from/etc/group
#include <grp.h> group *getgrnam( * group *getgrgid(gid_t gid);
Getgrnam returns the pointer to the group's password Record Based on the provided group name. getgrigid returns the pointer Based on the provided group number GID. If the call fails, NULL is returned.
PS: these two functions are also non-reentrant functions.
3. Scan password files and group files
#include <pwd.h> passwd *getpwent( setpwent( endpwent();
Getpwent () can return records one by one. Setpwent () can be reset. The starting position of the/etc/passwd file. Endpwent () can close files.
4. Retrieve records from the/etc/shadow password file
#include <shadow.h> spwd *getspnam( * spwd *getspent( setspent( endspent();
Getspnam and getspent return the pointer to the shadow password record. If the call fails, NULL is returned.
Setspent is reset to the starting position of the file, and endspent closes the file.
V. Password Encryption
_XOPEN_SOURCE #include <unistd.h> *crypt( *key, key *salt);
# Define _ XOPEN_SOURCE is used to obtain the crypt declaration.
Key is the entered password. salt points to a two-byte string used to change the DES algorithm. If the call succeeds, the encrypted password is returned. If the call fails, NULL is returned.
------------------- Tucao: It is really nice to write a blog and think about it when writing a blog. You need to read more books, code more, and think more ---------------------------
I heard from my colleagues that many of you have already found an internship. I really regret your failure. It is because of regret that we must do better !!!!
Continue to work !!!!!!
Certificate ---------------------------------------------------------------------------------------------------------------------------------------------------
Exercise:
8-2: Use sptwent (), getpwent (), and endpwent () to implement getpwnam ().
This is a simple question, because getpwent () is a one-by-one query, and the query matches the output. After the output, call sptwent to reset the file offset to the starting position of the file. Call endpwent to close the file.
#include <pwd.h> #include <.h> #include <stdio.h> #include passwd * Getpwnam( * passwd * ((pwd = getpwent()) != (strcmp(pwd->pw_name, name) == main( argc, * passwd * (argc < || strcmp(argv[], ) == usageErr(, argv[ (i = ; i < argc; ++ p = Getpwnam(( * (p == printf( printf(, argv[i], ()p->pw_uid, ()p-> }
Test results:
lancelot@debian:~/Code/tlpi$ ./, GID: , GID: