繁体   English   中英

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

[英]Run program from standard user as a root

我刚刚创建了需要 root 权限才能正常运行的 C 程序。 我想在我的普通用户帐户中使用特殊的键绑定来执行它,那么有什么方法可以授予程序 root 权限并使用我的普通用户执行它而不输入 sudo? 我已经尝试将所有者更改为 root 用户并向用户添加 s 模式,但它没有帮助。 有任何想法吗?? 这是代码:

/*
*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);
}

正如@thatotherguy 所说,解决方案是添加setuid(geteuid()); 到代码,加上将所有权更改为 root 并提供用户的模式(setuid)。

更新:如前所述,不建议使用 setuid 模式,因为它会导致许多安全漏洞!

这是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());
}

然后:

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

Output:

My real UID is 1234
My effective UID is 0

换句话说,我仍然是“真正的”我自己(UID 1234),但我实际上是 root(UID 0)。

这对你不起作用吗?

更新:好的,确实如此。

下一步是摆脱system调用,因为您的 root 权限不会转移到您通过 system.xml 执行的程序。 (顺便说一下,要了解这个问题,请考虑 shell 将通过查看您的 PATH 来找到paccache ,这意味着任何能够安排名为paccache的程序出现在您的 PATH 中的人都可能诱骗您进入以root身份运行它。)

Linux中启动进程的方式是调用fork ,将进程拆分为父子进程,然后在子进程中调用execl 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...

对于一个重要的程序,您可能需要检查来自forkwaitexecl等的错误。

暂无
暂无

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM