口令文件
linux中passwd结构包含10个字段中的7个,每个字段用:分隔
用户名:加密口令:用户ID:组ID:注释字段:初始工作目录:初始shell
yzq:x:1000:1000:,,,:/home/yzq:/bin/bash
按照上面的字段顺序,出现passwd结构体
struct passwd {
char *pw_name; /* username */
char *pw_passwd; /* user password */
uid_t pw_uid; /* user ID */
gid_t pw_gid; /* group ID */
char *pw_gecos; /* user information */
char *pw_dir; /* home directory */
char *pw_shell; /* shell program */
};
getpwuid、getpwname
//传入一个用户id,返回该用户的详细信息
struct passwd *getpwuid(uid_t uid);
//传入一个用户name,返回该用户的详细信息
struct passwd *getpwnam(const char *name);
组文件
根目录下/etc/group就是组文件,用于保存用户组的所有信息。
linux中group结构有四个字段
组名:加密口令:组ID:指向各用户名指针的数组
yzq:x:1000:
同样有个结构体
struct group {
char *gr_name; /* group name */
char *gr_passwd; /* group password */
gid_t gr_gid; /* group ID */
char **gr_mem; /* NULL-terminated array of pointers
to names of group members */
};
getgrgid、getgrgrnam
//通过gid查询组的所有信息
struct group *getgrgid(gid_t gid);
//通过name查询组的所有信息
struct group *getgrnam(const char *name);
阴影口令
/etc/shadow 文件,用于存储 Linux 系统中用户的密码信息,又称为“影子文件”。前面介绍了 /etc/passwd 文件,由于该文件允许所有用户读取,易导致用户密码泄露,因此 Linux 系统将用户的密码信息从 /etc/passwd 文件中分离出来,并单独放到了shadow文件中。
同 /etc/passwd 文件一样,文件中每行代表一个用户,同样使用 “:” 作为分隔符,不同之处在于,每行用户信息被划分为 9 个字段。
用户名:加密密码:最后一次修改时间:最小修改时间间隔:密码有效期:密码需要变更前的警告天数:密码过期后的宽限时间:账号失效时间:保留
yzq:$6$N6IhIX8foeKuzK.6$sgX.nRp5kAjzv2tbldw.4HQt9wSMACx9JCiNmwS6xoysJIfbIGFhLRlujhiu0MrSk1OMOpGxXOR/r2367lzto.:18924:0:99999:7:::
struct spwd {
char *sp_namp; /* Login name */
char *sp_pwdp; /* Encrypted password */
long sp_lstchg; /* Date of last change
(measured in days since
1970-01-01 00:00:00 +0000 (UTC)) */
long sp_min; /* Min # of days between changes */
long sp_max; /* Max # of days between changes */
long sp_warn; /* # of days before password expires
to warn user to change it */
long sp_inact; /* # of days after password expires
until account is disabled */
long sp_expire; /* Date when account expires
(measured in days since
1970-01-01 00:00:00 +0000 (UTC)) */
unsigned long sp_flag; /* Reserved */
};
getspnam
通过name获得其在shadow文件中的一行内容
struct spwd *getspnam(const char *name);
该函数可以配合crypt函数(用于加密)
时间
time
time_t time(time_t *tloc);
此函数会返回从公元 1970年1月1日的UTC时间从0时0分0秒算起到现在所经过的秒数
两种用法:
time_t stamp;
time(&stamp);
//或者这样写
stamp = time(NULL);
成功则返回秒数,失败则返回((time_t)-1)值,错误原因存于errno 中。
gmtime、localtime
两个函数都用于将time_t类型的内容转换为一个tm结构体
//gmtime返回的时间日期未经时区转换,而是UTC时间。
struct tm *gmtime(const time_t *timep);
//localtime返回的时间日期已经转换成当地时区。
struct tm *localtime(const time_t *timep);
struct tm {
int tm_sec; /* Seconds (0-60) */
int tm_min; /* Minutes (0-59) */
int tm_hour; /* Hours (0-23) */
int tm_mday; /* Day of the month (1-31) */
int tm_mon; /* Month (0-11) */
int tm_year; /* Year - 1900 */
int tm_wday; /* Day of the week (0-6, Sunday = 0) */
int tm_yday; /* Day in the year (0-365, 1 Jan = 0) */
int tm_isdst; /* Daylight saving time */
};
mktime
mktime用于将tm类型的参数转换为time_t类型
time_t mktime(struct tm *tm);
注意gmtime和localtime的形参都是有const修饰的,说明函数体不会转换时不会修改time_t类型。但是这里没有const修饰,意味着mktime在转换时可能会修改tm的内容。因为mktime会先判断时间是否合法,比如月份如果溢出会进行调整等等
strftime
格式化日期和时间,也就是将结构体类型向格式化字符串进行转换
size_t strftime(char *s, size_t max, const char *format, const struct tm *tm);
前两个参数共同指定了一块缓冲区,将最多max个内容放入s中。内容从tm中得到,并且是按照format的格式。
time_t stamp;
time(&stamp);
struct tm *ptm = localtime(&stamp);
strftime(buf, BUFSIZE, "%Y-%m-%d", ptm);
puts(buf);