简体   繁体   English

根SUID C包装器调试

[英]Root-SUID C wrapper debugging

I am new to C and this is a simple wrapper I wrote to run execute scripts as different user. 我是C语言的新手,这是我编写的一个简单包装程序,用于以其他用户身份运行执行脚本。 I understand I can do visudo in etc/sudoers but, I already did this and I don't want it to go to waste, also it will help me improve writing in C. I seem to ha The problem is I am having errors when I compile it. 我知道我可以在etc / sudoers中执行visudo,但是,我已经做到了,而且我不想浪费它,这也将帮助我改善C语言的编写。我编译它。 My operating system is Ubuntu 12.04.03 LTS. 我的操作系统是Ubuntu 12.04.03 LTS。 Can someone help me fix these errors? 有人可以帮我解决这些错误吗?

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

It would be nice if someone could fix these errors and give me the working code. 如果有人可以修复这些错误并提供给我有效的代码,那就太好了。 Also, I would like to know what I did wrong. 另外,我想知道我做错了什么。

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

Help is appreciated, 感谢您的帮助,

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);

Remove your third parameter in the call to stat(). 在对stat()的调用中删除您的第三个参数。 Your code should then be: 您的代码应为:

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

There is no need to tell stat() the size of the buffer because stat() expects a struct stat * which has a fixed size. 无需告诉stat()缓冲区的大小,因为stat()需要一个具有固定大小的struct stat *

For the compiler warning: 对于编译器警告:

cuserid() returns a pointer to a character ( char* ). cuserid()返回一个指向字符( char* )的指针。 When any function returns a pointer, and you want to place the return value into a buffer, then you have to put the return value into a specific place in the buffer, usually the beginning. 当任何函数返回指针,并且您要将返回值放入缓冲区时,则必须将返回值放入缓冲区中的特定位置,通常是开始位置。 Specifically, you should use: 具体来说,您应该使用:

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

Remember, cuserid() returns a pointer to a single character. 记住, cuserid()返回一个指向单个字符指针。 Therefore, the return value of the function should go into a single character - that is, *user or user[0] . 因此,该函数的返回值应使用单个字符- *useruser[0] When the above code is used, the compiler shouldn't complain. 使用上面的代码时,编译器不应抱怨。 Then you place the result of cuserid(NULL) into user , from the first byte to the rest of the memory allocated. 然后,将cuserid(NULL)的结果放入user ,从第一个字节到分配的其余内存。

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

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