简体   繁体   English

从标准用户以root身份运行程序

[英]Run program from standard user as a root

I just created C program that require a root to privileges run properly.我刚刚创建了需要 root 权限才能正常运行的 C 程序。 I want to execute it using special keybindings in my regular user account, so is there any way that I can give the program root permission and execute it with my regular user without typing sudo??我想在我的普通用户帐户中使用特殊的键绑定来执行它,那么有什么方法可以授予程序 root 权限并使用我的普通用户执行它而不输入 sudo? I already tried to change the owner ship to the root user and adding s mode to the user but it didn't help.我已经尝试将所有者更改为 root 用户并向用户添加 s 模式,但它没有帮助。 Any ideas??有任何想法吗?? Here is the code:这是代码:

/*
*This program will make some cleaning that i regularly do, 
*before the full system backup. And then itll create new dir 
*in my HDD with date to make the system backup in it useng rsync.
*The program will use system() to connect all the command line tools
*together and automate this process.
*/
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>

#define DEV_PATH "/run/media/yan/HDD/"

void delete_dir(char *);
void get_date(int *);
char *make_backup_dir(const char *, int *);
void backup_sys(char *);

int main() {
    char *dirs_to_clean[] = {
        "/home/yan/.cache/spotify", "/home/yan/.cache/yay/*", 
        "/home/yan/.cache/mozilla/firefox/9jizeht4.default-release/cache2", "\0"
        };
    char *backup_path_ptr;
    int date[3]; //Array for the date of today
    int i;

    //System cleaning 
    for(i=0; *dirs_to_clean[i]!='\0'; i++) //Delete every dir in the dirs_to_clean array
        delete_dir(dirs_to_clean[i]);
    system("paccache -rk2");
    //System backup
    get_date(date); //Get the date of today and pass it to the array 
    backup_path_ptr = make_backup_dir(DEV_PATH, date); //Create backup dir and get its path
    backup_sys(backup_path_ptr); //Backup system to the backup_path_ptr dir
    return 0;
}

/*
*This function will delete the given argument dir.
*/
void delete_dir(char *dir_path) {
    char command_buffer[100];

    //Copy command to buffer (rm -rf dir_path) to delete dir.
    strcpy(command_buffer, "rm -rf ");
    strcat(command_buffer, dir_path);

    system(command_buffer); //Execute command
}

/*
*This function will get the date of today, and it'll insert it to the passed date array.
*/
void get_date(int *date) {
    long int sec_since_epoch;
    struct tm current_time, *time_ptr;

    sec_since_epoch = time(0); 
    time_ptr = &current_time; //Set time pointer to the current_time struct
    localtime_r(&sec_since_epoch, time_ptr);

    //Pass today's date to the array 
    *date = time_ptr->tm_mday;
    *(date+1) = time_ptr->tm_mon + 1; //+1 because months range from 0 - 11
    *(date+2) =  time_ptr->tm_year - 100; //-100 because tm_year is the passed years since 1900
}

/*
*A function that gets pointer to int array that contains the
*date of today and it converts it to string name so itll create
*a backup dir in the passed path with converted string.
*Then it will return the full path of the created dir to 
*make backup in it.
*/
char *make_backup_dir(const char *device_path, int *date_array) {
    int i;
    char dir_name[9], command_buffer[100];
    static char full_path[50]; //The returned full path 

    strcpy(command_buffer, "mkdir "); //Insert command to the command_buffer
    strcpy(full_path, device_path);
    //Convert the date_array to a strin so will use it to name the dir
    sprintf(dir_name, "%02d", *date_array);
    sprintf((dir_name+3), "%02d", *(date_array+1));
    sprintf(dir_name, "%02d", *date_array);
    sprintf(dir_name+6, "%d", *(date_array+2));
    dir_name[2] = dir_name[5] = '-';
    strcat(full_path, dir_name); //Complete the full dir path 
    strcat(command_buffer, full_path); //Complete the command
    system(command_buffer); //Execute the command 

    return full_path;
}

/*
*This function will make the full system backup using rsync to the passed dir.
*/
void backup_sys(char *backup_path) {
    const char *backup_command = "rsync -aAXHv --exclude={\"/dev/*\",\"/proc/*\",\"/sys/*\",\"/tmp/*\",\"/run/*\",\"/mnt/*\",\"/media/*\",\"/lost+found\"} / ";
    char command_buffer[200];

    //Prepare command
    strcpy(command_buffer, backup_command);
    strcat(command_buffer, backup_path);
    system(command_buffer);
}

As @thatotherguy said, the solution is add setuid(geteuid());正如@thatotherguy 所说,解决方案是添加setuid(geteuid()); to the code, plus changing the ownership to root and giving the users s mode (setuid).到代码,加上将所有权更改为 root 并提供用户的模式(setuid)。

Update: As it was noted it is not recommended to use the setuid mode because it causes many security holes!更新:如前所述,不建议使用 setuid 模式,因为它会导致许多安全漏洞!

This is main.c:这是main.c:

#include <stdio.h>
#include <unistd.h>

int main(int argc, char* argv[]) {
  printf("My real UID is %d\n", getuid());
  printf("My effective UID is %d\n", geteuid());
}

Then:然后:

gcc main.c -o main
sudo chown root:root main
sudo chmod 6711 main
./main

Output: Output:

My real UID is 1234
My effective UID is 0

In other words, I'm still "really" myself (UID 1234) but I'm effectively root (UID 0).换句话说,我仍然是“真正的”我自己(UID 1234),但我实际上是 root(UID 0)。

Does this not work for you?这对你不起作用吗?

Update: Okay, it does.更新:好的,确实如此。

Next step is to get rid of the system call because your root privileges won't carry over to the program you execute via system.下一步是摆脱system调用,因为您的 root 权限不会转移到您通过 system.xml 执行的程序。 (By the way, to understand the problem with this, consider that the shell is going to find paccache by looking at your PATH, which means that anyone who is able to arrange for a program called paccache to appear in your PATH could trick you into running it as root.) (顺便说一下,要了解这个问题,请考虑 shell 将通过查看您的 PATH 来找到paccache ,这意味着任何能够安排名为paccache的程序出现在您的 PATH 中的人都可能诱骗您进入以root身份运行它。)

The way to launch a process in Linux is to call fork , which will split the process into a parent and a child, then call execl in the child process. Linux中启动进程的方式是调用fork ,将进程拆分为父子进程,然后在子进程中调用execl ( execl will never return, so if you want to do stuff after child program ends, you need to do that in the parent.) execl永远不会返回,所以如果你想在子程序结束后做一些事情,你需要在父程序中这样做。)

pid_t child_pid;
if (child_pid = fork()) {
  int child_status;
  // I'm the parent, wait for child to finish.
  wait(&child_status);
} else {
  // I'm the child; run the other program.
  execl("/path/to/paccache", "paccache", "-rk2", NULL);
}
// Do whatever you want to do after paccache ends...

For a non-trivial program you'd probably want to check for errors from fork , wait , execl , etc.对于一个重要的程序,您可能需要检查来自forkwaitexecl等的错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 从以用户root运行的C程序启动Python GUI - Launch a Python GUI from a C program running with user root 使用 SUID 以 root 身份运行程序 - Run program as root using SUID 从 setuid root C 程序调用脚本 - 脚本不以 root 身份运行 - Calling a script from a setuid root C program - script does not run as root Ubuntu,libftdi特权,非root用户运行程序时出现段错误 - Ubuntu, libftdi priviliges, seg fault when non-root user run program 如何将用户的输入值提供给程序中运行的进程 - How to give input values from user to a process run in a program 以root用户身份以编程方式运行C程序 - Running a C program as root user programatically 编译的 C 程序不会在我的 uid 下运行,但会以 root 身份运行 - Compiled C Program Wont Run Under My uid But Will Run As Root Qt Creator代码作为用户,但以root身份运行和调试 - Qt Creator code as a user but run and debug as root 在内核程序中获取root用户ID并与当前用户ID进行比较 - in kernel program get root user id and compare with current user id 如果以 root 身份执行的 C 程序通过调用 system(someprog) 执行另一个二进制文件,该程序是否也以 root 身份运行? - If a C program executing as root executes another binary by calling system(someprog) does that program also run as root?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM