ユーザーが呼び出すのではなく、ルートとしてbashスクリプト(shスクリプトではなくbashを読む)を起動したかったのですが、bashはスクリプトのsetuidを無視するため、スクリプト/引数を取り、それを呼び出す非常に小さなスクリプトを作成することにしましたsetuid セットで。
これはうまく機能し、プログラムの誤用を避けるために、スクリプトにsetuidが設定され、実行可能であり、rootとしてではなくファイルの所有者でsetuid()が呼び出されていることをさらに確認し、以下のプログラムになりました..
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
int main(int argc, char **argv)
{
char *command;
int i, file_owner, size = 0;
struct stat status_buf;
ushort file_mode;
// Check argc
if (argc < 2) {
printf("Usage: %s <script> [arguments]\n", argv[0]);
return 1;
}
// Make sure the script does exist
if(fopen(argv[1], "r") == NULL) {
printf("The file %s does not exist.\n", argv[1]);
return 1;
}
// Get the attributes of the file
stat(argv[1], &status_buf);
// Get the permissions of the file
file_mode = status_buf.st_mode;
// Make sure it's executable and it's setuid
if(file_mode >> 6 != 567) {
printf("The file %s should be executable and should have setuid set, please chmod it 0106755.\n", argv[1]);
return 1;
}
// Get the owner of the script
file_owner = status_buf.st_uid;
// setuid
setuid(file_owner);
// Generate the command
for (i = 1; i < argc; i++) {
size += strlen(argv[i]);
}
command = (char *) malloc( (size + argc + 11) * sizeof(char) );
sprintf(command, "/bin/bash %s", argv[1]);
if (argc > 2) {
for (i = 2; i < argc; i++) {
sprintf(command, "%s %s", command, argv[i]);
}
}
// Execute the command
system(command);
// free memory
free(command);
return 0;
}
この演習は私の問題を解決するためだけでなく、C をさらに理解するための方法でもありました。改善すべき点はありますか?
ありがとうございました..