//////////////////////////////////////////////////
// su w/o password
//
// Install: 
//   - modify the #define USER below to be your user name
//   - compile: gcc -o su su.c
//   - place in *your* path BEFORE the regular su command
//     - don't place it in the system path, b/c this is only 
//       useful to you
//   - make root the owner: chown root.root su
//   - set sticky bit: chmod +s su
//     - you'll need to be root to do this
// Usage:
//   - su
//       switch to root
//   - su <user> 
//       switch to user
//   - su -- cmd
//       run single command as root
//

#define USER "barr"

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pwd.h>

//#define DEBUG 1

#ifdef DEBUG
#define printf(x)    fprintf(stderr, x)
#define printf1(x,y) fprintf(stderr, x, y)
#else
#define printf(x)    {}
#define printf1(x,y) {}
#endif

char *getenv();
char *usage = "\nsu: format: `su [[-] login]' or `su -- \"command\"'\n";

main (int argc, char *argv[])
{
  int i, com=0;
  char command[300], *shell, msg[300];

  if (getuid() != getpwnam(USER)->pw_uid) {
    fprintf(stderr, "su: Permission denied.\n");
    exit(1);
  }

  shell = getenv("SHELL");
  if (shell == NULL)
    shell = "/bin/sh";

  if (argc == 1) {
    sprintf(msg, "");
    sprintf(command, shell);
  } else if (argc == 2 && argv[1][0] != '-') {
    sprintf(msg, "#### User is: %-10s ####\n", argv[1]);
    sprintf(command, "/bin/su %s", argv[1]);
  } else if (argc == 2) {
    fprintf(stderr, usage);
    exit(1);
  } else if (argc == 3 && !strcmp(argv[1], "-")) {
    sprintf(msg, "#### Login as: %-9s ####\n", argv[2]);
    sprintf(command, "/bin/su - %s", argv[2]);
  } else if (!strcmp(argv[1], "--")) {
    sprintf(command, "");
    for (i = 2; i < argc; i++) {
      strcat(command, " ");
      strcat(command, argv[i]);
    }
    sprintf(msg, "#### Command:%-11s ####\n", command);
    com = 1;
  } else if (!strcmp(argv[2], "--")) {
    sprintf(command, "/bin/su %s -c \"", argv[1]);
    for (i = 3; i < argc; i++) {
      strcat(command, " ");
      strcat(command, argv[i]);
    }
    strcat(command, "\"");
    sprintf(msg, "#### User is: %-10s ####\n#### Command:%-11s ####\n",
            argv[1], command);
    com = 1;
  } else {
    fprintf(stderr, usage);
    exit(1);
  }
  printf1("#############################\n%s", msg);

  if (setuid(0) || setgid(0)) {
    printf("setuid Failure!\n");
    exit(1);
  }
  printf("#### SUPER USER MODE ON! ####\n\n");
  if (com)
    printf1(">>> %s\n", command);
  system(command);
  printf("\n#### SUPER USER MODE OFF ####\n#############################\n");
}

