自己实现su命令

2020-07-23  本文已影响0人  一路向后

1.程序源码

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

int getsalt(struct spwd *sp, char *salt)
{
    int count = 0;
    int i = 0;

    for(i=0; sp->sp_pwdp[i] != 0x00; i++)
    {
        salt[i] = sp->sp_pwdp[i];

        if(salt[i] == '$')
        {
            count++;

            if(count == 3)
                break;
        }
    }

    return i;
}

int main(int argc, char **argv)
{
    struct termios old, new;
    struct spwd *sp = NULL;
    struct passwd *pw = NULL;
    char passwd[128] = {0};
    char salt[128] = {0};
    char *user = "root";
    char *p = NULL;

    if(argc == 2)
    {
        user = argv[1];
    }

    printf("Passwd: ");
    fflush(stdout);

    tcgetattr(0, &old);

    new = old;
    new.c_lflag &= ~ECHO;

    tcsetattr(0, TCSANOW, &new);
    fgets(passwd, 127, stdin);
    tcsetattr(0, TCSANOW, &old);

    putchar('\n');

    sp = getspnam(user);
    if(sp == NULL)
    {
        printf("用户不存在或密码错误!\n");
        exit(-1);
    }

    p = (char *)crypt(passwd, salt);
    if(p == NULL)
    {
        printf("用户不存在或密码错误!\n");
        exit(-1);
    }

    pw = getpwnam(user);
    if(pw == NULL)
    {
        printf("用户不存在或密码错误!\n");
        exit(-1);
    }

    setuid(pw->pw_uid);
    setenv("HOME", pw->pw_dir, 1);

    execl(pw->pw_shell, pw->pw_shell, NULL);

    return 0;
}

2.编译源码

$ gcc -o su su.c -lcrypt

3.授予权限

# chown root:root su
# chmod 511 su
# chmod +s su

4.运行程序

$ ./su
Passwd: 
# 
上一篇 下一篇

猜你喜欢

热点阅读