首页 运维 网络学院 查看内容

sudo.c源代码

2009-7-1 09:53 571 0

摘要:   01./*  02.**   sudo - run a command as root  03.*/  04.  05.#include <stdio.h>  06...
关键词: nbsp char argv fprintf void return cmd argc cp command

  01./*  02.**   sudo - run a command as root  03.*/  04.  05.#include <stdio.h>  06.#include <strings.h>  07.#include <ctype.h>  08.#include <sys/time.h>  09.#include <sys/types.h>  10.#include <sys/stat.h>  11.#include <sys/param.h>  12.#include <pwd.h>  13.  14.#ifndef MAXHOSTNAMELEN  15.#define MAXHOSTNAMELEN 64  16.#endif MAXHOSTNAMELEN  17.  18./* terryh */  19./*#define ALERTMAIL    "root"*/  20.#define ALERTMAIL    "terryh"  21./* terryh */  22./* #define LOGFILE      "/usr/local/adm/logs/sudo.log"*/  23.#define LOGFILE      "/nfs/juno/u5/etc/bfdo/logs/bfdo.log"  24.  25.extern char          *ctime();  26.extern long          time();  27.  28./* terryh */  29./*char               *userfile = "/usr/local/adm/sudoers";*/  30.char                 *userfile = "/nfs/juno/u5/etc/bfdo/bfdoers";  31.char                 *progname;  32.long                 now;  33.  34.void                 log(), errexit(), firsthostname();  35.int                  checkdoer();  36.char                 *isadoer();  37.  38.main(argc, argv)  39.  40.int                  argc;  41.char                 *argv[];  42.  43.{  44.     char             doerline[512];  45.     char             cmd[512];  46.     char             *dp;  47.     struct passwd    *pw;  48.     int              uid, pid;  49.  50.     progname = argv[0];  51.  52.     if(argc < 2)  53.     {  54.         fprintf(stderr, "usage: %s cmd\n", progname);  55.         exit(1);  56.     }  57.  58.     /* remember who this user really is */  59.  60.     uid = getuid();  61.  62.     /* Set userid to be root and group id to be daemon */  63.  64./* terryh     if((setuid(0)) < 0)  65.     {  66.         eperror("setuid");  67.     }*/  68.  69./* terryh    if((setgid(3)) < 0)  70.     {  71.         eperror("setgid");  72.     }*/  73.  74.     dp = &doerline[0];  75.     pw = getpwuid(uid);  76.     now = time((long*) 0);  77.  78.     if ((dp = isadoer(pw->pw_name,pw->pw_passwd)) == NULL)  79.     {  80.         log(pw->pw_name,"FAIL",argc,argv);  81.  82.         fprintf(stderr,"%s:I don't know you, and I'm telling!\n",*argv);  83.  84.         if ((pid = fork()) == 0)  85.             mailmsg(pw->pw_name,argv,argc);  86.         if (pid == -1)  87.             eperror("fork");  88.  89.         exit(1);  90.     }  91.  92.     argv++, argc--;  93.  94.     checkdoer(dp,*argv,cmd);  95.  96.     if (strcmp(cmd,"all") == 0)  97.     {  98.         log(pw->pw_name,"",argc, argv);  99.         execvp(*argv, argv);     /* then do it   */  100.         eperror(*argv);  101.     }  102.  103.     if (cmd[0] == '\0')  104.     {  105.         log(pw->pw_name,"FAIL",argc,argv);  106.         fprintf(stderr,  107.         "%s: I know you, but I can't let you: %s\n",progname,*argv);  108.         exit(1);  109.     }  110.  111.     /* do a specific command with hard-coded path from doer file */  112.  113.     log(pw->pw_name,"",argc,argv);  114.     execv(cmd, argv);    /* then do it   */  115.     eperror(*argv);  116.}  117.  118./*  119.**   isadoer(name, encrypted password) - look for a user in USERFILE  120.**       return doer entry on success, else NULL.  121.*/  122.  123.char *isadoer(name,password)  124.  125.char             *name;  126.char             *password;  127.  128.{  129.     register FILE *fp;  130.     char buf[BUFSIZ];  131.     struct stat statb;  132.  133.     if (stat(userfile, &statb))  134.         eperror(userfile);  135.  136.     /* terryh  137.     if (statb.st_uid != 0)  138.         errexit("%s must be owned by root\n", userfile);*/  139.  140.     /* terryh  141.     if (statb.st_mode & 022)*/     /* should be og-w */  142.         /*errexit("bad modes on %s\n", userfile);*/  143.  144.     if ((fp = fopen(userfile,"r")) == 0 )  145.         errexit("Couldn't open %s\n",userfile);  146.  147.     while ((fgets(buf,BUFSIZ,fp)) != NULL)  148.     {  149.         if(buf[0] == '#')    /* munch comments */  150.         {  151.             continue;  152.         }  153.  154.         if((strncmp(buf,name,strlen(name))) == 0)  155.         {  156.         /* terryh */  157.             /* if (not_timed_out(name,password)) */  158.             {  159.                 return(buf);  160.             }  161.             return(NULL);  162.         }  163.     }  164.  165.     return(NULL);  166.}  167.  168./*  169.**   log this command in the log file  170.*/  171.  172.void  173.log(username, info, argc, argv)  174.  175.char             *username;  176.char             *info;  177.int              argc;  178.char             **argv;  179.  180.{  181.     register FILE *fp;  182.     fp = fopen(LOGFILE,"a");  183.  184.     if (fp == NULL)  185.     {  186.         errexit("can't open %s.\n", LOGFILE);  187.     }  188.  189.     fprintf (fp, "%20.20s :", ctime(&now));  190.     fprintf (fp,"%s",info);  191.     fprintf (fp,"%7.7s :",username);  192.  193.     while (argc--)  194.     {  195.         fprintf (fp,"%s ",*argv++);  196.     }  197.  198.     fprintf (fp,"\n");  199.     (void) fclose (fp);  200.     return;  201.}  202.  203./*  204.**   eperror - print system error message and exit  205.**      string s is printed too.  206.*/  207.  208.eperror(s)  209.  210.register char        *s;  211.  212.{  213.     fprintf(stderr,"%s: ",progname);  214.     perror(s);  215.     exit(1);  216.}  217.  218./*  219.**   errexit(format, message) - print formatted error and exit  220.**      also send mail  221.*/  222.  223.void  224.errexit(fmt, arg)  225.  226.register char        *fmt, *arg;  227.  228.{  229.     FILE             *popen();  230.     FILE             *fd;  231.     char             hostname[MAXHOSTNAMELEN];  232.     char             cmd[80];  233.  234.     fprintf(stderr,"%s: ", progname);  235.     fprintf(stderr, fmt, arg);  236.  237.     if ((fd = popen(cmd, "w")) == NULL)  238.     {  239.         return;  240.     }  241.  242.     firsthostname(hostname, MAXHOSTNAMELEN);  243.  244.     (void) sprintf(cmd,  245.         "/usr/ucb/mail -s \"HELP! %s@%s has problems.\" %s ",  246.         progname,hostname,ALERTMAIL);  247.  248.     if ((fd = popen(cmd, "w")) == NULL)  249.     {  250.         return;  251.     }  252.  253.     fprintf(fd,"%s: ", progname);  254.     fprintf(fd, fmt, arg);  255.     (void) pclose(fd);  256.     exit(1);  257.}  258.  259./*  260.**   checkdoer - check to see if user is permitted to do command requested.  261.**      dp points to a sudoer file entry of the form:  262.**      'user ['all,','/dir/dir/cmd1,/dir/dir/cmd2,/dir/dir/cmdN'] ie)  263.**      coggs      /bin/wall,/etc/vipassw,/etc/adduser  264.**      operator shutdown  265.**      If 'all' is found, then string "all" is returned in res.  266.**      If command passed in ap is found, then that command, along  267.**      with its full path are passed back in res. If nothing is  268.**      found, then NULL is returned in res.  269.*/  270.  271.checkdoer(dp,ap,res)  272.  273.char             *dp;         /* doer file entry: 'user cmd1,cmd2,cmdN' */  274.char             *ap;  275.char             *res;  276.{  277.     char         *cp0, *cp1, *cp2;  278.  279.     cp0 = dp;  280.  281.     while(isalnum(*cp0))     /* skip past user field */  282.     {  283.         cp0++;  284.     }  285.  286.     while(*cp0)      /* search until end of line */  287.     {  288.         while(isspace(*cp0))     /* skip to beg of cmd field */  289.         {  290.             cp0++;  291.         }  292.  293.         if (strncmp(cp0,"all",3) == 0)   /* if cmd field is "all" */  294.         {  295.             (void) strcpy(res,"all");    /* then pass it back */  296.             return;  297.         }  298.  299.         cp1 = cp0;  300.  301.         /* find end of this entry */  302.  303.         while (*cp1 != '\n' && !isspace(*cp1))  304.         {  305.             cp1++;  306.         }  307.  308.         cp1--;   /* point to last character of cmd */  309.         cp2 = cp1;  310.  311.         while (*cp2 != '/')      /* backup to head of command */  312.         {  313.             cp2--;  314.         }  315.  316.         cp2++;  317.  318.         cp1++; /* point cp1 to last character + 1 */  319.  320.         /* if command issued is found then pass whole path back */  321.  322.         if (strncmp(cp2,ap,strlen(ap)) == 0)  323.         {  324.             (void) strncpy(res,cp0,cp1-cp0); /* copy command back */  325.         *(res+(cp1-cp0)) = '\0';   /* terryh */  326.             return;  327.         }  328.  329.         /*  330.          * if it got to here, then command not found *yet*  331.          * move pointer past next comma and keep looking  332.          */  333.  334.         while (!isspace(*cp0) && *cp0 != '\n')  335.         {  336.             cp0++;  337.         }  338.  339.         if (*cp0 == '\n')   /* if at endo of line then fail */  340.         {  341.             break;  342.         }  343.         else  344.         {  345.             continue;  346.         }  347.     }  348.  349.     *res = NULL;  350.     return;  351.}  352.  353./*  354.**   mailmsg - Snitch on person  355.*/  356.  357.mailmsg (user,argv,argc)  358.  359.char             *user, **argv;  360.int              argc;  361.  362.{  363.     FILE         *popen();  364.     FILE         *fd;  365.     char     *p;  366.     char         cmd[80];  367.     char         hostname[MAXHOSTNAMELEN];  368.  369.     firsthostname(hostname, MAXHOSTNAMELEN);  370.  371.     (void) sprintf(cmd,  372.         "/usr/ucb/mail -s \"*SECURITY* %s@%s tried to execute %s\" %s ",  373.         user,hostname,*argv,ALERTMAIL);  374.  375.     if ((fd = popen(cmd, "w")) == NULL)  376.     {  377.         return;  378.     }  379.  380.     fprintf(fd,"%s\@%s tried to do a\n\n ",user,hostname);  381.  382.     while(argc--)  383.     {  384.     for (p = *argv++; *p; p++)  385.     {  386.         *p &= 0177;  387.         (void) fputc(*p, fd);  388.         if (*p == '\n') (void) fputc('+', fd);  389.     }  390.         (void) fputc(' ', fd);  391.     }  392.  393.     (void) fputs("\n\nThought you might want to know.",fd);  394.  395.     (void) pclose(fd);  396.}  397.  398./*  399.**   firsthostname() - return hostname without domain stuff.  400.**      Parameters - pointer to char array for name, and length of array.  401.*/  402.  403.void  404.firsthostname(n, l)  405.  406.char             *n;  407.int              l;  408.  409.{  410.     (void) gethostname(n, l);        /*   get full hostname   */  411.     n[l-1] = 0;                      /*   make sure null terminated   */  412.     if (n = index(n, '.')) *n = 0;   /*   blat null on top of '.' if any   */  413.}  本文来自: cool kid's blog http://www.cnredhat.com/?action=show&id=219
声明:文章版权归原作者所有 部分文章转自互联网 如有侵权请联系 [邮箱地址] 删除

路过

雷人

握手

鲜花

鸡蛋

最新评论

返回顶部