Linux中的用户切换su.
将su可执行文件所属者设置为root的,则执行su时候则拥有了root的权限
切换到root用户下,chown root su 和chmod u+s su来改变su文件的权限
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <pwd.h>
#include <stdlib.h>
#include <assert.h>
#include <shadow.h>
#include <sys/types.h>
#include <termios.h>
int main(int argc, char *argv[])
{
	char *s = "root";
	if (argc == 2)
	{
		s = argv[1];
	}//取su的第二个参数
    
	struct passwd *p = getpwnam(s);//通过次函数来看第二个参数是否存在
	if (p == NULL)
	{
       		perror("username error");
   	}
    
    struct spwd *sp = getspnam(s);
   	if(sp == NULL)
   	{
      	perror("userpasswd error");
       	exit(0);
   	}
    printf("input passwd:");
    fflush(stdout);
	
	struct termios saveold, newreset;
	tcgetattr(fileno(stdin), &saveold);
	newreset = saveold;//保存旧的设置
	newreset.c_lflag &= ~ECHO;
    char buff[128] = {0};//获取键盘输入密码
	if (tcsetattr(fileno(stdin), TCSAFLUSH, &newreset) != 0)//消隐设置
	{
		perror("wrong happened\n");
	}
	else
	{
    		fgets(buff,128,stdin);
    		buff[strlen(buff)-1] = 0;
		    tcsetattr(fileno(stdin), TCSANOW, &saveold);//恢复原设置
	}
    char lt[128] = {0};
    int i = 0;
    int num = 0;
    for(;i<strlen(sp->sp_pwdp);i++)//获取加密密钥
    {
    	if(sp->sp_pwdp[i] == '$')
        {
           	num += 1;
           	if(num == 3)
            {
           		break;
           	}
        }	
		lt[i] = sp->sp_pwdp[i];
    }

    char *pw = crypt(buff,lt);//密钥和明文进行加密生成密文
   	if(strcmp(pw,sp->sp_pwdp) != 0)//系统的和生成密文进行比较
   	{
      	printf("failed\n");
	    exit(0);
    }
    printf("success\n");
       
    pid_t pid = fork();//产生新进程为用户的bash
    assert(pid != -1);
     
    if (pid == 0)
    {
      	setuid(p->pw_uid);//将现在的root权限修改为切入用户的uid
       	setenv("HOME",p->pw_dir,1);//设置当前环境变量
       	execl(p->pw_shell,p->pw_shell,(char *)0);//进入用户默认bash
		perror("exec error");//出错则发出信息,并且终止
       	exit(0);
    }
    wait(NULL); //子进程的结束发出SIGCHLD信号清理子进程
}    

Logo

更多推荐