《UNIX 环境高级编程》笔记0x5:系统数据文件和信息

此为第六章笔记


口令文件

/etc/passwd,其中每一行的格式如下

1
<用户名>:<加密口令>:<用户ID>:<组ID>:<注释字段>:<初始工作目录>:<初始shell>

禁止用户的登录的方式是对最后的 <初始shell> 进行设置,为: /usr/sbin/nologin/bin/true/bin/false。用户ID(65534)和组ID(65534)不提供任何特权。

可调用的结构体 passwd 定义在 <pwd.h>

1
2
3
4
5
6
7
8
9
10
11
/* 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. */
};

下面是使用系统调用的一个例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <apue.h>
// #include <stddef.h>
#include <string.h>
#include <pwd.h>

struct passwd * getpwnam(const char *name)
{
struct passwd *ptr;

setpwent();
while ((ptr = getpwent()) != NULL)
if (strcmp(name, ptr->pw_name) == 0)
break;
endpwent();

return ptr;
}

int main(int argc, char *argv[])
{
struct passwd* result = getpwnam("parallels");
exit(EXIT_SUCCESS);
}

结果如下

image1.png


阴影口令

加密口令是经过单向加密算法处理过的用户口令副本。算法为单向的。为了保护加密口令,系统将加密口令存放到另一个通常被称为阴影口令(shadow password)的文件中。Linux中为 /etc/shadow,每一行的格式如下

1
<1>:<2>:<3>:<4>:<5>:<6>:<7>:<8>:<9>
  1. 用户登录名
  2. 加密口令
  3. 上次更改口令以来经过的时间
  4. 经过多少天后允许更改
  5. 要求更改尚余天数
  6. 过期警告天数
  7. 账号不活动之前尚余天数
  8. 账户超期天数
  9. 保留

组文件

1
<组名>:<加密口令>:<组ID>:<组中的用户>

例子

1
2
3
adm:x:4:syslog,parallels
sudo:x:27:parallels
www-data:x:33:

使用c语言读取流程同上。数据结构存放在 <grp.h>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <apue.h>
// #include <stddef.h>
#include <string.h>
#include <grp.h>

struct group * get_grp_ptr(const char *name)
{
struct group *ptr;

setgrent();
while ((ptr = getgrent()) != NULL)
if (strcmp(name, ptr->gr_name) == 0)
break;
endgrent();

return ptr;
}

int main(int argc, char *argv[])
{
struct group* result = get_grp_ptr("adm");
exit(EXIT_SUCCESS);
}

允许结果如下

image2.png


其他数据文件

  • /etc/services 记录各网络服务器所提供服务的数据文件
  • /etc/protocols 记录协议信息的数据文件
  • /etc/networks 记录网络信息的数据文件

image3.png


处理时间

详细信息略,将 PDFp171

各个时间函数之间的关系

image4.png


C语言调用

格式化日期 tm 如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
struct tm
{
int tm_sec; /* Seconds. [0-60] (1 leap second) */
int tm_min; /* Minutes. [0-59] */
int tm_hour; /* Hours. [0-23] */
int tm_mday; /* Day. [1-31] */
int tm_mon; /* Month. [0-11] */
int tm_year; /* Year - 1900. */
int tm_wday; /* Day of week. [0-6] */
int tm_yday; /* Days in year.[0-365] */
int tm_isdst; /* DST. [-1/0/1]*/

# ifdef __USE_MISC
long int tm_gmtoff; /* Seconds east of UTC. */
const char *tm_zone; /* Timezone abbreviation. */
# else
long int __tm_gmtoff; /* Seconds east of UTC. */
const char *__tm_zone; /* Timezone abbreviation. */
# endif
};

下面编写一个函数获取当前的时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <apue.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

int main(int argc, char *argv[])
{
time_t t;
struct tm *tmp;
char buf[64];

time(&t);
tmp = localtime(&t);

if (strftime(buf, 64, "time and date: %r, %a %b %d, %Y", tmp) == 0)
printf("erro when strftime");
else
printf("%s\n", buf);

exit(EXIT_SUCCESS);
}

执行结果如下

image5.png