linux命令:su的实现

使用su命令可以切换用户,不加参数时默认切换到root用户。

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>
#include<assert.h>
#include <shadow.h>
#include <pwd.h>
#include <sys/types.h>
#include<termios.h>
#include<errno.h>


int main(int argc, char *argv[])
{
	char *user = "root";
	if(argv[1] != NULL)
	{
		user = argv[1];
	}

	printf("Password: ");
	fflush(stdout);
	
/
/设置终端不回显的代码
	struct termios oldflag, newflag;//保存原有终端属性和新设置的终端属性

	tcgetattr(fileno(stdin), &oldflag);//获得终端原有属性并保存在结构体oldflag
	newflag = oldflag;
	newflag.c_lflag &= ~ECHO;
	newflag.c_lflag |= ECHONL;
	if(tcsetattr(fileno(stdin), TCSANOW, &newflag) != 0)
	{
		perror("tcsetattr");
		return -1;
	}

	//
	char passwd[128] = {0}; 
	fgets(passwd, 128, stdin);
	passwd[strlen(passwd) - 1] = 0;
	/
	if(tcsetattr(fileno(stdin), TCSANOW, &oldflag) != 0)
	{
		perror("tcsetattr");
		return -1;
	}
	
	//根据用户名获取系统存储用户的密码信息
	struct spwd *pwd = getspnam(user);
	assert(pwd != NULL);
//
//根据用户密码信息获取加密算法iD以及密钥
	char *p = pwd->sp_pwdp;
	char salt[128] = {0};
	int count = 0, i = 0;
	while(1)
	{
		salt[i] = *p;
		if(salt[i] == '$')
		{
			count++;
		}

		if(count == 3)
		{
			break;
		}

		i++,p++;
	}


	//根据获取的算法ID和密钥,对输入的明文加密
    char *s = crypt(passwd, salt);

	if(strcmp(s, pwd->sp_pwdp) != 0)
	{
		printf("password is error\n");
		exit(0);
	}

	pid_t n = fork();
	assert(n != -1);

	if(n == 0)
	{
		struct passwd *pw = getpwnam(user);
		assert(pw != NULL);
	
		setenv("HOME", pw->pw_dir, 1); // 设置环境变量
		setuid(pw->pw_uid);     // 修改用户
		execl(pw->pw_shell, pw->pw_shell, (char*)0);

		printf("su is fail\n");
		exit(0);
	}
	else
	{
		wait(NULL);
	}
}

 

系统中的su命令,在你输入密码时不会回显,这样更加安全,

下面是实现代码:

#include<termios.h>
#include<errno.h>


/设置终端不回显的代码
	struct termios oldflag, newflag;//保存原有终端属性和新设置的终端属性

	tcgetattr(fileno(stdin), &oldflag);//获得终端原有属性并保存在结构体oldflag
	newflag = oldflag;
	newflag.c_lflag &= ~ECHO;
	newflag.c_lflag |= ECHONL;
	if(tcsetattr(fileno(stdin), TCSANOW, &newflag) != 0)
	{
		perror("tcsetattr");
		return -1;
	}

	//
	char passwd[128] = {0}; 
	fgets(passwd, 128, stdin);
	passwd[strlen(passwd) - 1] = 0;
	/
	if(tcsetattr(fileno(stdin), TCSANOW, &oldflag) != 0)
	{
		perror("tcsetattr");
		return -1;
	}
	

在该命令中,我们要判断用户输入的密码是否正确,在判断密码正确后,要重新设置环境变量,并且修改用户,将终端切换到当前新用户的默认终端下。这才真正完成了su命令。

执行结果如下:

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值