linux用户及密码的存储和校验方法

/etc/passwd文件

在passwd中,每一行代表一个用户记录,每条记录分为7个字段,字段间用':'分割,以下是每个字段的描述。

  • 用户名:用户绑定的名字
  • 加密后的密码(可选)
  • 用户id,用来标识用户
  • 用户组id,表示用户所属组
  • 用户描述信息
  • 用户的家目录
  • 用户命令解释器

如果第二项密码字段为一个小写的'x',则表示用户的密码存储在/etc/shadow文件中,即在/etc/shadow文件中也有一行对应该用户记录的记录。

/etc/shadow文件

shadow是一个包含系统帐户密码信息和可选时间信息的文件。shadow文件每一行代表一条记录,每一条记录有9个字段,以下是每个字段的描述。

登录用户名:必须对应到/etc/passwd文件中的一条记录中的用户登录名

  • 加密密码:加密后的密码字符串
  • 最后一次密码修改日期
  • 用户更改密码前必须等待的最小密码期限
  • 用户必须更改密码的最大密码期限
  • 密码过期警告时间
  • 密码不活动期
  • 用户到期时间
  • 保留,用于将来扩展其他属性

测试用户

新建一个用户test,设置密码为test,然后查看其passwd记录以及shadow记录。

1

2

3

4

5

6

7

8

9

10

11

12

13

└─$ sudo adduser --home /home/test --shell /bin/bash test

Adding user `test' ...

Adding new group `test' (1001) ...

configuration error - unknown item 'NONEXISTENT' (notify administrator)

configuration error - unknown item 'PREVENT_NO_AUTH' (notify administrator)

Adding new user `test' (1001) with group `test' ...

configuration error - unknown item 'NONEXISTENT' (notify administrator)

configuration error - unknown item 'PREVENT_NO_AUTH' (notify administrator)

Creating home directory `/home/test' ...

Copying files from `/etc/skel' ...

New password:

Retype new password:

passwd: password updated successfully

1

2

3

4

5

6

7

8

9

10

11

12

13

Changing the user information for test

Enter the new value, or press ENTER for the default

Full Name []:

Room Number []:

Work Phone []:

Home Phone []:

Other []:

Is the information correct? [Y/n] yes

└─$ cat /etc/passwd | grep test

test:x:1001:1001:,,,:/home/test:/bin/bash

└─$ sudo cat /etc/shadow | grep test

test:$y$j9T$1L/PH8ddqysyageBD6TnF1$MNm4An/z6LHdRq0JEOnFuviXBequ23gbIG8U1A/f4F.:19

112:0:99999:7:::

用户验证API

可使用crypt和shadow的api对用户和密码进行验证

1

2

3

4

5

6

7

8

9

10

11

12

13

14

#include <crypt.h>

#include <unistd.h>

char *crypt(const char *key, const char *salt);

/* General shadow password file API */

#include <shadow.h>

struct spwd *getspnam(const char *name);

struct spwd *getspent(void);

void setspent(void);

void endspent(void);

struct spwd *fgetspent(FILE *stream);

struct spwd *sgetspent(const char *s);

int putspent(const struct spwd *p, FILE *stream);

int lckpwdf(void);

int ulckpwdf(void);

下面的代码实例让用户输入用户名和密码,通过crypt和shadow API进行检验用户输入的用户名和密码是否匹配?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

#include <unistd.h>

#include <stdio.h>

#include <shadow.h>

#include <crypt.h>

#include <stdlib.h>

#include <errno.h>

#include <string.h>

/*

* user_auth - Authentication user name and password.

* @user: user name.

* @passwd: user password string.

*

* on success return 0, return errno on error.

*/

int user_auth(const char *user, const char *passwd)

{

  struct spwd *user_spwd;

  char *encrypted_pwd;

    if (!user || !passwd)

      return -EINVAL;

  user_spwd = getspnam(user);

    if (!user_spwd)

      return -errno;

  encrypted_pwd = crypt(passwd, user_spwd->sp_pwdp);

    if (!encrypted_pwd)

      return -errno;

      return abs(strcmp(encrypted_pwd, user_spwd->sp_pwdp));

}

int main(int argc, char *argv[])

{

  int ret; 

  char *user = argv[1];

  char *passwd = argv[2];

  ret = user_auth(user, passwd);

  if (ret < 0) {

    printf("user auth failed, ret=%d\n", ret);

    return ret;

}

  if (ret > 0) {

    printf("passwd not match, auth failed\n");

    return ret;

}

    printf("auth okay!\n");

    return 0;

}

编译该程序是指定链接库crypt

1

gcc auth.c -lcrypt

然后使用该程序验证我们添加的用户test,密码是test,正确的输入用户名和密码时输出结果如下:

1

2

└─$ sudo ./a.out test test

auth okay!

如果故意输入错误密码,再次执行得到如下结果:

1

2

└─$ sudo ./a.out test hello

passwd not match, auth failed

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sinat_40572875

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值