2011-06-09 87 views
1

我想啓動一個bash腳本(閱讀:bash不是sh腳本),而不是用戶調用它,但是bash忽略了腳本上的setuid,所以我選擇了寫一個非常小的腳本需要一個腳本/參數並用setuid set來調用它。需要幫助改進一個小型的C程序

這工作得很好,我甚至進一步驗證腳本setuid設置,可執行文件和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,那麼你們怎麼認爲?我應該改進什麼?

謝謝。

+1

對不起,這不是一個代碼評論網站。 – 2011-06-09 09:25:22

+0

... http://codereview.stackexchange.com/是。試試那裏。 – Johnsyweb 2011-06-09 09:33:22

+0

現代系統上bash和sh腳本的確切區​​別是什麼?在大多數Linux上,sh只是bash的鏈接/別名。 – taskinoor 2011-06-09 09:43:49

回答

2
if(file_mode >> 6 != 567) { 

幻數是壞的。改爲使用S_I*位掩碼。

system(command); 

你在* nix;使用fork()exec*()將消除剛剛在循環中執行的大部分雜技。

+0

嘿伊格納西奧,請你指點我的任何類型的文檔操作系統'S_I *'掩碼? – kalbasit 2011-06-09 09:54:03

+0

沒關係,我發現它http://www.gnu.org/s/hello/manual/libc/Permission-Bits.html#Permission-Bits – kalbasit 2011-06-09 09:57:32