linux系统中的数据文件有很多,在这一章里介绍的主要内容是和系统有关的一系列文件,包括passwd,shadow,group,utmp,wtmp以及一些系统的相关信息和时间的相关操作。
口令文件就是存在于目录/etc/passwd文件,它用来存储系统中的用户名,密码,用户ID,所属组ID,注释,起始工作目录和默认的shell。密码在早期是记录在这个文件中的,并且使用单向加密算法把密码加密成13个可读的ascii字符集,也就是说不可以对这13个字符集进行逆运算得到原来的密码。但是,由于可以通过这个文件对密码进行猜测,这里的猜测是指,我们可以指定一个密码,按照这种加密算法加密后,和passwd文件中的加密后的密码进行对照。所以处于安全的考虑,现在的linux系统都将密码存储在另一个文件/etc/shadow中。这样就可以对shadow文件的存取权限进行限制,从而保证了系统的安全性。
我们通过如下两个函数可以得到passwd文件的信息,如下:
struct passwd* getpwnam(const char* name); struct passwd* getpwuid(uid_t uid);
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 */ };
如果想要遍历passwd文件,需要使用三个函数:
#include <sys/types.h> #include <pwd.h> struct passwd *getpwent(void); void setpwent(void); void endpwent(void);
组文件就是用来保存组的一些信息,这个文件就是/etc/group文件。这个文件中包括了组名,组密码,组ID和组成员列表。与对passwd的操作类似,对组的操作也有如下这些函数:
#include <sys/types.h> #include <grp.h> struct group *getgrnam(const char *name); struct group *getgrgid(gid_t gid);
struct group { char *gr_name; /* group name */ char *gr_passwd; /* group password */ gid_t gr_gid; /* group ID */ char **gr_mem; /* group members */ };
#include <sys/types.h> #include <grp.h> struct group *getgrent(void); void setgrent(void); void endgrent(void);
添加组ID是用来给某一个用户添加一个组。对添加组ID所用到的操作包括:
#include <sys/types.h> #include <unistd.h> int getgroups(int size, gid_t list[]); #include <grp.h> int setgroups(size_t size, const gid_t *list);
utmp和wtmp这两个文件用来记录当前登录进系统的用户和系统的登录和注销事件。每次当一个用户登录系统时,就会填写一个utmp记录,并将这个记录写入到utmp文件和wtmp文件中,这个记录如下:
struct utmp { char ut_line[8]; char ut_name[8]; long ut_time; }
utmp用来记录当前系统中的登录用户,而wtmp文件用来记录系统的登录和注销的历史记录。每次当注销时,就会将utmp文件中对应的用户名清除,并且将注销的用户信息添加到wtmp中。使用 who 命令可以查看当前系统中,登录的用户,使用 who /var/log/wtmp 可以查看系统中的登录和注销的事件,或者使用 last 命令也可以查看系统的登录和注销事件。
uname这个函数用来获取和系统相关的一些信息,它的函数原型如下:
#include <sys/utsname.h> int uname(struct utsname *buf);
struct utsname { char sysname[]; /* Operating system name (e.g., "Linux") */ char nodename[]; /* Name within "some implementation-defined network" */ char release[]; /* OS release (e.g., "2.6.28") */ char version[]; /* OS version */ char machine[]; /* Hardware identifier */ #ifdef _GNU_SOURCE char domainname[]; /* NIS or YP domain name */ #endif };
在linux中,时间的记录是从1970年1月1日0时0分0秒开始经过的秒数,这个称为日历时间。可以使用如下函数获取:
#include <time.h> time_t time(time_t *t);