1. Password File
For security reasons, the user's logon password is encrypted in the/etc/shadow file. According to the spwd structure, encryption is a one-way encryption algorithm, which means that you cannot obtain the original password through the encrypted password, but can only verify whether it is correct through the original password, provides similar access functions. However, the user's encrypted password in shadow cannot be read.
1) POSIX.1 only defines two functions for getting the password file. Given the user login name or numeric user ID, these two functions allow us to search for related items
# Include <pwd. h> struct passwd * getpwuid (uid_t uid); struct passwd * getpwnam (const char * name); // if both are successful, a pointer is returned. If the two succeed, NULL is returned.
The getpwuid function is used by the ls program. It maps the numeric user id value in the I node to a user login name. When you type the login name, The getpwnam function is used by the login (1) function.
2) the following three functions can be used by the program to view the entire password file:
# Include <pwd. h> struct passwd * getpwent (void); // if the pointer is returned successfully, or if the pointer fails or the end of the file is returned, NULL is returned. Void setpwent (void); void endpwent (void );
When getpwent is called, it returns the next record item in the password file. The setpwent function bypasses the files it uses, and endpwent closes these files. After you use getpwent to view the password file, be sure to call endpwent to close these files
2. Shadow password
To make it more difficult to obtain the original data (encrypted password), some systems store the encrypted password in another file, usually called the shadow password. This file must contain at least the user name and the encrypted password. Other password-related information also exists in this file. See the following table:
| File/etc/shadow domain |
| Description |
Struct spwd Member |
| User Login Name |
Char * sp_namp |
| Encrypted password |
Char * sp_pwdp |
| Number of days from Epoch when the password is last modified |
Int sp_lstchg |
| Until the allowed days are changed |
Int sp_min |
| Need to change the previous days |
Int sp_max |
| Warning Password Expiration days |
Int sp_warn |
| Number of days before Account Expiration |
Int sp_inact |
| Number of days since Epoch when the account expires |
Int sp_expire |
| Retained |
Unsigned int sp_flag |
Similar to a group of functions that access the password file, another group of functions can be used to access the shadow password file.
# Include <shadow. h> struct spwd * getspnam (const char * name); struct spwd * getspent (void); // if both are successful, a pointer is returned; otherwise, NULL is returned. Void setspent (void); void endspent (void );
3. group files
1). You can use the two functions defined by POSIX.1 below to view the group name or group ID.
# Include <grp. h> struct group * getgrgid (gid_t gid); struct group * getgrnam (const char * name); // if both are successful, a pointer is returned; otherwise, NULL is returned.
Like the password file function, both functions usually return a pointer to a static variable, which is overwritten each time a call is made.
2) if you need to find the entire group file, you need to use several other functions. The following three functions are similar to the three functions for the password file:
# Include <grp. h> struct group * getgrent (void); // a pointer is returned for success. If the pointer fails or the end of the file returns NULL. Void setgrent (void); void endgrent (void );
4. Additional group ID
The advantage of using the additional group ID is that we no longer need to explicitly change the group
# Include <unistd. h> int getgroups (int gidsetsize, gid_t grouplist []); // The number of IDS added to the group is returned successfully, and-1 is returned for the error. # Inlcude <grp. h>/* on Linux */# inlcude <unistd. h>/* on FreeBSD, Mac OS X, and Solaris */int setgroups (int ngroups, const gid_t grouplist []); # inlcude <grp. h>/* on Linux and Solaris */# inlcude <unistd. h>/* on FreeBSD and Mac OS X */int initgroups (const char * username, gid_t basegid); // if both are successful, 0 is returned; otherwise,-1 is returned.
5. Other data files
Each data file has at least three functions.
1) The get function reads the next record and opens the file if necessary. These functions usually return a pointer to a struct. When the end of the file is reached, a null pointer is returned. Most get functions return a pointer to a static struct, so if we want to save it, we always need to copy it.
2). set function. If the file is not open, open the file and roll back the file. This function is used when we know that we want to start from the beginning of the file again.
3). end item to close the data file. As we mentioned earlier, we always need to call it when we finish the work to close all the files.
The following table lists the get, set, and end functions of all data files:
| Similar functions used to access system data files |
| Description |
Data Files |
Header file |
Struct |
Supplemented keyword search function |
| Password |
/Etc/passwd |
<Pwd. h> |
Passwd |
Getpwnam, getpwuid |
| Group |
/Etc/group |
<Grp. h> |
Group |
Getgrnam, getgrgid |
| Shadow |
/Etc/shadow |
<Shadow. h> |
Spwd |
Getspanam |
| Host |
/Etc/hosts/ |
<Netdb. h> |
Hostent |
Gethostbyname, gethostbyaddr |
| Network |
/Etc/networks |
<Netdb. h> |
Netent |
Getnetbyname, getnetbyaddr |
| Protocol |
/Etc/protocols |
<Netdb. h> |
Protoent |
Getprotobyname, getprotobynumber |
| Service |
/Etc/services |
<Netdb. h> |
Servent |
Getservbyname, getservbyport |
6. login account records
Most UNIX systems provide two data files: The utmp file, which records all users currently logged on to the system; the wtmp file, which records all login and logout events. In V7, a record type is written by these two files, and a binary record consistent with the following struct
struct utmp { char ut_line[8]; /* tty line: "tyh0", "ttyd0", "ttyp0", ... */ char ut_name[8]; /* login name */ long ut_time; /* seconds since Epoch */};
7. System ID
1) POSIX.1 defines the uname function, which returns information about the current host and operating system.
# Include <sys/utsname. h> int uname (struct utsname * name); // if the call succeeds, a non-negative value is returned, and-1 is returned if the call fails.
A utsname struct:
struct utsname { char sysname[]; /* name of the operating system */ char nodename[]; /* name of hits node */ char release[]; /* current release of operating system */ char version[]; /* current version of this release */ char machine[]; /* name of hardware type */};
2) The BSD-based system provides the gethostname function to return only the host name. This name is usually the host name on the TCP/IP network.
# Include <unistd. h> int gethostname (char * name, int namelen); // success returns 0, Failure Returns-1.
The namelen parameter specifies the name buffer length. If sufficient space is provided, the returned string ends with null. If you do not provide enough space, you do not specify whether the string ends with null.
8. time and date routines
1) The time function returns the current time and date.
# Include <time. h> time_t time (time_t * calptr); // a time value is returned for success, and-1 is returned for error.
2). The gettimeofday function provides better precision (accurate to microseconds) than the time function)
# Include <sys/time. h> int gettimeofday (struct timeval * restrict tp, void * restrict tzp); // return value: always returns 0.
Timeval struct
struct timeval { time_t tv_sec; /* seconds */ long tv_usec; /* microseconds */};
3). localtime and gmtime
# Include <time. h> struct tm * gmtime (const time_t * calptr); struct tm * localtime (const time_t * calptr); // both return the pointer of the decomposition time.
The localtime and gmtime functions convert the calendar time to a struct tm called the broken-down time:
struct tm { /* a broken-down time */ int tm_sec; /* seconds after the minute: [0 - 60] */ int tm_min; /* minutes after the hour: [0-59] */ int tm_hour; /* hours after midnight:[0-23] */ int tm_mday; /* day of the month: [1-31] */ int tm_mon; /* months since January: [0-11] */ int tm_year; /* years since 1900 */ int tm_wday; /* days since sunday: [0-6] */ int tm_yday; /* days since January 1: [0-365] */ int tm_isdst; /* daylight saving time flag: <0, 0, >0 */};
The difference between localtime and gmtime is that the first one converts the calendar time to the local time based on the time zone and the Daylight Saving Time sign, while the latter converts the calendar time into a decomposition time expressed as UTC.
4). The mktime function accepts a decomposition time expressed as the local time and converts it into a time_t value.
# Include <time. h> time_t mktime (struct tm * tmptr); // If the calendar time is returned successfully, error-1 is returned.
5). The asctime and ctime functions produce familiar 26-byte strings
# Include <time. h> char * asctime (const struct tm * tmptr); char * ctime (const time_t * calptr); // both return strings ending with null.
6). strftime is the most complex. It is a function with a time value similar to printf.
# Include <time. h> size_t strftime (char * restrict buf, size_t maxsize, const char * restrict format, const struct tm * restrict tmptr ); // if the space is sufficient, return the number of characters stored in the array; otherwise, return 0.
The final parameter is the time value required by the format, specified by a pointer to the decomposition time value. The formatted structure is stored in the buf array of maxsize. If the size of the result of terminating null can be included in the buffer, the function returns the number of characters stored in buf, excluding terminating null. Otherwise, the function returns 0.