1. 系统中有哪些用户?
- 系统用户信息保存在/etc/passwd文件中
2. /etc/passwd 文件访问接口
2.1)关键字检索
2.2)查询整各文件#include <sys/types.h> #include <pwd.h> /*用于login程序*/ struct passwd *getpwnam(const char *name); /*ls程序可以把用户ID映射为用户名*/ struct passwd *getpwuid(uid_t uid);
#include <sys/types.h> #include <pwd.h> /*打开文件,并且每调用一次返回下一项*/ struct passwd *getpwent(void); /*回到数据库的起点*/ void setpwent(void); /*关闭文件*/ void endpwent(void);
2. 用户秘钥如何验证?
2.1 验证原理
-
用户的密码被加密后存放在/etc/shadow文件中!用户登录验证需要提供用户名+密码的形式
-
加密算法有多种:
为了提高安全性,Linux引入了salt。salt即为一个随机数,它是12bit的数值。当用户设置密码时,会随机生成一个salt与用户的密码一起加密,得到一个加密的字符串(salt以明文形式包含在该字符中),存储到密码文件中。 -
crypt函数可以将用户输入的密码和salt一起适应某种算法进行加密,该加密后的字符串就是我们需要的与密码文件中密码对比的加密字符串!如果相同用户验证通过,否则验证失败!
-
crypt为支持不同的方式将salt格式化为
$id$salt$encode
其中id代表不同的算法
1 | MD5
2a | Blowfish (not in mainline glibc; added in some
| Linux distributions)
5 | SHA-256 (since glibc 2.7)
6 | SHA-512 (since glibc 2.7)
接口:
struct spwd *getspnam(const char *name);
struct spwd *getspent(void);
void setspent(void);
void endspent(void);
2.2 验证举例
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <shadow.h>
#include <errno.h>
void help(void)
{
printf("用户密码验证程序\n第一个参数为用户名!\n");
exit(-1);
}
void error_quit(char *msg)
{
perror(msg);
exit(-2);
}
void get_salt(char *salt,char *passwd)
{
int i,j;
//取出salt,i记录密码字符下标,j记录$出现次数
for(i=0,j=0;passwd[i] && j != 3;++i)
{
if(passwd[i] == '$')
++j;
}
strncpy(salt,passwd,i-1);
}
int main(int argc,char **argv)
{
/*阴影口令*/
struct spwd *sp;
/*用户口令*/
char *passwd;
char salt[512]={0};
if(argc != 2)
help();
/*得到用户口令*/
passwd=getpass("请输入密码:");
/*得到阴影口令*/
if((sp=getspnam(argv[1])) == NULL)
error_quit("获取用户名和密码");
/*通过阴影口令得到加密方式id:salt*/
get_salt(salt,sp->sp_pwdp);
//进行密码验证
if(strcmp(sp->sp_pwdp,crypt(passwd,salt)) == 0)
printf("验证通过!\n");
else
printf("验证失败!\n");
return 0;
}
3. 用户组关系是怎样的?
用户组有两种:初始化组(只有一个)以及附加组(可能多个)(反正用户在这些组的集合中)
3.1 初始组
用户所在初始组存放在/etc/passwd中pw_gid 字段中,用户可以使用这个字段检索/etc/group文件的匹配项
/etc/group文件:
匹配某一项:
#include <sys/types.h>
#include <grp.h>
struct group *getgrnam(const char *name);
struct group *getgrgid(gid_t gid);
遍历整个文件:
#include <sys/types.h>
#include <grp.h>
struct group *getgrent(void);
void setgrent(void);
void endgrent(void);
3.2 附加组(略)
4. 谁登陆了我的系统?
login程序会记录用户登录信息,使用who命令或者last命令可以查阅这些信息!