概述
在哪里
首先还是要简单的说下账户与密码都在哪里。
Linux系统中,所有用户(包括系统管理员)的账号和密码都可以在/etc/passwd和/etc/shadow这两个文件中找到。
查看权限可发现passwd文件谁都可以查看,而shadow只有root及同组用户可以
-rw-r–r-- 1 root root 1912 10月 15 2018 passwd
-rw-r----- 1 root shadow 1127 10月 15 2018 shadow
都有啥
首先查看下passwd文件有啥内容
hqz@ubuntu:/etc$ less passwd
上面每一行都代表一个用户,每一行又通过[:]分为七个部分。
1、账号名称
2、原先用来保存密码的,现在密码都放在/etc/shadow中,所以这里显示x
3、UID,也就是使用者ID。默认的系统管理员的UID为0,我们添加用户的时候最好使用1000以上的UID,1-1000范围的UID最好保留给系统用。
4、GID,也就是群组ID
5、关于账号的一些说明信息(暂时可以忽略)
6、账号的家目录,家目录就是你登陆系统后默认的那个目录
7、账号使用的shell(不确定)
接着我们来查看 shadow文件
这里也是由[:]来进行分割,但是这里一共分出来九个栏目,每个栏目的解释如下:
1. 账户名称
2.加密后的密码,如果这一栏的第一个字符为!或者*的话,说明这是一个不能登录的账户,从上面可以看出,ubuntu默认的就不启用root账户。密码格式为:$id$salt$encrypted
id表示加密算法。起初密码用DES算法加密,单随着DES加密破解难度的降低,已用其他加密算法替代DES。在shadow文件中,密码字段如果以“$”打头,则表示非DES加密
常见标识:
salt 最多可以是16个字符,encrypted 则根据不同的加密算法有固定的长度。如下图:
3. 最近改动密码的日期(不是日期吗,咋是一堆数字,别急,这个是从1970年1月1日算起的总的天数)。那怎么才能知道今天距1970年1月1日有多少天呢?很简单,你改下密码,然后看下这个栏目中的数字是多少就可以了!
4. 密码不可被变更的天数:设置了这个值,则表示从变更密码的日期算起,多少天内无法再次修改密码,如果是0的话,则没有限制
5. 密码需要重新变更的天数:密码经常更换才能保证安全,为了提醒某些经常不更换密码的用户,可以设置一个天数,强制让用户更换密码,也就是说该用户的密码会在多少天后过期,如果为99999则没有限制
6. 密码过期预警天数:如果在5中设置了密码需要重新变更的天数,则会在密码过期的前多少天进行提醒,提示用户其密码将在多少天后过期
7. 密码过期的宽恕时间:如果在5中设置的日期过后,用户仍然没有修改密码,则该用户还可以继续使用的天数
8. 账号失效日期,过了这个日期账号就不能用了
9. 留的
进入正题
正题是啥,账号密码的匹配,打字好累,直接上代码吧
#define _XOPEN_SOURCE //定义该宏,使crypt函数有效
#include <shadow.h>
#include <pwd.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h> //crypt
//extern char *crypt(const char *key, const char *salt); //函数不声明默认返回类型位整形。
int main(char argc,char* argv[])
{
if(argc < 2)
{
perror("argument is not invalidn");
return -1;
}
struct spwd *pwd = getspnam(argv[1]); //从shadow文件获取账户信息
char salt[16] = {0};
if(pwd)
{
printf("shadow code:%sn",pwd->sp_pwdp); //$1$I/c8gPVE$tpbQU1MysIhYOAkWaAbiZ1 两个 $ 之间为 salt 数据,用于加密,原始数据 +salt 会生成 shadow 里的密码
strncpy(salt,pwd->sp_pwdp,15); //测试发现至少11位才行
printf("salt:%sn",salt);
}
else
{
perror("get passwd fail");
return -1;
}
struct passwd *pw = getpwnam(argv[1]); //从passwd文件中获取账户信息
printf("code:%sn",pw->pw_passwd); //x
char *cpwd = crypt(argv[2], salt);//合成shadow 中的密码
if(!cpwd)
{
perror("crypt errorn");
return;
}
if(!strcmp(cpwd,pwd->sp_pwdp))
{
puts("密码匹配成功n");
}
else
{
puts("密码匹配失败n");
}
//char path[50]={0};
//getcwd(path,50); //获取当前所在目录
//printf("getcwd:%sn",path);
return 0;
}
编译与运行结果:
小结:实现了如何验证输入的账户和密码是系统管理的账户与密码,可以用于ftp服务器登录验证等应用。
最后感谢部分网友的分享
参考链接:
https://www.cnblogs.com/fuyuanming/p/6519758.html
https://www.cnblogs.com/Genesis-007/p/5368760.html
最后
以上就是单身大碗为你收集整理的linux 账户和密码匹配实现的全部内容,希望文章能够帮你解决linux 账户和密码匹配实现所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复