【发布时间】:2013-12-24 05:08:20
【问题描述】:
我是 C 新手,这是一个简单的包装器(rootsetuidwrapper.c),用于以不同的用户身份执行脚本。我要执行的脚本是路径 (/home/neehar) 上的 ubuntu-server-secure.sh 作为 root。我的操作系统是 Ubuntu 12.04.03 LTS。有人可以帮我解决这些错误吗?我使用 gcc 编译并通过执行 gcc -o rootsuidwrap rootsetuidwrapper.c 将编译后的代码称为 rootsuidwrap。当我通过执行 ./rootsuidwrap ubuntu-server-secure.sh [0] 在终端中运行它时。这是正确的称呼方式吗?代码中的用法部分说要这样做。它出现说:Segmentation Fault (core dumped)。是否与这部分代码有关:*user=cuserid(NULL);。它可能是流氓指针。如果是这样,解决方法是什么?它会是什么样子?
如果有人能修复这些错误并给我工作代码,那就太好了。另外,我想知道我做错了什么。
* 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
*/
memset (domain, '\0', sizeof domain );
getdomainname (domain, sizeof domain - 1);
/*
* Figure out our fully canonicalized hostname
*/
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
*/
*user = cuserid (NULL);
if (user == 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);
}
感谢您的帮助,
【问题讨论】:
-
尝试使用
gdb调试代码并找出代码出现Seg-Faulting的确切行号。 -
为什么你认为空的
#ifdef/#endif块是个好主意?为什么你认为#ifdef __STDC__条件编译是个好主意?或者,换一种说法,您认为在哪个平台上工作会有非标准编译器?让我们面对现实吧,这样的系统肯定有一个近 25 年没有故意升级的编译器,而且它们很少而且相差甚远。 (关于我所知道的唯一情况是 HP-UX 上用于重建内核的 C 编译器。但您不应该将该编译器用于诸如此类的一般开发工作。) -
我在 1992 年写了这篇文章,它运行良好。
标签: c debugging segmentation-fault root setuid