#define NULL ((void *)0)
typedef unsigned long size_t; // Customize by platform.
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef long scalar_t__; // Either arithmetic or pointer type.
/* By default, we understand bool (as a convenience). */
typedef int bool;
#define false 0
#define true 1

/* Forward declarations */

/* Type definitions */
struct passwd {
  char *pw_name;
  char *pw_dir;
  int /*<<< orphan*/ pw_uid;
  int /*<<< orphan*/ pw_gid;
};
typedef int /*<<< orphan*/ FILE;

/* Variables and functions */
int EXIT_FAILURE;
int EXIT_SUCCESS;
int PATH_MAX;
scalar_t__ atoi(char *);
scalar_t__ chdir(char *);
int /*<<< orphan*/ check_user_auth(char *, char *, int /*<<< orphan*/ *);
scalar_t__ clearenv();
int /*<<< orphan*/ close_fds();
int /*<<< orphan*/ command_found(char *, char *);
int do_log(char *, char *, char *, char *, char **);
int execvp(char *, char **);
int /*<<< orphan*/ exit(int);
int /*<<< orphan*/ fclose(int /*<<< orphan*/ *);
int /*<<< orphan*/ *fopen(char *, char *);
int /*<<< orphan*/ fprintf(int /*<<< orphan*/, char *, ...);
int /*<<< orphan*/ free(char *);
char *get_current_dir_name();
char *getenv(char *);
struct passwd *getpwnam(char *);
struct passwd *getpwuid(scalar_t__);
scalar_t__ getuid();
scalar_t__ initgroups(char *, int /*<<< orphan*/);
int /*<<< orphan*/ perror(char *);
int /*<<< orphan*/ printf(char *, ...);
scalar_t__ setenv(char *, char *, int);
scalar_t__ setgid(int /*<<< orphan*/);
scalar_t__ setgroups(int /*<<< orphan*/, int /*<<< orphan*/ *);
scalar_t__ setuid(int /*<<< orphan*/);
int /*<<< orphan*/ setup_environment(char *, int /*<<< orphan*/ *);
int /*<<< orphan*/ stderr;
int main(int argc, char **argv) {
  int ret = EXIT_SUCCESS;
  int i;
  struct passwd *pwd;
  static FILE *fp;
  char *to_chdir;
  char *from_user;
  char *cwd = get_current_dir_name();
  char cmdpath[PATH_MAX];
  if (argc < 3) {
    fprintf(stderr, "Usage: runasuser user program [args ...]\n");
    ret = EXIT_FAILURE;
    goto out;
  }
  pwd = getpwnam(argv[1]);
  if (!pwd) {
    fprintf(stderr, "Error: No such user %s\n", argv[1]);
    ret = EXIT_FAILURE;
    goto out;
  }
  fp = fopen("/etc/runasuser.conf", "r");
  if (!fp) {
    fp = fopen("/usr/local/etc/runasuser.conf", "r");
    if (!fp) {
      perror("fopen runasuser.conf");
      ret = EXIT_FAILURE;
      goto out;
    }
  }
  pwd = getpwuid(getuid());
  from_user = pwd->pw_name;
  if (getuid() > 0) {
    if (!check_user_auth(from_user, argv[1], fp)) {
      fprintf(stderr,
              "Error: You are not authorized to run "
              "as %s\n",
              argv[1]);
      ret = EXIT_FAILURE;
      goto out;
    }
  }
  fclose(fp);
  if (setgroups(0, NULL) != 0) {
    perror("setgroups");
    ret = EXIT_FAILURE;
    goto out;
  }
  pwd = getpwnam(argv[1]);
  if (initgroups(pwd->pw_name, pwd->pw_gid) != 0) {
    perror("initgroups");
    ret = EXIT_FAILURE;
    goto out;
  }
  if (setgid(pwd->pw_gid) != 0) {
    perror("setgid");
    ret = EXIT_FAILURE;
    goto out;
  }
  if (setuid(pwd->pw_uid) != 0) {
    perror("setuid");
    ret = EXIT_FAILURE;
    goto out;
  }
  to_chdir = getenv("RUNASUSER_CHDIR");
  if (!to_chdir || atoi(to_chdir) != 0) {
    if (chdir(pwd->pw_dir) != 0) {
      perror("chdir");
      ret = EXIT_FAILURE;
      goto out;
    }
  }
  if (clearenv() != 0) {
    perror("clearenv");
    ret = EXIT_FAILURE;
    goto out;
  }
  if (setenv("HOME", pwd->pw_dir, 1) != 0) {
    fprintf(stderr,
            "setenv: %s: can't set environment "
            "variable\n",
            "HOME");
    ;
    ret = EXIT_FAILURE;
    goto out;
  }
  if (setenv("USER", pwd->pw_name, 1) != 0) {
    fprintf(stderr,
            "setenv: %s: can't set environment "
            "variable\n",
            "USER");
    ;
    ret = EXIT_FAILURE;
    goto out;
  }
  if (setenv("RUNASUSER_USER", from_user, 1) != 0) {
    fprintf(stderr,
            "setenv: %s: can't set environment "
            "variable\n",
            "RUNASUSER_USER");
    ;
    ret = EXIT_FAILURE;
    goto out;
  }
  if (setenv("PATH", "/usr/local/bin:/bin:/usr/bin", 1) != 0) {
    fprintf(stderr,
            "setenv: %s: can't set environment "
            "variable\n",
            "PATH");
    ;
    ret = EXIT_FAILURE;
    goto out;
  }
  fp = fopen("/etc/runasuser.env.conf", "r");
  if (!fp)
    fp = fopen("/usr/local/etc/runasuser.env.conf", "r");
  if (fp) {
    if (!setup_environment(pwd->pw_name, fp)) {
      ret = EXIT_FAILURE;
      goto out;
    }
    fclose(fp);
  }
  if (!command_found(argv[2], cmdpath)) {
    fprintf(stderr, "runasuser: %s: command not found\n", argv[2]);
    ret = EXIT_FAILURE;
    goto out;
  }
  printf("Execing [ ");
  for (i = 2; i < argc; i++)
    printf("%s ", argv[i]);
  printf("]\n");
  ret = do_log(from_user, pwd->pw_name, cwd, cmdpath, argv);
  if (!ret) {
    ret = EXIT_FAILURE;
    goto out;
  }
  close_fds();
  if (execvp(argv[2], argv + 2) == -1) {
    perror("exec");
    ret = EXIT_FAILURE;
  }
out:
  free(cwd);
  exit(ret);
}


x86 assembly (clang, -O0):
<main>:
push   %rbp
mov    %rsp,%rbp
sub    $0x50,%rsp
movl   $0x0,-0x4(%rbp)
mov    %edi,-0x8(%rbp)
mov    %rsi,-0x10(%rbp)
mov    0x2d0b(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
xor    %eax,%eax
call   1110 <get_current_dir_name@plt>
mov    %rax,-0x38(%rbp)
mov    0x2d1c(%rip),%rax
mov    (%rax),%eax
mov    %rsp,%rcx
mov    %rcx,-0x40(%rbp)
mov    %rax,%rdx
add    $0xf,%rdx
and    $0xfffffffffffffff0,%rdx
mov    %rsp,%rcx
sub    %rdx,%rcx
mov    %rcx,-0x50(%rbp)
mov    %rcx,%rsp
mov    %rax,-0x48(%rbp)
cmpl   $0x3,-0x8(%rbp)
jge    132b <main+0x8b>
mov    0x2cce(%rip),%rax
mov    (%rax),%edi
lea    0xced(%rip),%rsi
mov    $0x0,%al
call   1100 <fprintf@plt>
mov    0x2caf(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
jmp    18da <main+0x63a>
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdi
call   10f0 <getpwnam@plt>
mov    %rax,-0x20(%rbp)
cmpq   $0x0,-0x20(%rbp)
jne    1377 <main+0xd7>
mov    0x2c8a(%rip),%rax
mov    (%rax),%edi
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdx
lea    0xccb(%rip),%rsi
mov    $0x0,%al
call   1100 <fprintf@plt>
mov    0x2c63(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
jmp    18da <main+0x63a>
lea    0xcce(%rip),%rdi
lea    0xd53(%rip),%rsi
call   1130 <fopen@plt>
mov    %rax,0x2d6f(%rip)
cmpq   $0x0,0x2d67(%rip)
jne    13e9 <main+0x149>
lea    0xc9c(%rip),%rdi
lea    0xd2b(%rip),%rsi
call   1130 <fopen@plt>
mov    %rax,0x2d47(%rip)
cmpq   $0x0,0x2d3f(%rip)
jne    13e4 <main+0x144>
lea    0xc92(%rip),%rdi
call   1140 <perror@plt>
mov    0x2bf6(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
jmp    18da <main+0x63a>
jmp    13e9 <main+0x149>
mov    $0x0,%al
call   10a0 <getuid@plt>
mov    %rax,%rdi
call   1070 <getpwuid@plt>
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
mov    (%rax),%rax
mov    %rax,-0x30(%rbp)
mov    $0x0,%al
call   10a0 <getuid@plt>
cmp    $0x0,%rax
jle    146e <main+0x1ce>
mov    -0x30(%rbp),%rdi
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rsi
mov    0x2cd5(%rip),%rdx
call   1150 <check_user_auth@plt>
cmp    $0x0,%eax
jne    1469 <main+0x1c9>
mov    0x2b98(%rip),%rax
mov    (%rax),%edi
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdx
lea    0xc24(%rip),%rsi
mov    $0x0,%al
call   1100 <fprintf@plt>
mov    0x2b71(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
jmp    18da <main+0x63a>
jmp    146e <main+0x1ce>
mov    0x2c8b(%rip),%rdi
call   1060 <fclose@plt>
xor    %edi,%edi
xor    %eax,%eax
mov    %eax,%esi
call   10c0 <setgroups@plt>
cmp    $0x0,%rax
je     14ac <main+0x20c>
lea    0xc0b(%rip),%rdi
call   1140 <perror@plt>
mov    0x2b2e(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
jmp    18da <main+0x63a>
mov    -0x10(%rbp),%rax
mov    0x8(%rax),%rdi
call   10f0 <getpwnam@plt>
mov    %rax,-0x20(%rbp)
mov    -0x20(%rbp),%rax
mov    (%rax),%rdi
mov    -0x20(%rbp),%rax
mov    0x14(%rax),%esi
call   11b0 <initgroups@plt>
cmp    $0x0,%rax
je     14f7 <main+0x257>
lea    0xbca(%rip),%rdi
call   1140 <perror@plt>
mov    0x2ae3(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
jmp    18da <main+0x63a>
mov    -0x20(%rbp),%rax
mov    0x14(%rax),%edi
call   1120 <setgid@plt>
cmp    $0x0,%rax
je     152a <main+0x28a>
lea    0xba2(%rip),%rdi
call   1140 <perror@plt>
mov    0x2ab0(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
jmp    18da <main+0x63a>
mov    -0x20(%rbp),%rax
mov    0x10(%rax),%edi
call   1190 <setuid@plt>
cmp    $0x0,%rax
je     155d <main+0x2bd>
lea    0xb76(%rip),%rdi
call   1140 <perror@plt>
mov    0x2a7d(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
jmp    18da <main+0x63a>
lea    0xb60(%rip),%rdi
call   1030 <getenv@plt>
mov    %rax,-0x28(%rbp)
cmpq   $0x0,-0x28(%rbp)
je     158b <main+0x2eb>
mov    -0x28(%rbp),%rdi
call   1170 <atoi@plt>
cmp    $0x0,%rax
je     15c4 <main+0x324>
mov    -0x20(%rbp),%rax
mov    0x8(%rax),%rdi
call   1090 <chdir@plt>
cmp    $0x0,%rax
je     15bf <main+0x31f>
lea    0xb2b(%rip),%rdi
call   1140 <perror@plt>
mov    0x2a1b(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
jmp    18da <main+0x63a>
jmp    15c4 <main+0x324>
mov    $0x0,%al
call   1080 <clearenv@plt>
cmp    $0x0,%rax
je     15f2 <main+0x352>
lea    0xafe(%rip),%rdi
call   1140 <perror@plt>
mov    0x29e8(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
jmp    18da <main+0x63a>
mov    -0x20(%rbp),%rax
mov    0x8(%rax),%rsi
lea    0xae2(%rip),%rdi
mov    $0x1,%edx
call   1050 <setenv@plt>
cmp    $0x0,%rax
je     1644 <main+0x3a4>
mov    0x29bc(%rip),%rax
mov    (%rax),%edi
lea    0xac3(%rip),%rsi
lea    0xab7(%rip),%rdx
mov    $0x0,%al
call   1100 <fprintf@plt>
mov    0x2996(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
jmp    18da <main+0x63a>
mov    -0x20(%rbp),%rax
mov    (%rax),%rsi
lea    0xacc(%rip),%rdi
mov    $0x1,%edx
call   1050 <setenv@plt>
cmp    $0x0,%rax
je     1695 <main+0x3f5>
mov    0x296b(%rip),%rax
mov    (%rax),%edi
lea    0xa72(%rip),%rsi
lea    0xaa1(%rip),%rdx
mov    $0x0,%al
call   1100 <fprintf@plt>
mov    0x2945(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
jmp    18da <main+0x63a>
mov    -0x30(%rbp),%rsi
lea    0xa74(%rip),%rdi
mov    $0x1,%edx
call   1050 <setenv@plt>
cmp    $0x0,%rax
je     16e3 <main+0x443>
mov    0x291d(%rip),%rax
mov    (%rax),%edi
lea    0xa24(%rip),%rsi
lea    0xa49(%rip),%rdx
mov    $0x0,%al
call   1100 <fprintf@plt>
mov    0x28f7(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
jmp    18da <main+0x63a>
lea    0xa39(%rip),%rdi
lea    0xa37(%rip),%rsi
mov    $0x1,%edx
call   1050 <setenv@plt>
cmp    $0x0,%rax
je     1734 <main+0x494>
mov    0x28cc(%rip),%rax
mov    (%rax),%edi
lea    0x9d3(%rip),%rsi
lea    0xa07(%rip),%rdx
mov    $0x0,%al
call   1100 <fprintf@plt>
mov    0x28a6(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
jmp    18da <main+0x63a>
lea    0xa14(%rip),%rdi
lea    0x996(%rip),%rsi
call   1130 <fopen@plt>
mov    %rax,0x29b2(%rip)
cmpq   $0x0,0x29aa(%rip)
jne    1776 <main+0x4d6>
lea    0x9e2(%rip),%rdi
lea    0x96e(%rip),%rsi
call   1130 <fopen@plt>
mov    %rax,0x298a(%rip)
cmpq   $0x0,0x2982(%rip)
je     17bd <main+0x51d>
mov    -0x20(%rbp),%rax
mov    (%rax),%rdi
mov    0x296e(%rip),%rsi
call   11a0 <setup_environment@plt>
cmp    $0x0,%eax
jne    17b1 <main+0x511>
mov    0x2829(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
jmp    18da <main+0x63a>
mov    0x2948(%rip),%rdi
call   1060 <fclose@plt>
mov    -0x50(%rbp),%rsi
mov    -0x10(%rbp),%rax
mov    0x10(%rax),%rdi
call   10d0 <command_found@plt>
cmp    $0x0,%eax
jne    1807 <main+0x567>
mov    0x27fa(%rip),%rax
mov    (%rax),%edi
mov    -0x10(%rbp),%rax
mov    0x10(%rax),%rdx
lea    0x978(%rip),%rsi
mov    $0x0,%al
call   1100 <fprintf@plt>
mov    0x27d3(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
jmp    18da <main+0x63a>
lea    0x97b(%rip),%rdi
mov    $0x0,%al
call   10b0 <printf@plt>
movl   $0x2,-0x18(%rbp)
mov    -0x18(%rbp),%eax
cmp    -0x8(%rbp),%eax
jge    1850 <main+0x5b0>
mov    -0x10(%rbp),%rax
movslq -0x18(%rbp),%rcx
mov    (%rax,%rcx,8),%rsi
lea    0x959(%rip),%rdi
mov    $0x0,%al
call   10b0 <printf@plt>
mov    -0x18(%rbp),%eax
add    $0x1,%eax
mov    %eax,-0x18(%rbp)
jmp    181c <main+0x57c>
lea    0x7d0(%rip),%rdi
mov    $0x0,%al
call   10b0 <printf@plt>
mov    -0x50(%rbp),%rcx
mov    -0x30(%rbp),%rdi
mov    -0x20(%rbp),%rax
mov    (%rax),%rsi
mov    -0x38(%rbp),%rdx
mov    -0x10(%rbp),%r8
call   10e0 <do_log@plt>
mov    %eax,-0x14(%rbp)
cmpl   $0x0,-0x14(%rbp)
jne    1898 <main+0x5f8>
mov    0x2742(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
jmp    18da <main+0x63a>
mov    $0x0,%al
call   11c0 <close_fds@plt>
mov    -0x10(%rbp),%rax
mov    0x10(%rax),%rdi
mov    -0x10(%rbp),%rsi
add    $0x10,%rsi
call   1160 <execvp@plt>
cmp    $0xffffffff,%eax
jne    18d5 <main+0x635>
lea    0x8d4(%rip),%rdi
call   1140 <perror@plt>
mov    0x2700(%rip),%rax
mov    (%rax),%eax
mov    %eax,-0x14(%rbp)
jmp    18da <main+0x63a>
mov    -0x38(%rbp),%rdi
call   1040 <free@plt>
mov    -0x14(%rbp),%edi
call   1180 <exit@plt>

x86 assembly (clang, -O2):
<main>:
push   %rbp
mov    %rsp,%rbp
push   %r15
push   %r14
push   %r13
push   %r12
push   %rbx
sub    $0x28,%rsp
mov    %rsi,%r13
mov    %edi,%r12d
xor    %eax,%eax
call   1120 <get_current_dir_name@plt>
mov    %rax,%r14
mov    0x2d18(%rip),%rax
mov    (%rax),%eax
mov    %rsp,%r15
add    $0xf,%rax
and    $0xfffffffffffffff0,%rax
sub    %rax,%r15
mov    %r15,%rsp
cmp    $0x2,%r12d
jle    1622 <main+0x372>
mov    0x8(%r13),%rdi
call   1100 <getpwnam@plt>
test   %rax,%rax
je     163b <main+0x38b>
lea    0xd3e(%rip),%rdi
lea    0xdc3(%rip),%rsi
call   1140 <fopen@plt>
mov    %rax,0x2de7(%rip)
test   %rax,%rax
jne    1351 <main+0xa1>
lea    0xd15(%rip),%rdi
lea    0xda4(%rip),%rsi
call   1140 <fopen@plt>
mov    %rax,0x2dc8(%rip)
test   %rax,%rax
jne    1351 <main+0xa1>
lea    0xd14(%rip),%rdi
jmp    15cf <main+0x31f>
xor    %eax,%eax
call   10b0 <getuid@plt>
mov    %rax,%rdi
call   1080 <getpwuid@plt>
mov    (%rax),%rbx
xor    %eax,%eax
call   10b0 <getuid@plt>
test   %rax,%rax
jle    138a <main+0xda>
mov    0x8(%r13),%rsi
mov    0x2d8e(%rip),%rdx
mov    %rbx,%rdi
call   1160 <check_user_auth@plt>
test   %eax,%eax
je     1651 <main+0x3a1>
mov    0x2d77(%rip),%rdi
call   1070 <fclose@plt>
xor    %edi,%edi
xor    %esi,%esi
call   10d0 <setgroups@plt>
test   %rax,%rax
jne    15c8 <main+0x318>
mov    %r14,-0x30(%rbp)
mov    0x8(%r13),%rdi
call   1100 <getpwnam@plt>
mov    %rax,%r14
mov    (%rax),%rdi
mov    0x14(%rax),%esi
call   11c0 <initgroups@plt>
test   %rax,%rax
jne    15d6 <main+0x326>
mov    0x14(%r14),%edi
call   1130 <setgid@plt>
test   %rax,%rax
jne    15df <main+0x32f>
mov    %r14,-0x38(%rbp)
mov    0x10(%r14),%edi
call   11a0 <setuid@plt>
test   %rax,%rax
jne    15e8 <main+0x338>
lea    0xcc9(%rip),%rdi
call   1030 <getenv@plt>
test   %rax,%rax
mov    -0x30(%rbp),%r14
je     1416 <main+0x166>
mov    %rax,%rdi
call   1180 <atoi@plt>
test   %rax,%rax
je     142c <main+0x17c>
mov    -0x38(%rbp),%rax
mov    0x8(%rax),%rdi
call   10a0 <chdir@plt>
test   %rax,%rax
jne    1610 <main+0x360>
xor    %eax,%eax
call   1090 <clearenv@plt>
test   %rax,%rax
jne    1619 <main+0x369>
mov    -0x38(%rbp),%r14
mov    0x8(%r14),%rsi
lea    0xc98(%rip),%rdi
mov    $0x1,%edx
call   1060 <setenv@plt>
test   %rax,%rax
jne    166e <main+0x3be>
mov    (%r14),%rsi
lea    0xcb6(%rip),%rdi
mov    $0x1,%edx
call   1060 <setenv@plt>
test   %rax,%rax
jne    1687 <main+0x3d7>
lea    0xc92(%rip),%rdi
mov    %rbx,%rsi
mov    $0x1,%edx
call   1060 <setenv@plt>
test   %rax,%rax
mov    -0x30(%rbp),%r14
jne    16a0 <main+0x3f0>
lea    0xc80(%rip),%rdi
lea    0xc7e(%rip),%rsi
mov    $0x1,%edx
call   1060 <setenv@plt>
test   %rax,%rax
jne    16b9 <main+0x409>
lea    0xc8b(%rip),%rdi
lea    0xc0d(%rip),%rsi
call   1140 <fopen@plt>
mov    %rax,0x2c31(%rip)
test   %rax,%rax
jne    14fb <main+0x24b>
lea    0xc62(%rip),%rdi
lea    0xbee(%rip),%rsi
call   1140 <fopen@plt>
mov    %rax,0x2c12(%rip)
test   %rax,%rax
je     151e <main+0x26e>
mov    -0x38(%rbp),%rcx
mov    (%rcx),%rdi
mov    %rax,%rsi
call   11b0 <setup_environment@plt>
test   %eax,%eax
je     15f8 <main+0x348>
mov    0x2bef(%rip),%rdi
call   1070 <fclose@plt>
mov    %rbx,-0x48(%rbp)
lea    0x10(%r13),%rax
mov    %rax,-0x40(%rbp)
mov    0x10(%r13),%rdi
mov    %r15,%rsi
call   10e0 <command_found@plt>
test   %eax,%eax
je     16d2 <main+0x422>
lea    0xc44(%rip),%rdi
xor    %eax,%eax
call   10c0 <printf@plt>
mov    %r12d,%ebx
mov    $0x2,%r14d
lea    0xc38(%rip),%r12
nopl   0x0(%rax)
mov    0x0(%r13,%r14,8),%rsi
mov    %r12,%rdi
xor    %eax,%eax
call   10c0 <printf@plt>
add    $0x1,%r14
cmp    %r14,%rbx
jne    1560 <main+0x2b0>
lea    0xc1e(%rip),%rdi
call   1050 <puts@plt>
mov    -0x38(%rbp),%rax
mov    (%rax),%rsi
mov    -0x48(%rbp),%rdi
mov    -0x30(%rbp),%r14
mov    %r14,%rdx
mov    %r15,%rcx
mov    %r13,%r8
call   10f0 <do_log@plt>
test   %eax,%eax
je     15f8 <main+0x348>
mov    %eax,%ebx
xor    %eax,%eax
call   11d0 <close_fds@plt>
mov    -0x40(%rbp),%rsi
mov    (%rsi),%rdi
call   1170 <execvp@plt>
cmp    $0xffffffff,%eax
jne    1601 <main+0x351>
lea    0xbd2(%rip),%rdi
jmp    15cf <main+0x31f>
lea    0xad2(%rip),%rdi
call   1150 <perror@plt>
jmp    15f8 <main+0x348>
lea    0xace(%rip),%rdi
jmp    15ef <main+0x33f>
lea    0xad0(%rip),%rdi
jmp    15ef <main+0x33f>
lea    0xace(%rip),%rdi
call   1150 <perror@plt>
mov    -0x30(%rbp),%r14
mov    0x29d1(%rip),%rax
mov    (%rax),%ebx
mov    %r14,%rdi
call   1040 <free@plt>
mov    %ebx,%edi
call   1190 <exit@plt>
lea    0xabd(%rip),%rdi
jmp    15cf <main+0x31f>
lea    0xaba(%rip),%rdi
jmp    15cf <main+0x31f>
mov    0x29af(%rip),%rax
mov    (%rax),%edi
lea    0x9ce(%rip),%rsi
xor    %eax,%eax
call   1110 <fprintf@plt>
jmp    15f8 <main+0x348>
mov    0x2996(%rip),%rax
mov    (%rax),%edi
mov    0x8(%r13),%rdx
lea    0x9db(%rip),%rsi
jmp    1665 <main+0x3b5>
mov    0x2980(%rip),%rax
mov    (%rax),%edi
mov    0x8(%r13),%rdx
lea    0xa10(%rip),%rsi
xor    %eax,%eax
call   1110 <fprintf@plt>
jmp    15f8 <main+0x348>
mov    0x2963(%rip),%rax
mov    (%rax),%edi
lea    0xa6a(%rip),%rsi
lea    0xa5e(%rip),%rdx
jmp    16e9 <main+0x439>
mov    0x294a(%rip),%rax
mov    (%rax),%edi
lea    0xa51(%rip),%rsi
lea    0xa80(%rip),%rdx
jmp    16e9 <main+0x439>
mov    0x2931(%rip),%rax
mov    (%rax),%edi
lea    0xa38(%rip),%rsi
lea    0xa5d(%rip),%rdx
jmp    1665 <main+0x3b5>
mov    0x2918(%rip),%rax
mov    (%rax),%edi
lea    0xa1f(%rip),%rsi
lea    0xa53(%rip),%rdx
jmp    1665 <main+0x3b5>
mov    0x28ff(%rip),%rax
mov    (%rax),%edi
mov    -0x40(%rbp),%rax
mov    (%rax),%rdx
lea    0xa7e(%rip),%rsi
xor    %eax,%eax
call   1110 <fprintf@plt>
jmp    15f4 <main+0x344>

LLVM IR (-O0):
%struct.passwd = type { i8*, i8*, i32, i32 }
@EXIT_SUCCESS = global i32 0
@main.fp = internal global i32* null
@PATH_MAX = global i32 0
@stderr = global i32 0
@.str = [42 x i8] c"Usage: runasuser user program [args ...]\0A\00"
@EXIT_FAILURE = global i32 0
@.str.1 = [24 x i8] c"Error: No such user %s\0A\00"
@.str.2 = [20 x i8] c"/etc/runasuser.conf\00"
@.str.3 = [2 x i8] c"r\00"
@.str.4 = [30 x i8] c"/usr/local/etc/runasuser.conf\00"
@.str.5 = [21 x i8] c"fopen runasuser.conf\00"
@.str.6 = [44 x i8] c"Error: You are not authorized to run as %s\0A\00"
@.str.7 = [10 x i8] c"setgroups\00"
@.str.8 = [11 x i8] c"initgroups\00"
@.str.9 = [7 x i8] c"setgid\00"
@.str.10 = [7 x i8] c"setuid\00"
@.str.11 = [16 x i8] c"RUNASUSER_CHDIR\00"
@.str.12 = [6 x i8] c"chdir\00"
@.str.13 = [9 x i8] c"clearenv\00"
@.str.14 = [5 x i8] c"HOME\00"
@.str.15 = [44 x i8] c"setenv: %s: can't set environment variable\0A\00"
@.str.16 = [5 x i8] c"USER\00"
@.str.17 = [15 x i8] c"RUNASUSER_USER\00"
@.str.18 = [5 x i8] c"PATH\00"
@.str.19 = [29 x i8] c"/usr/local/bin:/bin:/usr/bin\00"
@.str.20 = [24 x i8] c"/etc/runasuser.env.conf\00"
@.str.21 = [34 x i8] c"/usr/local/etc/runasuser.env.conf\00"
@.str.22 = [34 x i8] c"runasuser: %s: command not found\0A\00"
@.str.23 = [11 x i8] c"Execing [ \00"
@.str.24 = [4 x i8] c"%s \00"
@.str.25 = [3 x i8] c"]\0A\00"
@.str.26 = [5 x i8] c"exec\00"
define i32 @main(i32 %0, i8** %1) {
%3 = alloca i32
%4 = alloca i32
%5 = alloca i8**
%6 = alloca i32
%7 = alloca i32
%8 = alloca %struct.passwd*
%9 = alloca i8*
%10 = alloca i8*
%11 = alloca i8*
%12 = alloca i8*
%13 = alloca i64
store i32 0, i32* %3
store i32 %0, i32* %4
store i8** %1, i8*** %5
%14 = load i32, i32* @EXIT_SUCCESS
store i32 %14, i32* %6
%15 = call i8* (...) @get_current_dir_name()
store i8* %15, i8** %11
%16 = load i32, i32* @PATH_MAX
%17 = zext i32 %16 to i64
%18 = call i8* @llvm.stacksave()
store i8* %18, i8** %12
%19 = alloca i8, i64 %17
store i64 %17, i64* %13
%20 = load i32, i32* %4
%21 = icmp slt i32 %20, 3
br i1 %21, label %22, label %26
22: ; preds = %2
%23 = load i32, i32* @stderr
%24 = call i32 (i32, i8*, ...) @fprintf(i32 %23, i8* getelementptr inbounds ([42 x i8], [42 x i8]* @.str, i64 0, i64 0))
%25 = load i32, i32* @EXIT_FAILURE
store i32 %25, i32* %6
br label %253
26: ; preds = %2
%27 = load i8**, i8*** %5
%28 = getelementptr inbounds i8*, i8** %27, i64 1
%29 = load i8*, i8** %28
%30 = call %struct.passwd* @getpwnam(i8* %29)
store %struct.passwd* %30, %struct.passwd** %8
%31 = load %struct.passwd*, %struct.passwd** %8
%32 = icmp ne %struct.passwd* %31, null
br i1 %32, label %40, label %33
33: ; preds = %26
%34 = load i32, i32* @stderr
%35 = load i8**, i8*** %5
%36 = getelementptr inbounds i8*, i8** %35, i64 1
%37 = load i8*, i8** %36
%38 = call i32 (i32, i8*, ...) @fprintf(i32 %34, i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.1, i64 0, i64 0), i8* %37)
%39 = load i32, i32* @EXIT_FAILURE
store i32 %39, i32* %6
br label %253
40: ; preds = %26
%41 = call i32* @fopen(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.2, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i64 0, i64 0))
store i32* %41, i32** @main.fp
%42 = load i32*, i32** @main.fp
%43 = icmp ne i32* %42, null
br i1 %43, label %52, label %44
44: ; preds = %40
%45 = call i32* @fopen(i8* getelementptr inbounds ([30 x i8], [30 x i8]* @.str.4, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i64 0, i64 0))
store i32* %45, i32** @main.fp
%46 = load i32*, i32** @main.fp
%47 = icmp ne i32* %46, null
br i1 %47, label %51, label %48
48: ; preds = %44
%49 = call i32 @perror(i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.5, i64 0, i64 0))
%50 = load i32, i32* @EXIT_FAILURE
store i32 %50, i32* %6
br label %253
51: ; preds = %44
br label %52
52: ; preds = %51, %40
%53 = call i64 (...) @getuid()
%54 = call %struct.passwd* @getpwuid(i64 %53)
store %struct.passwd* %54, %struct.passwd** %8
%55 = load %struct.passwd*, %struct.passwd** %8
%56 = getelementptr inbounds %struct.passwd, %struct.passwd* %55, i32 0, i32 0
%57 = load i8*, i8** %56
store i8* %57, i8** %10
%58 = call i64 (...) @getuid()
%59 = icmp sgt i64 %58, 0
br i1 %59, label %60, label %76
60: ; preds = %52
%61 = load i8*, i8** %10
%62 = load i8**, i8*** %5
%63 = getelementptr inbounds i8*, i8** %62, i64 1
%64 = load i8*, i8** %63
%65 = load i32*, i32** @main.fp
%66 = call i32 @check_user_auth(i8* %61, i8* %64, i32* %65)
%67 = icmp ne i32 %66, 0
br i1 %67, label %75, label %68
68: ; preds = %60
%69 = load i32, i32* @stderr
%70 = load i8**, i8*** %5
%71 = getelementptr inbounds i8*, i8** %70, i64 1
%72 = load i8*, i8** %71
%73 = call i32 (i32, i8*, ...) @fprintf(i32 %69, i8* getelementptr inbounds ([44 x i8], [44 x i8]* @.str.6, i64 0, i64 0), i8* %72)
%74 = load i32, i32* @EXIT_FAILURE
store i32 %74, i32* %6
br label %253
75: ; preds = %60
br label %76
76: ; preds = %75, %52
%77 = load i32*, i32** @main.fp
%78 = call i32 @fclose(i32* %77)
%79 = call i64 @setgroups(i32 0, i32* null)
%80 = icmp ne i64 %79, 0
br i1 %80, label %81, label %84
81: ; preds = %76
%82 = call i32 @perror(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.7, i64 0, i64 0))
%83 = load i32, i32* @EXIT_FAILURE
store i32 %83, i32* %6
br label %253
84: ; preds = %76
%85 = load i8**, i8*** %5
%86 = getelementptr inbounds i8*, i8** %85, i64 1
%87 = load i8*, i8** %86
%88 = call %struct.passwd* @getpwnam(i8* %87)
store %struct.passwd* %88, %struct.passwd** %8
%89 = load %struct.passwd*, %struct.passwd** %8
%90 = getelementptr inbounds %struct.passwd, %struct.passwd* %89, i32 0, i32 0
%91 = load i8*, i8** %90
%92 = load %struct.passwd*, %struct.passwd** %8
%93 = getelementptr inbounds %struct.passwd, %struct.passwd* %92, i32 0, i32 3
%94 = load i32, i32* %93
%95 = call i64 @initgroups(i8* %91, i32 %94)
%96 = icmp ne i64 %95, 0
br i1 %96, label %97, label %100
97: ; preds = %84
%98 = call i32 @perror(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.8, i64 0, i64 0))
%99 = load i32, i32* @EXIT_FAILURE
store i32 %99, i32* %6
br label %253
100: ; preds = %84
%101 = load %struct.passwd*, %struct.passwd** %8
%102 = getelementptr inbounds %struct.passwd, %struct.passwd* %101, i32 0, i32 3
%103 = load i32, i32* %102
%104 = call i64 @setgid(i32 %103)
%105 = icmp ne i64 %104, 0
br i1 %105, label %106, label %109
106: ; preds = %100
%107 = call i32 @perror(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.9, i64 0, i64 0))
%108 = load i32, i32* @EXIT_FAILURE
store i32 %108, i32* %6
br label %253
109: ; preds = %100
%110 = load %struct.passwd*, %struct.passwd** %8
%111 = getelementptr inbounds %struct.passwd, %struct.passwd* %110, i32 0, i32 2
%112 = load i32, i32* %111
%113 = call i64 @setuid(i32 %112)
%114 = icmp ne i64 %113, 0
br i1 %114, label %115, label %118
115: ; preds = %109
%116 = call i32 @perror(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.10, i64 0, i64 0))
%117 = load i32, i32* @EXIT_FAILURE
store i32 %117, i32* %6
br label %253
118: ; preds = %109
%119 = call i8* @getenv(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.11, i64 0, i64 0))
store i8* %119, i8** %9
%120 = load i8*, i8** %9
%121 = icmp ne i8* %120, null
br i1 %121, label %122, label %126
122: ; preds = %118
%123 = load i8*, i8** %9
%124 = call i64 @atoi(i8* %123)
%125 = icmp ne i64 %124, 0
br i1 %125, label %126, label %136
126: ; preds = %122, %118
%127 = load %struct.passwd*, %struct.passwd** %8
%128 = getelementptr inbounds %struct.passwd, %struct.passwd* %127, i32 0, i32 1
%129 = load i8*, i8** %128
%130 = call i64 @chdir(i8* %129)
%131 = icmp ne i64 %130, 0
br i1 %131, label %132, label %135
132: ; preds = %126
%133 = call i32 @perror(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.12, i64 0, i64 0))
%134 = load i32, i32* @EXIT_FAILURE
store i32 %134, i32* %6
br label %253
135: ; preds = %126
br label %136
136: ; preds = %135, %122
%137 = call i64 (...) @clearenv()
%138 = icmp ne i64 %137, 0
br i1 %138, label %139, label %142
139: ; preds = %136
%140 = call i32 @perror(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.13, i64 0, i64 0))
%141 = load i32, i32* @EXIT_FAILURE
store i32 %141, i32* %6
br label %253
142: ; preds = %136
%143 = load %struct.passwd*, %struct.passwd** %8
%144 = getelementptr inbounds %struct.passwd, %struct.passwd* %143, i32 0, i32 1
%145 = load i8*, i8** %144
%146 = call i64 @setenv(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.14, i64 0, i64 0), i8* %145, i32 1)
%147 = icmp ne i64 %146, 0
br i1 %147, label %148, label %152
148: ; preds = %142
%149 = load i32, i32* @stderr
%150 = call i32 (i32, i8*, ...) @fprintf(i32 %149, i8* getelementptr inbounds ([44 x i8], [44 x i8]* @.str.15, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.14, i64 0, i64 0))
%151 = load i32, i32* @EXIT_FAILURE
store i32 %151, i32* %6
br label %253
152: ; preds = %142
%153 = load %struct.passwd*, %struct.passwd** %8
%154 = getelementptr inbounds %struct.passwd, %struct.passwd* %153, i32 0, i32 0
%155 = load i8*, i8** %154
%156 = call i64 @setenv(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.16, i64 0, i64 0), i8* %155, i32 1)
%157 = icmp ne i64 %156, 0
br i1 %157, label %158, label %162
158: ; preds = %152
%159 = load i32, i32* @stderr
%160 = call i32 (i32, i8*, ...) @fprintf(i32 %159, i8* getelementptr inbounds ([44 x i8], [44 x i8]* @.str.15, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.16, i64 0, i64 0))
%161 = load i32, i32* @EXIT_FAILURE
store i32 %161, i32* %6
br label %253
162: ; preds = %152
%163 = load i8*, i8** %10
%164 = call i64 @setenv(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.17, i64 0, i64 0), i8* %163, i32 1)
%165 = icmp ne i64 %164, 0
br i1 %165, label %166, label %170
166: ; preds = %162
%167 = load i32, i32* @stderr
%168 = call i32 (i32, i8*, ...) @fprintf(i32 %167, i8* getelementptr inbounds ([44 x i8], [44 x i8]* @.str.15, i64 0, i64 0), i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.17, i64 0, i64 0))
%169 = load i32, i32* @EXIT_FAILURE
store i32 %169, i32* %6
br label %253
170: ; preds = %162
%171 = call i64 @setenv(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.18, i64 0, i64 0), i8* getelementptr inbounds ([29 x i8], [29 x i8]* @.str.19, i64 0, i64 0), i32 1)
%172 = icmp ne i64 %171, 0
br i1 %172, label %173, label %177
173: ; preds = %170
%174 = load i32, i32* @stderr
%175 = call i32 (i32, i8*, ...) @fprintf(i32 %174, i8* getelementptr inbounds ([44 x i8], [44 x i8]* @.str.15, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.18, i64 0, i64 0))
%176 = load i32, i32* @EXIT_FAILURE
store i32 %176, i32* %6
br label %253
177: ; preds = %170
%178 = call i32* @fopen(i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.20, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i64 0, i64 0))
store i32* %178, i32** @main.fp
%179 = load i32*, i32** @main.fp
%180 = icmp ne i32* %179, null
br i1 %180, label %183, label %181
181: ; preds = %177
%182 = call i32* @fopen(i8* getelementptr inbounds ([34 x i8], [34 x i8]* @.str.21, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i64 0, i64 0))
store i32* %182, i32** @main.fp
br label %183
183: ; preds = %181, %177
%184 = load i32*, i32** @main.fp
%185 = icmp ne i32* %184, null
br i1 %185, label %186, label %198
186: ; preds = %183
%187 = load %struct.passwd*, %struct.passwd** %8
%188 = getelementptr inbounds %struct.passwd, %struct.passwd* %187, i32 0, i32 0
%189 = load i8*, i8** %188
%190 = load i32*, i32** @main.fp
%191 = call i32 @setup_environment(i8* %189, i32* %190)
%192 = icmp ne i32 %191, 0
br i1 %192, label %195, label %193
193: ; preds = %186
%194 = load i32, i32* @EXIT_FAILURE
store i32 %194, i32* %6
br label %253
195: ; preds = %186
%196 = load i32*, i32** @main.fp
%197 = call i32 @fclose(i32* %196)
br label %198
198: ; preds = %195, %183
%199 = load i8**, i8*** %5
%200 = getelementptr inbounds i8*, i8** %199, i64 2
%201 = load i8*, i8** %200
%202 = call i32 @command_found(i8* %201, i8* %19)
%203 = icmp ne i32 %202, 0
br i1 %203, label %211, label %204
204: ; preds = %198
%205 = load i32, i32* @stderr
%206 = load i8**, i8*** %5
%207 = getelementptr inbounds i8*, i8** %206, i64 2
%208 = load i8*, i8** %207
%209 = call i32 (i32, i8*, ...) @fprintf(i32 %205, i8* getelementptr inbounds ([34 x i8], [34 x i8]* @.str.22, i64 0, i64 0), i8* %208)
%210 = load i32, i32* @EXIT_FAILURE
store i32 %210, i32* %6
br label %253
211: ; preds = %198
%212 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.23, i64 0, i64 0))
store i32 2, i32* %7
br label %213
213: ; preds = %224, %211
%214 = load i32, i32* %7
%215 = load i32, i32* %4
%216 = icmp slt i32 %214, %215
br i1 %216, label %217, label %227
217: ; preds = %213
%218 = load i8**, i8*** %5
%219 = load i32, i32* %7
%220 = sext i32 %219 to i64
%221 = getelementptr inbounds i8*, i8** %218, i64 %220
%222 = load i8*, i8** %221
%223 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str.24, i64 0, i64 0), i8* %222)
br label %224
224: ; preds = %217
%225 = load i32, i32* %7
%226 = add nsw i32 %225, 1
store i32 %226, i32* %7
br label %213
227: ; preds = %213
%228 = call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([3 x i8], [3 x i8]* @.str.25, i64 0, i64 0))
%229 = load i8*, i8** %10
%230 = load %struct.passwd*, %struct.passwd** %8
%231 = getelementptr inbounds %struct.passwd, %struct.passwd* %230, i32 0, i32 0
%232 = load i8*, i8** %231
%233 = load i8*, i8** %11
%234 = load i8**, i8*** %5
%235 = call i32 @do_log(i8* %229, i8* %232, i8* %233, i8* %19, i8** %234)
store i32 %235, i32* %6
%236 = load i32, i32* %6
%237 = icmp ne i32 %236, 0
br i1 %237, label %240, label %238
238: ; preds = %227
%239 = load i32, i32* @EXIT_FAILURE
store i32 %239, i32* %6
br label %253
240: ; preds = %227
%241 = call i32 (...) @close_fds()
%242 = load i8**, i8*** %5
%243 = getelementptr inbounds i8*, i8** %242, i64 2
%244 = load i8*, i8** %243
%245 = load i8**, i8*** %5
%246 = getelementptr inbounds i8*, i8** %245, i64 2
%247 = call i32 @execvp(i8* %244, i8** %246)
%248 = icmp eq i32 %247, -1
br i1 %248, label %249, label %252
249: ; preds = %240
%250 = call i32 @perror(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.26, i64 0, i64 0))
%251 = load i32, i32* @EXIT_FAILURE
store i32 %251, i32* %6
br label %252
252: ; preds = %249, %240
br label %253
253: ; preds = %252, %238, %204, %193, %173, %166, %158, %148, %139, %132, %115, %106, %97, %81, %68, %48, %33, %22
%254 = load i8*, i8** %11
%255 = call i32 @free(i8* %254)
%256 = load i32, i32* %6
%257 = call i32 @exit(i32 %256)
unreachable
}

LLVM IR (-O2):
%struct.passwd = type { i8*, i8*, i32, i32 }
@EXIT_SUCCESS = global i32 0
@main.fp = internal unnamed_addr global i32* null
@PATH_MAX = global i32 0
@stderr = global i32 0
@.str = [42 x i8] c"Usage: runasuser user program [args ...]\0A\00"
@EXIT_FAILURE = global i32 0
@.str.1 = [24 x i8] c"Error: No such user %s\0A\00"
@.str.2 = [20 x i8] c"/etc/runasuser.conf\00"
@.str.3 = [2 x i8] c"r\00"
@.str.4 = [30 x i8] c"/usr/local/etc/runasuser.conf\00"
@.str.5 = [21 x i8] c"fopen runasuser.conf\00"
@.str.6 = [44 x i8] c"Error: You are not authorized to run as %s\0A\00"
@.str.7 = [10 x i8] c"setgroups\00"
@.str.8 = [11 x i8] c"initgroups\00"
@.str.9 = [7 x i8] c"setgid\00"
@.str.10 = [7 x i8] c"setuid\00"
@.str.11 = [16 x i8] c"RUNASUSER_CHDIR\00"
@.str.12 = [6 x i8] c"chdir\00"
@.str.13 = [9 x i8] c"clearenv\00"
@.str.14 = [5 x i8] c"HOME\00"
@.str.15 = [44 x i8] c"setenv: %s: can't set environment variable\0A\00"
@.str.16 = [5 x i8] c"USER\00"
@.str.17 = [15 x i8] c"RUNASUSER_USER\00"
@.str.18 = [5 x i8] c"PATH\00"
@.str.19 = [29 x i8] c"/usr/local/bin:/bin:/usr/bin\00"
@.str.20 = [24 x i8] c"/etc/runasuser.env.conf\00"
@.str.21 = [34 x i8] c"/usr/local/etc/runasuser.env.conf\00"
@.str.22 = [34 x i8] c"runasuser: %s: command not found\0A\00"
@.str.23 = [11 x i8] c"Execing [ \00"
@.str.24 = [4 x i8] c"%s \00"
@.str.26 = [5 x i8] c"exec\00"
@str = [2 x i8] c"]\00"
define i32 @main(i32 %0, i8** %1) {
%3 = tail call i8* (...) @get_current_dir_name()
%4 = load i32, i32* @PATH_MAX
%5 = zext i32 %4 to i64
%6 = alloca i8, i64 %5
%7 = icmp slt i32 %0, 3
br i1 %7, label %8, label %11
8: ; preds = %2
%9 = load i32, i32* @stderr
%10 = tail call i32 (i32, i8*, ...) @fprintf(i32 %9, i8* getelementptr inbounds ([42 x i8], [42 x i8]* @.str, i64 0, i64 0))
br label %165
11: ; preds = %2
%12 = getelementptr inbounds i8*, i8** %1, i64 1
%13 = load i8*, i8** %12
%14 = tail call %struct.passwd* @getpwnam(i8* %13)
%15 = icmp eq %struct.passwd* %14, null
br i1 %15, label %16, label %20
16: ; preds = %11
%17 = load i32, i32* @stderr
%18 = load i8*, i8** %12
%19 = tail call i32 (i32, i8*, ...) @fprintf(i32 %17, i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.1, i64 0, i64 0), i8* %18)
br label %165
20: ; preds = %11
%21 = tail call i32* @fopen(i8* getelementptr inbounds ([20 x i8], [20 x i8]* @.str.2, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i64 0, i64 0))
store i32* %21, i32** @main.fp
%22 = icmp eq i32* %21, null
br i1 %22, label %23, label %28
23: ; preds = %20
%24 = tail call i32* @fopen(i8* getelementptr inbounds ([30 x i8], [30 x i8]* @.str.4, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i64 0, i64 0))
store i32* %24, i32** @main.fp
%25 = icmp eq i32* %24, null
br i1 %25, label %26, label %28
26: ; preds = %23
%27 = tail call i32 @perror(i8* getelementptr inbounds ([21 x i8], [21 x i8]* @.str.5, i64 0, i64 0))
br label %165
28: ; preds = %23, %20
%29 = tail call i64 (...) @getuid()
%30 = tail call %struct.passwd* @getpwuid(i64 %29)
%31 = getelementptr inbounds %struct.passwd, %struct.passwd* %30, i64 0, i32 0
%32 = load i8*, i8** %31
%33 = tail call i64 (...) @getuid()
%34 = icmp sgt i64 %33, 0
br i1 %34, label %35, label %44
35: ; preds = %28
%36 = load i8*, i8** %12
%37 = load i32*, i32** @main.fp
%38 = tail call i32 @check_user_auth(i8* %32, i8* %36, i32* %37)
%39 = icmp eq i32 %38, 0
br i1 %39, label %40, label %44
40: ; preds = %35
%41 = load i32, i32* @stderr
%42 = load i8*, i8** %12
%43 = tail call i32 (i32, i8*, ...) @fprintf(i32 %41, i8* getelementptr inbounds ([44 x i8], [44 x i8]* @.str.6, i64 0, i64 0), i8* %42)
br label %165
44: ; preds = %35, %28
%45 = load i32*, i32** @main.fp
%46 = tail call i32 @fclose(i32* %45)
%47 = tail call i64 @setgroups(i32 0, i32* null)
%48 = icmp eq i64 %47, 0
br i1 %48, label %51, label %49
49: ; preds = %44
%50 = tail call i32 @perror(i8* getelementptr inbounds ([10 x i8], [10 x i8]* @.str.7, i64 0, i64 0))
br label %165
51: ; preds = %44
%52 = load i8*, i8** %12
%53 = tail call %struct.passwd* @getpwnam(i8* %52)
%54 = getelementptr inbounds %struct.passwd, %struct.passwd* %53, i64 0, i32 0
%55 = load i8*, i8** %54
%56 = getelementptr inbounds %struct.passwd, %struct.passwd* %53, i64 0, i32 3
%57 = load i32, i32* %56
%58 = tail call i64 @initgroups(i8* %55, i32 %57)
%59 = icmp eq i64 %58, 0
br i1 %59, label %62, label %60
60: ; preds = %51
%61 = tail call i32 @perror(i8* getelementptr inbounds ([11 x i8], [11 x i8]* @.str.8, i64 0, i64 0))
br label %165
62: ; preds = %51
%63 = load i32, i32* %56
%64 = tail call i64 @setgid(i32 %63)
%65 = icmp eq i64 %64, 0
br i1 %65, label %68, label %66
66: ; preds = %62
%67 = tail call i32 @perror(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.9, i64 0, i64 0))
br label %165
68: ; preds = %62
%69 = getelementptr inbounds %struct.passwd, %struct.passwd* %53, i64 0, i32 2
%70 = load i32, i32* %69
%71 = tail call i64 @setuid(i32 %70)
%72 = icmp eq i64 %71, 0
br i1 %72, label %75, label %73
73: ; preds = %68
%74 = tail call i32 @perror(i8* getelementptr inbounds ([7 x i8], [7 x i8]* @.str.10, i64 0, i64 0))
br label %165
75: ; preds = %68
%76 = tail call i8* @getenv(i8* getelementptr inbounds ([16 x i8], [16 x i8]* @.str.11, i64 0, i64 0))
%77 = icmp eq i8* %76, null
br i1 %77, label %81, label %78
78: ; preds = %75
%79 = tail call i64 @atoi(i8* %76)
%80 = icmp eq i64 %79, 0
br i1 %80, label %88, label %81
81: ; preds = %78, %75
%82 = getelementptr inbounds %struct.passwd, %struct.passwd* %53, i64 0, i32 1
%83 = load i8*, i8** %82
%84 = tail call i64 @chdir(i8* %83)
%85 = icmp eq i64 %84, 0
br i1 %85, label %88, label %86
86: ; preds = %81
%87 = tail call i32 @perror(i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.12, i64 0, i64 0))
br label %165
88: ; preds = %81, %78
%89 = tail call i64 (...) @clearenv()
%90 = icmp eq i64 %89, 0
br i1 %90, label %93, label %91
91: ; preds = %88
%92 = tail call i32 @perror(i8* getelementptr inbounds ([9 x i8], [9 x i8]* @.str.13, i64 0, i64 0))
br label %165
93: ; preds = %88
%94 = getelementptr inbounds %struct.passwd, %struct.passwd* %53, i64 0, i32 1
%95 = load i8*, i8** %94
%96 = tail call i64 @setenv(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.14, i64 0, i64 0), i8* %95, i32 1)
%97 = icmp eq i64 %96, 0
br i1 %97, label %101, label %98
98: ; preds = %93
%99 = load i32, i32* @stderr
%100 = tail call i32 (i32, i8*, ...) @fprintf(i32 %99, i8* getelementptr inbounds ([44 x i8], [44 x i8]* @.str.15, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.14, i64 0, i64 0))
br label %165
101: ; preds = %93
%102 = load i8*, i8** %54
%103 = tail call i64 @setenv(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.16, i64 0, i64 0), i8* %102, i32 1)
%104 = icmp eq i64 %103, 0
br i1 %104, label %108, label %105
105: ; preds = %101
%106 = load i32, i32* @stderr
%107 = tail call i32 (i32, i8*, ...) @fprintf(i32 %106, i8* getelementptr inbounds ([44 x i8], [44 x i8]* @.str.15, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.16, i64 0, i64 0))
br label %165
108: ; preds = %101
%109 = tail call i64 @setenv(i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.17, i64 0, i64 0), i8* %32, i32 1)
%110 = icmp eq i64 %109, 0
br i1 %110, label %114, label %111
111: ; preds = %108
%112 = load i32, i32* @stderr
%113 = tail call i32 (i32, i8*, ...) @fprintf(i32 %112, i8* getelementptr inbounds ([44 x i8], [44 x i8]* @.str.15, i64 0, i64 0), i8* getelementptr inbounds ([15 x i8], [15 x i8]* @.str.17, i64 0, i64 0))
br label %165
114: ; preds = %108
%115 = tail call i64 @setenv(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.18, i64 0, i64 0), i8* getelementptr inbounds ([29 x i8], [29 x i8]* @.str.19, i64 0, i64 0), i32 1)
%116 = icmp eq i64 %115, 0
br i1 %116, label %120, label %117
117: ; preds = %114
%118 = load i32, i32* @stderr
%119 = tail call i32 (i32, i8*, ...) @fprintf(i32 %118, i8* getelementptr inbounds ([44 x i8], [44 x i8]* @.str.15, i64 0, i64 0), i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.18, i64 0, i64 0))
br label %165
120: ; preds = %114
%121 = tail call i32* @fopen(i8* getelementptr inbounds ([24 x i8], [24 x i8]* @.str.20, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i64 0, i64 0))
store i32* %121, i32** @main.fp
%122 = icmp eq i32* %121, null
br i1 %122, label %123, label %126
123: ; preds = %120
%124 = tail call i32* @fopen(i8* getelementptr inbounds ([34 x i8], [34 x i8]* @.str.21, i64 0, i64 0), i8* getelementptr inbounds ([2 x i8], [2 x i8]* @.str.3, i64 0, i64 0))
store i32* %124, i32** @main.fp
%125 = icmp eq i32* %124, null
br i1 %125, label %134, label %126
126: ; preds = %120, %123
%127 = phi i32* [ %124, %123 ], [ %121, %120 ]
%128 = load i8*, i8** %54
%129 = tail call i32 @setup_environment(i8* %128, i32* %127)
%130 = icmp eq i32 %129, 0
br i1 %130, label %165, label %131
131: ; preds = %126
%132 = load i32*, i32** @main.fp
%133 = tail call i32 @fclose(i32* %132)
br label %134
134: ; preds = %131, %123
%135 = getelementptr inbounds i8*, i8** %1, i64 2
%136 = load i8*, i8** %135
%137 = call i32 @command_found(i8* %136, i8* %6)
%138 = icmp eq i32 %137, 0
br i1 %138, label %139, label %143
139: ; preds = %134
%140 = load i32, i32* @stderr
%141 = load i8*, i8** %135
%142 = call i32 (i32, i8*, ...) @fprintf(i32 %140, i8* getelementptr inbounds ([34 x i8], [34 x i8]* @.str.22, i64 0, i64 0), i8* %141)
br label %165
143: ; preds = %134
%144 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([11 x i8], [11 x i8]* @.str.23, i64 0, i64 0))
%145 = zext i32 %0 to i64
br label %146
146: ; preds = %143, %146
%147 = phi i64 [ 2, %143 ], [ %151, %146 ]
%148 = getelementptr inbounds i8*, i8** %1, i64 %147
%149 = load i8*, i8** %148
%150 = call i32 (i8*, ...) @printf(i8* dereferenceable(1) getelementptr inbounds ([4 x i8], [4 x i8]* @.str.24, i64 0, i64 0), i8* %149)
%151 = add nuw nsw i64 %147, 1
%152 = icmp eq i64 %151, %145
br i1 %152, label %153, label %146
153: ; preds = %146
%154 = call i32 @puts(i8* dereferenceable(1) getelementptr inbounds ([2 x i8], [2 x i8]* @str, i64 0, i64 0))
%155 = load i8*, i8** %54
%156 = call i32 @do_log(i8* %32, i8* %155, i8* %3, i8* %6, i8** %1)
%157 = icmp eq i32 %156, 0
br i1 %157, label %165, label %158
158: ; preds = %153
%159 = call i32 (...) @close_fds()
%160 = load i8*, i8** %135
%161 = call i32 @execvp(i8* %160, i8** %135)
%162 = icmp eq i32 %161, -1
br i1 %162, label %163, label %167
163: ; preds = %158
%164 = call i32 @perror(i8* getelementptr inbounds ([5 x i8], [5 x i8]* @.str.26, i64 0, i64 0))
br label %165
165: ; preds = %153, %126, %8, %16, %26, %40, %49, %60, %66, %73, %86, %91, %98, %105, %111, %117, %139, %163
%166 = load i32, i32* @EXIT_FAILURE
br label %167
167: ; preds = %165, %158
%168 = phi i32 [ %156, %158 ], [ %166, %165 ]
%169 = call i32 @free(i8* %3)
%170 = call i32 @exit(i32 %168)
unreachable
}