6 系统数据文件和信息
6.2 口令文件
#include <pwd.h>
struct passwd *getpwuid(uid_t uid); /* 查看用户登录名 */
struct passwd *getpwnam(const char *name); /* 查看用户ID */
return: pointer; error: NULL
struct passwd *getpwent(void); /* 查看整个口令文件,返回口令文件中的下一个记录项,到达最后返回NULL */
return: pointer; error: NULL
void setpwent(void); /* 反绕它所使用的文件 */
void endpwent(void); /* 关闭这些文件 */
struct passwd
{
char * pw_name; /* Username, POSIX.1 */
char * pw_passwd; /* Password */
__uid_t pw_uid; /* User ID, POSIX.1 */
__gid_t pw_gid; /* Group ID, POSIX.1 */
char * pw_gecos; /* Real Name or Comment field */
char * pw_dir; /* Home directory, POSIX.1 */
char * pw_shell; /* Shell Program, POSIX.1 */
};
1.通常有一个登录项,其用户名为root,其用户ID是0(超级用户).
2.加密口令字段包含了经单向密码算法处理过的用户口令副本.
3.口令文件中的某些字段可能为空.(如果密码口令为空,意味着没有密码)
4.支持finger命令的某些unix系统支持注释字段中的附加信息.
6.3 阴影口令文件
#include <shadow.h>
struct spwd *getspnam(const char *name);
struct spwd *getspend(void);
retrun: struct pointer; error: NULL.
void setspend(void);
void endspend(void);
struct spwd
{
char *sp_namp; /* Login name */
char *sp_pwdp; /* Encrypted password */
long int sp_lstchg; /* Date of last change */
long int sp_min; /* Minimum number of days between changes */
long int sp_max; /* Maximum number of days between changes */
long int sp_warn; /* Number of days to warn user to change the password */
long int sp_inact; /* Number of days the account may be inactive */
long int sp_expire; /* Number of days since 1970-01-01 until account expires */
unsigned long int sp_flag; /* Reserved */
};
对unix口令通常使用的加密算法是单向算法.给出一个密码口令,找不到一种算法可以将其反变换到普通文本口令(普通文本口令是在Password:提示后键入的口令).但是可以猜测,比如用跟用户相关的事物进行猜测密码然后经单向算法加密形成,这样就存在了泄密的可能,所以要避免.
为使企图这样做的人难以获得加密口令,某些系统将加密口令存放在另一个通常称为阴影口令(shadow password)的文件中.
6.4 组文件
#include <grp.h>
struct group *getgrgid(gid_t gid);
struct group *getgrnam(const char *name);
return: struct pointer; error: NULL.
struct group{
char *gr_name; /* Group name */
char *gr_passwd; /* password */
__gid_t gr_gid; /* Group ID */
char **gr_mem; /* Member list */
};
struct group *getgrent(void);
return: struct pointer; error: NULL.
void setgrent(void);
void endgrent(void);
包含组名,加密口令,数字组ID,指向各用户名指针的数组.
6.5 附属组ID
#include <unistd.h>
int getgroups(int gidsetsize, gid_t grouplist[]);
return: groupID's quantity; error: -1.
#include <grp.h> /* on Linux */
#include <unistd.h> /* On FreeBSD, Mac OS X, and Solaris */
int setgroups(int ngroups, const git_t grouplist[]);
#include <grp.h> /* On Linux and Solaris */
#include <unistd.h> /* On FreeBSD and Mac OS X */
int initgroups(const char *username, gid_t basegid);
return: 0; error: -1.
setgroups函数可由超级用户调用以便为调用进程设置添加组ID表.
grouplist是组ID数组,而ngroups说明了数组中的元素数.
6.6 其他数据文件
已提到过两个系统数据文件–口令文件和组文件.
记录各网络服务器所提供的服务的数据文件:/etc/services
记录协议信息的数据文件:/etc/protocols
记录网络信息的数据文件:/etc/networks
主机:/etc/hosts
6.7 登录会计
大多数unix系统都提供下列两个数据文件:
utmp:它记录当前登录进系统的各个用户
wtmp:它跟踪各个登录和注销事件
6.8 系统标识
uname函数,它返回与主机和操作系统有关的信息.
#include <sys/utsname.h>
int uname(struct utsname *name);
return: !0; error: -1.
#include <unistd.h>
int gethostname(char *name, int namelen);
return: 0; error: -1.
struct utsname {
char sysname[]; // name of the OS.
char nodename[]; // name of this node.
char release[]; // current release of OS.
char version[]; //current version of this release.
char machine[]; // name of hardware type.
};
6.9 时间和日期例程
#include <time.h>
time_t time(time_t *calptr); //获取当前的时间和日期
return: time value; error: -1.
struct tm *gmtime(const time_t *calptr);//将日历时间转换协调统一时间的年,月,日,时,分,秒,周日分解结构。
struct tm *localtime(const time_t *calptr);//将日历时间转换成本地时间(考虑本地时区和夏令时标志)
return: 指向分解的tm结构的指针; error: NULL.
time_t mktime(struct tm *tmptr); //以本地时间的年月日等作为参数,转变为time_t值
return: time_t value; error: -1.
下面strftime函数是一个类似于printf的时间值函数,可通过可用的多个参数来制定产生的字符串.
size_t strftime(char *restrict buf, size_t maxsize, const char *restrict format, const struct tm *restrict tmptr);
return: 若有空间,返回存入数组的字符数,error: 0.
size_t strftime_l(char *restrict buf, size_t maxsize, const char *restrict format, const struct tm *restrict tmptr, locale_t locale);
return: 若有空间,返回存入数组的字符数,error: 0.
struct tm {
int tm_sec; //seconds after the minute:[0-60]
int tm_min; //minutes after the hour:[0-59]
int tm_hour;//hours after the 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
}
#include <sys/time.h>
int clock_gettime(clockid_t clock_id, struct timespec *tsp); // 获取指定时钟的时间,精度比time高
return: 0; error: -1.
int clock_getres(clockid_t clock_id, struct timespec *tsp); //将tsp指向的timespec结构初始化为clock_id参数对应的时钟精度
return: 0; error: -1.
int clock_settime(clockid_t clock_id, const struct tiemsepc *tsp); // 对特定时钟设置时间
return: 0; error: -1.
int gettimeofday(struct timeval *restrict tp, void *restrict tzp); //函数已弃用,提供了比time更高的精度(微秒级)
return: 0