sudo.c
来源:互联网 发布:特大网络传销案判决书 编辑:程序博客网 时间:2024/06/05 21:09
/*
** sudo - run a command as root
*/
#include <stdio.h>
#include <strings.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <pwd.h>
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 64
#endif MAXHOSTNAMELEN
/* terryh */
/*#define ALERTMAIL "root"*/
#define ALERTMAIL "terryh"
/* terryh */
/* #define LOGFILE "/usr/local/adm/logs/sudo.log"*/
#define LOGFILE "/nfs/juno/u5/etc/bfdo/logs/bfdo.log"
extern char *ctime();
extern long time();
/* terryh */
/*char *userfile = "/usr/local/adm/sudoers";*/
char *userfile = "/nfs/juno/u5/etc/bfdo/bfdoers";
char *progname;
long now;
void log(), errexit(), firsthostname();
int checkdoer();
char *isadoer();
main(argc, argv)
int argc;
char *argv[];
{
char doerline[512];
char cmd[512];
char *dp;
struct passwd *pw;
int uid, pid;
progname = argv[0];
if(argc < 2)
{
fprintf(stderr, "usage: %s cmd\n", progname);
exit(1);
}
/* remember who this user really is */
uid = getuid();
/* Set userid to be root and group id to be daemon */
/* terryh if((setuid(0)) < 0)
{
eperror("setuid");
}*/
/* terryh if((setgid(3)) < 0)
{
eperror("setgid");
}*/
dp = &doerline[0];
pw = getpwuid(uid);
now = time((long*) 0);
if ((dp = isadoer(pw->pw_name,pw->pw_passwd)) == NULL)
{
log(pw->pw_name,"FAIL",argc,argv);
fprintf(stderr,"%s:I don't know you, and I'm telling!\n",*argv);
if ((pid = fork()) == 0)
mailmsg(pw->pw_name,argv,argc);
if (pid == -1)
eperror("fork");
exit(1);
}
argv++, argc--;
checkdoer(dp,*argv,cmd);
if (strcmp(cmd,"all") == 0)
{
log(pw->pw_name,"",argc, argv);
execvp(*argv, argv); /* then do it */
eperror(*argv);
}
if (cmd[0] == '\0')
{
log(pw->pw_name,"FAIL",argc,argv);
fprintf(stderr,
"%s: I know you, but I can't let you: %s\n",progname,*argv);
exit(1);
}
/* do a specific command with hard-coded path from doer file */
log(pw->pw_name,"",argc,argv);
execv(cmd, argv); /* then do it */
eperror(*argv);
}
/*
** isadoer(name, encrypted password) - look for a user in USERFILE
** return doer entry on success, else NULL.
*/
char *isadoer(name,password)
char *name;
char *password;
{
register FILE *fp;
char buf[BUFSIZ];
struct stat statb;
if (stat(userfile, &statb))
eperror(userfile);
/* terryh
if (statb.st_uid != 0)
errexit("%s must be owned by root\n", userfile);*/
/* terryh
if (statb.st_mode & 022)*/ /* should be og-w */
/*errexit("bad modes on %s\n", userfile);*/
if ((fp = fopen(userfile,"r")) == 0 )
errexit("Couldn't open %s\n",userfile);
while ((fgets(buf,BUFSIZ,fp)) != NULL)
{
if(buf[0] == '#') /* munch comments */
{
continue;
}
if((strncmp(buf,name,strlen(name))) == 0)
{
/* terryh */
/* if (not_timed_out(name,password)) */
{
return(buf);
}
return(NULL);
}
}
return(NULL);
}
/*
** log this command in the log file
*/
void
log(username, info, argc, argv)
char *username;
char *info;
int argc;
char **argv;
{
register FILE *fp;
fp = fopen(LOGFILE,"a");
if (fp == NULL)
{
errexit("can't open %s.\n", LOGFILE);
}
fprintf (fp, "%20.20s :", ctime(&now));
fprintf (fp,"%s",info);
fprintf (fp,"%7.7s :",username);
while (argc--)
{
fprintf (fp,"%s ",*argv++);
}
fprintf (fp,"\n");
(void) fclose (fp);
return;
}
/*
** eperror - print system error message and exit
** string s is printed too.
*/
eperror(s)
register char *s;
{
fprintf(stderr,"%s: ",progname);
perror(s);
exit(1);
}
/*
** errexit(format, message) - print formatted error and exit
** also send mail
*/
void
errexit(fmt, arg)
register char *fmt, *arg;
{
FILE *popen();
FILE *fd;
char hostname[MAXHOSTNAMELEN];
char cmd[80];
fprintf(stderr,"%s: ", progname);
fprintf(stderr, fmt, arg);
if ((fd = popen(cmd, "w")) == NULL)
{
return;
}
firsthostname(hostname, MAXHOSTNAMELEN);
(void) sprintf(cmd,
"/usr/ucb/mail -s \"HELP! %s@%s has problems.\" %s ",
progname,hostname,ALERTMAIL);
if ((fd = popen(cmd, "w")) == NULL)
{
return;
}
fprintf(fd,"%s: ", progname);
fprintf(fd, fmt, arg);
(void) pclose(fd);
exit(1);
}
/*
** checkdoer - check to see if user is permitted to do command requested.
** dp points to a sudoer file entry of the form:
** 'user ['all,','/dir/dir/cmd1,/dir/dir/cmd2,/dir/dir/cmdN'] ie)
** coggs /bin/wall,/etc/vipassw,/etc/adduser
** operator shutdown
** If 'all' is found, then string "all" is returned in res.
** If command passed in ap is found, then that command, along
** with its full path are passed back in res. If nothing is
** found, then NULL is returned in res.
*/
checkdoer(dp,ap,res)
char *dp; /* doer file entry: 'user cmd1,cmd2,cmdN' */
char *ap;
char *res;
{
char *cp0, *cp1, *cp2;
cp0 = dp;
while(isalnum(*cp0)) /* skip past user field */
{
cp0++;
}
while(*cp0) /* search until end of line */
{
while(isspace(*cp0)) /* skip to beg of cmd field */
{
cp0++;
}
if (strncmp(cp0,"all",3) == 0) /* if cmd field is "all" */
{
(void) strcpy(res,"all"); /* then pass it back */
return;
}
cp1 = cp0;
/* find end of this entry */
while (*cp1 != '\n' && !isspace(*cp1))
{
cp1++;
}
cp1--; /* point to last character of cmd */
cp2 = cp1;
while (*cp2 != '/') /* backup to head of command */
{
cp2--;
}
cp2++;
cp1++; /* point cp1 to last character + 1 */
/* if command issued is found then pass whole path back */
if (strncmp(cp2,ap,strlen(ap)) == 0)
{
(void) strncpy(res,cp0,cp1-cp0); /* copy command back */
*(res+(cp1-cp0)) = '\0'; /* terryh */
return;
}
/*
* if it got to here, then command not found *yet*
* move pointer past next comma and keep looking
*/
while (!isspace(*cp0) && *cp0 != '\n')
{
cp0++;
}
if (*cp0 == '\n') /* if at endo of line then fail */
{
break;
}
else
{
continue;
}
}
*res = NULL;
return;
}
/*
** mailmsg - Snitch on person
*/
mailmsg (user,argv,argc)
char *user, **argv;
int argc;
{
FILE *popen();
FILE *fd;
char *p;
char cmd[80];
char hostname[MAXHOSTNAMELEN];
firsthostname(hostname, MAXHOSTNAMELEN);
(void) sprintf(cmd,
"/usr/ucb/mail -s \"*SECURITY* %s@%s tried to execute %s\" %s ",
user,hostname,*argv,ALERTMAIL);
if ((fd = popen(cmd, "w")) == NULL)
{
return;
}
fprintf(fd,"%s\@%s tried to do a\n\n ",user,hostname);
while(argc--)
{
for (p = *argv++; *p; p++)
{
*p &= 0177;
(void) fputc(*p, fd);
if (*p == '\n') (void) fputc('+', fd);
}
(void) fputc(' ', fd);
}
(void) fputs("\n\nThought you might want to know.",fd);
(void) pclose(fd);
}
/*
** firsthostname() - return hostname without domain stuff.
** Parameters - pointer to char array for name, and length of array.
*/
void
firsthostname(n, l)
char *n;
int l;
{
(void) gethostname(n, l); /* get full hostname */
n[l-1] = 0; /* make sure null terminated */
if (n = index(n, '.')) *n = 0; /* blat null on top of '.' if any */
}
** sudo - run a command as root
*/
#include <stdio.h>
#include <strings.h>
#include <ctype.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <pwd.h>
#ifndef MAXHOSTNAMELEN
#define MAXHOSTNAMELEN 64
#endif MAXHOSTNAMELEN
/* terryh */
/*#define ALERTMAIL "root"*/
#define ALERTMAIL "terryh"
/* terryh */
/* #define LOGFILE "/usr/local/adm/logs/sudo.log"*/
#define LOGFILE "/nfs/juno/u5/etc/bfdo/logs/bfdo.log"
extern char *ctime();
extern long time();
/* terryh */
/*char *userfile = "/usr/local/adm/sudoers";*/
char *userfile = "/nfs/juno/u5/etc/bfdo/bfdoers";
char *progname;
long now;
void log(), errexit(), firsthostname();
int checkdoer();
char *isadoer();
main(argc, argv)
int argc;
char *argv[];
{
char doerline[512];
char cmd[512];
char *dp;
struct passwd *pw;
int uid, pid;
progname = argv[0];
if(argc < 2)
{
fprintf(stderr, "usage: %s cmd\n", progname);
exit(1);
}
/* remember who this user really is */
uid = getuid();
/* Set userid to be root and group id to be daemon */
/* terryh if((setuid(0)) < 0)
{
eperror("setuid");
}*/
/* terryh if((setgid(3)) < 0)
{
eperror("setgid");
}*/
dp = &doerline[0];
pw = getpwuid(uid);
now = time((long*) 0);
if ((dp = isadoer(pw->pw_name,pw->pw_passwd)) == NULL)
{
log(pw->pw_name,"FAIL",argc,argv);
fprintf(stderr,"%s:I don't know you, and I'm telling!\n",*argv);
if ((pid = fork()) == 0)
mailmsg(pw->pw_name,argv,argc);
if (pid == -1)
eperror("fork");
exit(1);
}
argv++, argc--;
checkdoer(dp,*argv,cmd);
if (strcmp(cmd,"all") == 0)
{
log(pw->pw_name,"",argc, argv);
execvp(*argv, argv); /* then do it */
eperror(*argv);
}
if (cmd[0] == '\0')
{
log(pw->pw_name,"FAIL",argc,argv);
fprintf(stderr,
"%s: I know you, but I can't let you: %s\n",progname,*argv);
exit(1);
}
/* do a specific command with hard-coded path from doer file */
log(pw->pw_name,"",argc,argv);
execv(cmd, argv); /* then do it */
eperror(*argv);
}
/*
** isadoer(name, encrypted password) - look for a user in USERFILE
** return doer entry on success, else NULL.
*/
char *isadoer(name,password)
char *name;
char *password;
{
register FILE *fp;
char buf[BUFSIZ];
struct stat statb;
if (stat(userfile, &statb))
eperror(userfile);
/* terryh
if (statb.st_uid != 0)
errexit("%s must be owned by root\n", userfile);*/
/* terryh
if (statb.st_mode & 022)*/ /* should be og-w */
/*errexit("bad modes on %s\n", userfile);*/
if ((fp = fopen(userfile,"r")) == 0 )
errexit("Couldn't open %s\n",userfile);
while ((fgets(buf,BUFSIZ,fp)) != NULL)
{
if(buf[0] == '#') /* munch comments */
{
continue;
}
if((strncmp(buf,name,strlen(name))) == 0)
{
/* terryh */
/* if (not_timed_out(name,password)) */
{
return(buf);
}
return(NULL);
}
}
return(NULL);
}
/*
** log this command in the log file
*/
void
log(username, info, argc, argv)
char *username;
char *info;
int argc;
char **argv;
{
register FILE *fp;
fp = fopen(LOGFILE,"a");
if (fp == NULL)
{
errexit("can't open %s.\n", LOGFILE);
}
fprintf (fp, "%20.20s :", ctime(&now));
fprintf (fp,"%s",info);
fprintf (fp,"%7.7s :",username);
while (argc--)
{
fprintf (fp,"%s ",*argv++);
}
fprintf (fp,"\n");
(void) fclose (fp);
return;
}
/*
** eperror - print system error message and exit
** string s is printed too.
*/
eperror(s)
register char *s;
{
fprintf(stderr,"%s: ",progname);
perror(s);
exit(1);
}
/*
** errexit(format, message) - print formatted error and exit
** also send mail
*/
void
errexit(fmt, arg)
register char *fmt, *arg;
{
FILE *popen();
FILE *fd;
char hostname[MAXHOSTNAMELEN];
char cmd[80];
fprintf(stderr,"%s: ", progname);
fprintf(stderr, fmt, arg);
if ((fd = popen(cmd, "w")) == NULL)
{
return;
}
firsthostname(hostname, MAXHOSTNAMELEN);
(void) sprintf(cmd,
"/usr/ucb/mail -s \"HELP! %s@%s has problems.\" %s ",
progname,hostname,ALERTMAIL);
if ((fd = popen(cmd, "w")) == NULL)
{
return;
}
fprintf(fd,"%s: ", progname);
fprintf(fd, fmt, arg);
(void) pclose(fd);
exit(1);
}
/*
** checkdoer - check to see if user is permitted to do command requested.
** dp points to a sudoer file entry of the form:
** 'user ['all,','/dir/dir/cmd1,/dir/dir/cmd2,/dir/dir/cmdN'] ie)
** coggs /bin/wall,/etc/vipassw,/etc/adduser
** operator shutdown
** If 'all' is found, then string "all" is returned in res.
** If command passed in ap is found, then that command, along
** with its full path are passed back in res. If nothing is
** found, then NULL is returned in res.
*/
checkdoer(dp,ap,res)
char *dp; /* doer file entry: 'user cmd1,cmd2,cmdN' */
char *ap;
char *res;
{
char *cp0, *cp1, *cp2;
cp0 = dp;
while(isalnum(*cp0)) /* skip past user field */
{
cp0++;
}
while(*cp0) /* search until end of line */
{
while(isspace(*cp0)) /* skip to beg of cmd field */
{
cp0++;
}
if (strncmp(cp0,"all",3) == 0) /* if cmd field is "all" */
{
(void) strcpy(res,"all"); /* then pass it back */
return;
}
cp1 = cp0;
/* find end of this entry */
while (*cp1 != '\n' && !isspace(*cp1))
{
cp1++;
}
cp1--; /* point to last character of cmd */
cp2 = cp1;
while (*cp2 != '/') /* backup to head of command */
{
cp2--;
}
cp2++;
cp1++; /* point cp1 to last character + 1 */
/* if command issued is found then pass whole path back */
if (strncmp(cp2,ap,strlen(ap)) == 0)
{
(void) strncpy(res,cp0,cp1-cp0); /* copy command back */
*(res+(cp1-cp0)) = '\0'; /* terryh */
return;
}
/*
* if it got to here, then command not found *yet*
* move pointer past next comma and keep looking
*/
while (!isspace(*cp0) && *cp0 != '\n')
{
cp0++;
}
if (*cp0 == '\n') /* if at endo of line then fail */
{
break;
}
else
{
continue;
}
}
*res = NULL;
return;
}
/*
** mailmsg - Snitch on person
*/
mailmsg (user,argv,argc)
char *user, **argv;
int argc;
{
FILE *popen();
FILE *fd;
char *p;
char cmd[80];
char hostname[MAXHOSTNAMELEN];
firsthostname(hostname, MAXHOSTNAMELEN);
(void) sprintf(cmd,
"/usr/ucb/mail -s \"*SECURITY* %s@%s tried to execute %s\" %s ",
user,hostname,*argv,ALERTMAIL);
if ((fd = popen(cmd, "w")) == NULL)
{
return;
}
fprintf(fd,"%s\@%s tried to do a\n\n ",user,hostname);
while(argc--)
{
for (p = *argv++; *p; p++)
{
*p &= 0177;
(void) fputc(*p, fd);
if (*p == '\n') (void) fputc('+', fd);
}
(void) fputc(' ', fd);
}
(void) fputs("\n\nThought you might want to know.",fd);
(void) pclose(fd);
}
/*
** firsthostname() - return hostname without domain stuff.
** Parameters - pointer to char array for name, and length of array.
*/
void
firsthostname(n, l)
char *n;
int l;
{
(void) gethostname(n, l); /* get full hostname */
n[l-1] = 0; /* make sure null terminated */
if (n = index(n, '.')) *n = 0; /* blat null on top of '.' if any */
}
0 0
- sudo.c
- sudo
- sudo
- sudo
- Sudo
- sudo
- sudo
- sudo
- sudo
- sudo
- sudo
- Sudo
- sudo
- sudo
- sudo
- sudo
- sudo
- sudo
- 黑马程序员--Java常用的类
- android 简析 addToBackStack使用和Fragment执行流程
- 局部变量
- 使用“swap技巧”除去多余的容量
- IOS练习题
- sudo.c
- 怎样防止sql注入
- 初识 Cloudera Impala
- Linux中,PHP以root身份运行外部命令-sudo实施方法
- extjs4 异步树的写法
- package,import,include的联系与区别【好】
- Eclipse中SVN的安装步骤(两种)和使用方法
- 最长公共子序列
- eclipse使用技巧一