Guest User

some C wrapper

a guest
Oct 19th, 2011
108
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 3.78 KB | None | 0 0
  1. ┌─[22:59]-[root@stavrovski]-[~]
  2. └─› cat /tmp/wrapper.c
  3. /**
  4.  * vim:ft=c:fenc=UTF-8:ts=2:sts=2:sw=2:expandtab
  5.  *
  6.  * Copyright 2011 TechnoGate <[email protected]>
  7.  *
  8.  * This program is free software: you can redistribute it and/or modify it under the
  9.  * terms of the GNU General Public License as published by the Free Software
  10.  * Foundation, either version 3 of the License, or (at your option) any later
  11.  * version.
  12.  *
  13.  * This program is distributed in the hope that it will be useful, but WITHOUT ANY
  14.  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
  15.  * PARTICULAR PURPOSE. See the GNU General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU General Public License along with
  18.  * This program. If not, see http://www.gnu.org/licenses/
  19.  */
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <unistd.h>
  24. #include <string.h>
  25. #include <sys/types.h>
  26. #include <sys/stat.h>
  27. #include <pwd.h>
  28.  
  29. int main(int argc, char **argv)
  30. {
  31.   int    file_owner, status;
  32.   char   *newenviron[] = { NULL };
  33.   uid_t  current_uid;
  34.   pid_t  child_pid, wpid;
  35.   ushort file_mode;
  36.   struct stat status_buf;
  37.   struct passwd * passent;
  38.  
  39.   // Check that we are root!
  40.   current_uid = geteuid();
  41.   if(current_uid != 0) {
  42.     fprintf(stderr, "The wrapper should be ran as root, you should maybe set the owner to root and set setuid.\n");
  43.     return 1;
  44.   }
  45.  
  46.   // Check argc
  47.   if (argc < 2) {
  48.     fprintf(stderr, "Usage: %s <script> [arguments]\n", argv[0]);
  49.     return 1;
  50.   }
  51.  
  52.   // Make sure the script does exist
  53.   if(fopen(argv[1], "r") == NULL) {
  54.     fprintf(stderr, "The file %s does not exist.\n", argv[1]);
  55.     return 1;
  56.   }
  57.  
  58.   // Get the attributes of the file
  59.   if(stat(argv[1], &status_buf) < 0) {
  60.     fprintf(stderr, "Can't stat %s\n", argv[1]);
  61.     return 1;
  62.   }
  63.  
  64.   // Get the permissions of the file
  65.   file_mode = status_buf.st_mode;
  66.  
  67.   // Make sure it's executable and it's setuid
  68.   if( !( (file_mode & S_ISUID) || (file_mode & S_IXUSR) ) ) {
  69.     fprintf(stderr, "The file %s should be executable and should have setuid set.\n", argv[1]);
  70.     return 1;
  71.   }
  72.  
  73.   // Get the owner of the script
  74.   file_owner = status_buf.st_uid;
  75.  
  76.   // Get the name of the owner
  77.   passent = getpwuid(file_owner);
  78.  
  79.   // setuid
  80.   if(setuid(file_owner)) {
  81.     if(passent != NULL)
  82.       fprintf(stderr, "Can't change the persona to %s\n", passent -> pw_name);
  83.     else
  84.       fprintf(stderr, "Can't change the persona to %d\n", file_owner);
  85.     return 1;
  86.   }
  87.  
  88.   // Fork
  89.   child_pid = fork();
  90.   if(child_pid == -1) {
  91.     perror("fork");
  92.     exit(EXIT_FAILURE);
  93.   }
  94.  
  95.   // Execute the command in a child
  96.   if(child_pid == 0) {
  97.     execve(argv[1], argv + 1, newenviron);
  98.     perror("Failed to execute the script");
  99.     exit(EXIT_FAILURE);
  100.   } else {
  101.     do {
  102.       wpid = waitpid(child_pid, &status, WUNTRACED
  103.     #ifdef WCONTINUED       /* Not all implementations support this */
  104.         | WCONTINUED
  105.     #endif
  106.         );
  107.  
  108.       // Seems the child is not running
  109.       if (wpid == -1) {
  110.         perror("waitpid");
  111.         exit(EXIT_FAILURE);
  112.       }
  113.  
  114.       if (WIFEXITED(status)) { /* Child exited ? */
  115.         return WEXITSTATUS(status);
  116.  
  117.  
  118.       } else if (WIFSIGNALED(status)) { /* Child signaled ? */
  119.         return WTERMSIG(status);
  120.  
  121.       } else if (WIFSTOPPED(status)) { /* Child stopped */
  122.         return WSTOPSIG(status);
  123.  
  124.  
  125.     #ifdef WIFCONTINUED     /* Not all implementations support this */
  126.       } else if (WIFCONTINUED(status)) {
  127.         // The child is still running...
  128.     #endif
  129.       } else {    /* Non-standard case -- may never happen */
  130.         printf("Unexpected status (0x%x)\n", status);
  131.       }
  132.     } while (!WIFEXITED(status) && !WIFSIGNALED(status));
  133.   }
  134.  
  135.   return EXIT_FAILURE;
  136. }
  137.  
  138.  
Advertisement
Add Comment
Please, Sign In to add comment