[英]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 = ¤t_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...
对于一个重要的程序,您可能需要检查来自fork
、 wait
、 execl
等的错误。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.