【Linux】系统数据文件和信息

Linux系统的正常运行需要使用大量与系统有关的数据文件,例如口令文件“/etc/passwd”和组文件“/etc/group”,这两种文件是经常被使用的,此外还有网路服务“/etc/services”、协议信息“/etc/protocols”、网络信息“/etc/networks”、主机数据“/etc/hosts”等。下面主要说明一下口令文件。

口令文件——

Linux系统的口令文件为ASCII文本,一般有下面一行:

root:x:0:0:root:/root:/bin/bash

上面共七个字段,以冒号分割,其数据结构在头文件“pwd.h”中定义,是一个名为passwd的struct,如下所示:

/* The passwd structure.  */
struct passwd
{
  char *pw_name;                /* Username.  */
  char *pw_passwd;              /* Password.  */
  __uid_t pw_uid;               /* User ID.  */
  __gid_t pw_gid;               /* Group ID.  */
  char *pw_gecos;               /* Real name.  */
  char *pw_dir;                 /* Home directory.  */
  char *pw_shell;               /* Shell program.  */
};

口令文件中每一行的各字段的含义分别为用户名、密码、用户ID、组ID、注释、用户根目录、登录shell。密码字段是一个占位符“x”,在早期的Linux系统版本中,该字段存放密码,但是将密码存放在一个人人可读的文件中构成了一个安全性漏洞,所以现在将密码存放在另一个位置,一种shadow口令文件中。命令finger可用于查看用户登录信息,命令vipw可以用于编辑相关口令文件。在头文件“pwd.h”中,还声明了一些与口令文件相关的函数,如下:

#include <pwd.h>
struct passwd *getpwuid(uid_t uid);
struct passwd *getpwnam(const char *name);
struct passwd *getpwent(void);
void setpwent(void);
void endpwent(void);

getpwuid以用户ID获取口令数据,getpwnam以用户名获取口令数据,getpwent用于读取口令文件,每次读取一行,setpwent设置口令文件读取偏移量到文件开始位置,endpwent用于关闭打开的口令文件。

shadow口令文件——

密码是用单向加密算法处理过的,如MD5算法,在某些Linux系统版本上,密码实际存放在shadow口令文件“/etc/shadow”中,例如我的用户名为evo,就有下面这么一行:

evo:$6$kuLgFlTH$eGxHb1X6PoyuIXJFNgB9IIKaLei6Xy3B19gY.UhPK7/Qv5HrF5D0q20AuvXIvzPjzizD7trj8Gutby3wtz3O9/:17058:0:99999:7:::

在头文件“shadow.h”中定义了对应的数据结构spwd和相关函数。

#include <shadow.h>
/* Structure of the password file.  */
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.  */
  };
struct spwd *getspnam(const char *name);
struct spwd *getspent(void);
void setspent(void);
void endspent(void);

组文件——

同理,“/etc/group”为组文件,其中的一行如下:

root:x:0:

在头文件“grp.h”中定义了对应的数据结构group和相关函数。

#include <grp.h>
/* The group structure.  */
struct group
  {
    char *gr_name;      /* Group name.  */
    char *gr_passwd;        /* Password.    */
    __gid_t gr_gid;     /* Group ID.    */
    char **gr_mem;      /* Member list. */
  };
struct group *getgrgid(gid_t gid);
struct group *getgrnam(const char *name);
struct group *getgrent(void);
void setgrent(void);
void endgrent(void);

在Linux中,用户同时只属于一个组,但还有一个附加组,附加组可以为用户指定多个所属组,也就是说用户除了实际的所属组外,还可以同时是附加组内的任何组。

除了上文提到的数据文件之外,大多数Linux系统还提供了“/var/run/utmp”和“/var/log/wtmp”两个数据文件,前者记录当前登录的各个用户,后者跟踪各个登录和注销事件。在shell中,命令“uname”可查看系统信息,“hostname”可查看主机信息,对应的,函数“uname”和“gethostname”可做同样的事情。

时间相关——

Linux内核提供的时间是从国际标准时间1970年1月1日零点开始经过的秒数,函数time可以获得这段秒数,即日历时间,gettimeofday则可以获得更精确的时间值。日历时间可读性差,结构体tm一个可读性好数据形式,包括年、月、日、时、分、秒等,函数gmtime可以把日历时间转换成国际标准时间的tm形式,考虑到本地时区和夏时制,localtime把日历时间转换成本地时间。函数mktime把时间的tm形式转换为日历时间,而asctime把时间的tm形式转换成了26字节的字符串,strftime则是对时间进行格式化。ctime函数把时间秒数转换为字符串。需要注意的是,localtime、mktime、strftime、ctime四个函数与环境变量TZ有关联,一个设置时区的环境变量。

#include <time.h>
time_t time(time_t *tloc);
size_t strftime(char *s, size_t max, const char *format,
                       const struct tm *tm);
#include <sys/time.h>
int gettimeofday(struct timeval *tv, struct timezone *tz);
          struct timeval {
               time_t      tv_sec;     /* seconds */
               suseconds_t tv_usec;    /* microseconds */
           };
          struct timezone {
               int tz_minuteswest;     /* minutes west of Greenwich */
               int tz_dsttime;         /* type of DST correction */
           };
struct tm *gmtime(const time_t *timep);
struct tm *localtime(const time_t *timep);
time_t mktime(struct tm *tm);
char *ctime(const time_t *timep);
char *asctime(const struct tm *tm);
          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 */
           };
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值