Need help improving a small C program
I wanted to launch a bash script (read: bash not sh script) as a root not as the user calling it, however bash ignore setuid on scripts, so I chose to write a very small script that takes a script/arguments and call it with setuid set.

This worked well and I went even further to verify that the script has setuid set on, executable and setuid() called on the owner of the file and not as root, to avoid any misuse of the program and I ended up with the program below..

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>

    int main(int argc, char **argv)
    {
      char *command;
      int i, file_owner;
      struct stat status_buf;
      ushort file_mode;

      // Check argc
      if (argc < 2) {
        printf("Usage: %s <script> [arguments]\n", argv[0]);
        return 1;
      }
  
      // Make sure the script does exist
      if(fopen(argv[1], "r") == NULL) {
        printf("The file %s does not exist.\n", argv[1]);
        return 1;
      }
  
      // Get the attributes of the file
      stat(argv[1], &status_buf);
  
      // Get the permissions of the file
      file_mode = status_buf.st_mode;
  
      // Make sure it's executable and it's setuid
      if(file_mode >> 6 != 567) {
        printf("The file %s should be executable and should have setuid set, please chmod it 0106755.\n", argv[1]);
        return 1;
      }
  
      // Get the owner of the script
      file_owner = status_buf.st_uid;

      // setuid
      setuid(file_owner);

      // call the script
      command = (char *) malloc( (strlen(argv[1]) + 10) * sizeof(char) );
      sprintf(command, "/bin/bash %s", argv[1]);
      if (argc > 2) {
        for (i = 2; i < argc; i++) {
          realloc(command, (strlen(argv[i]) + 1 + strlen(command)) * sizeof(char) );
          sprintf(command, "%s %s", command, argv[i]);
        }
      }

      // Execute the command
      system(command);

      // free memory
      free(command);

      return 0;
    }


The exercise was not only to solve my problem, but it was also a way to get more into C, so what do you guys suggest? Is there anything I should improve ?

Thank you..

Need help improving a small C program
===

I wanted to launch a bash script (read: bash not sh script) as a root not as the user calling it, however bash ignore setuid on scripts, so I chose to write a very small script that takes a script/arguments and call it with setuid set.

This worked well and I went even further to verify that the script has setuid set on, executable and setuid() called on the owner of the file and not as root, to avoid any misuse of the program and I ended up with the program below..

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <sys/types.h>
    #include <sys/stat.h>

    int main(int argc, char **argv)
    {
      char *command;
      int i, file_owner;
      struct stat status_buf;
      ushort file_mode;

      // Check argc
      if (argc < 2) {
        printf("Usage: %s <script> [arguments]\n", argv[0]);
        return 1;
      }
  
      // Make sure the script does exist
      if(fopen(argv[1], "r") == NULL) {
        printf("The file %s does not exist.\n", argv[1]);
        return 1;
      }
  
      // Get the attributes of the file
      stat(argv[1], &status_buf);
  
      // Get the permissions of the file
      file_mode = status_buf.st_mode;
  
      // Make sure it's executable and it's setuid
      if(file_mode >> 6 != 567) {
        printf("The file %s should be executable and should have setuid set, please chmod it 0106755.\n", argv[1]);
        return 1;
      }
  
      // Get the owner of the script
      file_owner = status_buf.st_uid;

      // setuid
      setuid(file_owner);

      // call the script
      command = (char *) malloc( (strlen(argv[1]) + 10) * sizeof(char) );
      sprintf(command, "/bin/bash %s", argv[1]);
      if (argc > 2) {
        for (i = 2; i < argc; i++) {
          realloc(command, (strlen(argv[i]) + 1 + strlen(command)) * sizeof(char) );
          sprintf(command, "%s %s", command, argv[i]);
        }
      }

      // Execute the command
      system(command);

      // free memory
      free(command);

      return 0;
    }


The exercise was not only to solve my problem, but it was also a way to get more into C, so what do you guys suggest? Is there anything I should improve ?

Thank you..
