2013-12-24 3 views
0

Я новичок в C, и это простая оболочка, которую я написал для запуска сценариев выполнения как другого пользователя. Я понимаю, что могу делать visudo в etc/sudoers, но, я уже сделал это, и я не хочу, чтобы он пропал даром, также он поможет мне улучшить письмо на C. Мне кажется, проблема. У меня возникают ошибки, когда Я скомпилирую его. Моя операционная система - Ubuntu 12.04.03 LTS. Может кто-нибудь помочь мне исправить эти ошибки?Отладка корневой SUID C

rootsuidwrapper.c: In function ‘trusted’: 
rootsuidwrapper.c:60:15: warning: assignment makes pointer from integer without a cast [enabled by default] 
rootsuidwrapper.c: In function ‘main’: 
rootsuidwrapper.c:116:48: error: too many arguments to function ‘stat’ 
/usr/include/x86_64-linux-gnu/sys/stat.h:211:12: note: declared here 

Было бы неплохо, если бы кто-то мог исправить эти ошибки и дать мне рабочий код. Кроме того, я хотел бы знать, что я сделал неправильно.

* This program must be run as root to work. 
*/ 

#if !defined(lint) && !defined(SABER) || defined(RCS_HDRS) 
#endif /* !lint && !SABER || RCS_HDRS */ 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <netdb.h> 
#include <sys/stat.h> 

#define TRUSTED_GROUP "trusted" 

typedef enum { false = 0, true } bool; 

#ifdef __STDC__ 
bool trusted(char *whoami) 
#else 
bool trusted(whoami) 
    char *whoami; 
#endif /* __STDC__ */ 
{ 
    char *user; 
    char host[BUFSIZ + 1]; 
    char domain[BUFSIZ + 1]; 
    struct hostent *hp; 

    /* 
    * Figure out whether this user on this host in this domain is 
    * trusted. 
    */ 

    /* 
    * Determine our domain name 
    */ 
    (void) memset(domain, '\0', sizeof(domain)); 
    getdomainname(domain, sizeof(domain) - 1); 

    /* 
    * Figure out our fully canonicalized hostname 
    */ 

    (void) memset(host, '\0', sizeof(host)); 
    gethostname(host, sizeof(host) - 1); 
    if ((hp = gethostbyname(host)) == NULL) { 
    strcat(host, "."); 
    strcat(host, domain); 
    fprintf(stderr, 
     "%s: WARNING: can't canonlicalize hostname; assuming %s.\n", 
     whoami, host); 
    } 
    else { 
    strcpy(host, hp->h_name); 
    } 

    /* 
    * Get login name of current user 
    */ 
    if ((user = cuserid(NULL)) == NULL) { 
    fprintf(stderr, " %s: You do not seem to be in the passwd file!\n", 
     whoami); 
    return(false); 
    } 

    /* 
    * Look this triple up in the trusted netgroup 
    */ 

    return ((innetgr(TRUSTED_GROUP, host, user, domain) == 1) ? true : false); 
} 


#ifdef __STDC__ 
main(int argc, char *argv[]) 
#else 
main(argc, argv) 
    int argc; 
    char *argv[]; 
#endif /* __STDC__ */ 
{ 
    char *whoami; 
    int ouruid;   /* uid we set to run chown and chmod */ 
    int proguid;  /* uid we are chowning program to */ 
    char *filename; 
    struct stat statbuf; 
    int error = 0; 

    if (whoami = strrchr(argv[0], '/')) 
    whoami ++; 
    else 
    whoami = argv[0]; 

    if (argc == 3) 
    proguid = atoi(argv[2]); 
    else if (argc == 2) 
    proguid = 0; 
    else { 
    fprintf(stderr, "usage: %s filename [proguid]\n", whoami); 
    exit(1); 
    } 

    filename = argv[1]; 

    if (trusted(whoami)) 
    ouruid = 0; 
    else 
    ouruid = getuid(); 

    if (setuid(ouruid) == -1) { 
    fprintf(stderr, "%s: Warning: setuid(%d) failed: ", whoami, ouruid); 
    perror(NULL); 
    exit(1); 
    } 

    if (stat(filename, &statbuf, sizeof(struct stat)) == -1) { 
    fprintf(stderr, "%s: failure statting %s: ", whoami, filename); 
    perror(NULL); 
    exit(1); 
    } 

    if (chown(filename, proguid, -1) == -1) { 
    error++; 
    fprintf(stderr, "%s: chown %d %s failed: ", whoami, proguid, filename); 
    perror(NULL); 
    fprintf(stderr, "continuing...\n"); 
    } 

    if (chmod(filename, statbuf.st_mode | S_ISUID)) { 
    error++; 
    fprintf(stderr, "%s: chmod u+s %s failed: ", whoami, filename); 
    perror(NULL); 
    } 

    return(error); 
} 

Помощь ценится,

+0

stat() только ожидает 2 параметра. Удалите третий параметр sizeof (struct stat). – alvits

ответ

1
NAME 
     stat, fstat, lstat - get file status 

SYNOPSIS 
     #include <sys/types.h> 
     #include <sys/stat.h> 
     #include <unistd.h> 

     int stat(const char *path, struct stat *buf); 
     int fstat(int filedes, struct stat *buf); 
     int lstat(const char *path, struct stat *buf); 

Удалите третий параметр в вызове стат(). Ваш код должен быть затем:

if (stat(filename, &statbuf) == -1) { 

Там нет необходимости говорить stat() размера буфера, потому что stat() ожидает struct stat *, который имеет фиксированный размер.

0

Для предупреждения компилятора:

cuserid() возвращает указатель на символ (char*). Когда какая-либо функция возвращает указатель и вы хотите поместить возвращаемое значение в буфер, тогда вы должны поместить возвращаемое значение в определенное место в буфере, обычно в начале. В частности, вы должны использовать:

*user = cuserid(NULL); 
if(user == NULL) 

Помните, что cuserid() возвращает указатель на один символ. Следовательно, возвращаемое значение функции должно начинаться с одного символа - то есть *user или user[0]. Когда используется вышеуказанный код, компилятор не должен жаловаться. Затем вы поместите результат cuserid(NULL) в user, начиная с первого байта и остальной выделенной памяти.

+0

Затем я получаю сообщение об ошибке сравнения между указателем и целым числом. – CodingWolf

+0

Не пытайтесь полностью копировать K & R все время. Затем вы получаете такие ошибки. Все не может быть сделано в if-statement. – trifork

+0

Я изменил код. Посмотри, что я сделал. Теперь это на две линии вместо одной (проще управлять этим способом). Теперь вся строка сравнивается с «NULL», а не только с одним символом. – trifork

Смежные вопросы