Exemplo n.º 1
0
static
void
run(void)
{
	pid_t pids[NPROCS*4], wp;
	int i, status;

	for (i=0; i<NPROCS; i++) {
		pids[i*4] = dofork(mkdir_proc);
		pids[i*4+1] = dofork(mkdir_proc);
		pids[i*4+2] = dofork(rename_proc);
		pids[i*4+3] = dofork(rmdir_proc);
	}
	
	for (i=0; i<NPROCS*4; i++) {
		if (pids[i]>=0) {
			wp = waitpid(pids[i], &status, 0);
			if (wp<0) {
				say("waitpid %d: %s\n", (int) pids[i], 
				    strerror(errno));
			}
			else if (WIFSIGNALED(status)) {
				say("pid %d: signal %d\n", (int) pids[i],
				    WTERMSIG(status));
			}
			else if (WIFEXITED(status) && WEXITSTATUS(status)!=0) {
				say("pid %d: exit %d\n", (int) pids[i], 
				    WEXITSTATUS(status));
			}
		}
	}
}
Exemplo n.º 2
0
int main()
{

    int pid0, pid1, pid2;

	pid0 = dofork();
	
	putchar('0');
	check();
	putchar('a');

	pid1 = dofork();
	putchar('1');
	check();
	putchar('b');

	pid2 = dofork();
	putchar('2');
	check();
	//putchar('c');

	dowait(pid2);
	dowait(pid1);
	dowait(pid0);

	putchar('\n');

	return 0;
}
Exemplo n.º 3
0
/*
 * Actually run the test.
 */
static
void
test()
{
	int pid0, pid1, ret;

	pid0 = dofork();
	warnx("Child 0 created.");
	pid1 = dofork();
	warnx("Child 1 created.");

	ret = kill(pid1, 17);
	if (ret == -1) {
		warn("kill failed.");
	}
	else {
		warnx("Child 1 stopped.");
	}
	ret = kill(pid0, 17);
	if (ret == -1) {
		warn("kill failed.");
	}
	else {
		warnx("Child 0 stopped.");
	}
	
	ret = kill(pid1, 19);
	if (ret == -1) {
		warn("kill failed.");
	}
	else {
		warnx("Child 0 continued.");
	}
	ret = kill(pid1, 17);
	if (ret == -1) {
		warnx("Correct error when child 1 stopped twice");
	}
	else {
		warnx("Child 1 stopped twice?");
	}
	
	ret = kill(pid1, 9);
	if (ret == -1) {
		warn("kill failed.");
	}
	else {
		warnx("Child 1 killed.");
	}
	ret = kill(pid0, 9);
	if (ret == -1) {
		warn("kill failed.");
	}
	else {
		warnx("Child 0 killed.");
	}
}
Exemplo n.º 4
0
/**
 * @brief dispatch 
 * 并发数分配到若干进程
 *
 * 将期待的并发量p->num
 * 也就是参数 c 的值分组
 * 每组调用一次dofork函数得到一个进程
 * 默认一个进程里面会产生BM_GROUP_THREADS个线程
 * p->num在对BM_GROUP_THREADS求余
 * 剩下的不足BM_GROUP_THREADS都会分配到一个进程中
 *
 * @param p
 * cbenchmark全局信息
 */
void dispatch(struct bench * bp)
{
		long int i;

		for (i = 0; i < bp->num/BM_GROUP_THREADS; i++) {
				dofork(bp,BM_GROUP_THREADS,i);
		}
		if(bp->num%BM_GROUP_THREADS > 0)
				dofork(bp,bp->num%BM_GROUP_THREADS,i);
}
Exemplo n.º 5
0
Arquivo: psort.c Projeto: BWK/os161
static
void
doforkall(const char *phasename, void (*func)(void))
{
	int i, bad = 0;
	pid_t pids[numprocs];

	for (i=0; i<numprocs; i++) {
		pids[i] = dofork();
		if (pids[i] < 0) {
			bad = 1;
		}
		else if (pids[i] == 0) {
			/* child */
			me = i;
			func();
			exit(0);
		}
	}

	for (i=0; i<numprocs; i++) {
		if (pids[i] > 0 && dowait(i, pids[i])) {
			bad = 1;
		}
	}

	if (bad) {
		complainx("%s failed.", phasename);
		exit(1);
	}
}
Exemplo n.º 6
0
static
void
expect_segfault(segfault_fn func)
{
	int status;
	int result;
	pid_t pid = dofork();

	if (pid == 0) {
		func();	// This exits
	} else {
		result = waitpid(pid, &status, 0);
		tprintf("status is %d \n", status);
		if (result == -1) {
			err(1, "waitpid");
		}
		else if (WIFSIGNALED(status)) {
			if (WTERMSIG(status) != 11) {
				errx(1, "child: Signal %d", WTERMSIG(status));
			}
		}
		else  {
			errx(1, "child exited, expected segfault");
		}
	}
}
Exemplo n.º 7
0
/*
 * Fork and then allocate in both the parent and the child, in case
 * fork messes up the heap. Note: this is not intended to test the
 * parent and child running concurrently -- that should probably be
 * its own test program.
 */
static
void
test12(void)
{
	pid_t pid;
	void *p;

	tprintf("Forking...\n");
	pid = dofork();
	if (pid == 0) {
		/* child */
		say("Child allocating a page...\n");
		p = dosbrk(PAGE_SIZE);
		markpage(p, 0);
		if (checkpage(p, 0, false)) {
			errx(1, "FAILED: data corrupt in child");
		}
		say("Child done.\n");
		exit(0);
	}
	/* parent */
	say("Parent allocating a page...\n");
	p = dosbrk(PAGE_SIZE);
	markpage(p, 0);
	if (checkpage(p, 0, false)) {
		errx(1, "FAILED: data corrupt in parent");
	}
	say("Parent done.\n");
	dowait(pid);
	tprintf("Passed sbrk test 12.\n");
	success(TEST161_SUCCESS, SECRET, "/testbin/sbrktest");
}
Exemplo n.º 8
0
/*
 * Allocate and then fork, in case fork doesn't preserve the heap.
 */
static
void
test13(void)
{
	pid_t pid;
	void *p;

	printf("Allocating a page...\n");
	p = dosbrk(PAGE_SIZE);
	markpage(p, 0);
	if (checkpage(p, 0, false)) {
		errx(1, "FAILED: data corrupt before forking");
	}

	printf("Forking...\n");
	pid = dofork();
	if (pid == 0) {
		/* child */
		if (checkpage(p, 0, false)) {
			errx(1, "FAILED: data corrupt in child");
		}
		exit(0);
	}
	if (checkpage(p, 0, false)) {
		errx(1, "FAILED: data corrupt in parent");
	}
	dowait(pid);
	printf("Passed sbrk test 13.\n");
}
Exemplo n.º 9
0
/*
 * Actually run the test for signals that should cause termination.
 */
static
void
testsig_die(int signum, const char *signame)
{
	int pid0, ret, status;

	pid0 = dofork();
	warnx("Child %d created.",pid0);

	ret = kill(pid0, signum);
	if (ret == -1) {
		warn("kill failed.");
	}
	else {
		warnx("Child %d sent %s.",pid0, signame);
	}

	ret = waitpid(pid0, &status, 0);
	if (ret != pid0) {
		warn("waitpid failed (signal %s, status %d)",signame,WEXITSTATUS(status));
	} else {
		warnx("waitpid succeeded (signal %s, status %d, rawstatus %d).",signame,WEXITSTATUS(status),status);
		if (WIFSIGNALED(status)) {
			warnx("\t status %d indicates exit due to signal.");
		} else {
			warnx("\t status %d does NOT indicate exit due to signal.");
		}
	}
		
}
Exemplo n.º 10
0
int main()
{

        pid_p = getpid();
	//printf("value of pid_p after getpid is %d \n", pid_p);        
	putchar('w');
        pid_c = dofork();
	//printf("value of pid_c after getpid is %d \n", pid_c);    
        if (getpid() == pid_p) {
                check();
                dowait(pid_c);
        } else {
                putchar('e');
                _exit(0);
        }

        putchar('k');

        if (getpid() == pid_p)
                putchar('p');
        else 
                printf("wrong %d\n", getpid());

        putchar('\n');

	return 0;
}
Exemplo n.º 11
0
void dofile()
{
    (void)printf("(This file must be converted; you knew that already.)\n");
    (void)printf("\n");
    pos_ptr = 1;
    state = 0;
    rep_char = -1;
    rep_count = 0;
    outchar(':');
    doheader();
    dofork(data_fork, data_size);
    dofork(rsrc_fork, rsrc_size);
    finish();
    (void)putchar(':');
    (void)putchar('\n');
}
Exemplo n.º 12
0
/*
 * Allocate, then fork, then free the allocated page in the child.
 */
static
void
test14(void)
{
	pid_t pid;
	void *p;

	tprintf("Allocating a page...\n");
	p = dosbrk(PAGE_SIZE);
	markpage(p, 0);
	if (checkpage(p, 0, false)) {
		errx(1, "FAILED: data corrupt before forking");
	}

	tprintf("Forking...\n");
	pid = dofork();
	if (pid == 0) {
		/* child */
		if (checkpage(p, 0, false)) {
			errx(1, "FAILED: data corrupt in child");
		}
		tprintf("Child freeing a page...\n");
		dosbrk(-PAGE_SIZE);
		exit(0);
	}
	dowait(pid);
	if (checkpage(p, 0, false)) {
		errx(1, "FAILED: data corrupt in parent after child ran");
	}
	tprintf("Passed sbrk test 14.\n");
	success(TEST161_SUCCESS, SECRET, "/testbin/sbrktest");
}
Exemplo n.º 13
0
int
main()
{
	int pid;
        int result, status;

	warnx("Starting.");

	/* Wait for child - parent should have to wait */ 
	warnx("Creating long-running child.  Parent should have to wait.");
	pid = dofork(10, 10000);
	result = waitpid(pid, &status, 0);
	if (result != pid) {
		warn("unexpected result %d from waitpid, status %d.",result,status);
	} else {
		warnx("waitpid returned status %d (raw %d).", WEXITSTATUS(status), status);
	}

	/* Wait for child - child should exit before parent does wait */
	warnx("Creating short-running child.  Parent should not have to wait.");
	pid = dofork(20, 0);
	result = waitpid(pid, &status, 0);
	if (result != pid) {
		warn("unexpected result %d from waitpid, status %d.",result,status);
	} else {
		warnx("waitpid returned status %d (raw %d).", WEXITSTATUS(status), status);
	}


	/* Wait for child, WNOHANG */
	warnx("Creating long-running child.  Parent should not have to wait (WNOHANG).");
	pid = dofork(30, 10000);
	status = 0xabababab; /* pattern should not be changed unless status is set */
	result = waitpid(pid, &status, WNOHANG);
	if (result != 0 || status != (int)0xabababab) {
		warn("unexpected result from waitpid (result %d, status 0x%x).",result,status);
	} else {
		warnx("waitpid returned status %d (raw %d).", WEXITSTATUS(status), status);
	}

	warnx("Complete.");
	return 0;
}
Exemplo n.º 14
0
int
background(void)
{
  int pid = dofork();

  if (pid == 0) {
    dlog("backgrounded");
    foreground = 0;
  }
  return pid;
}
Exemplo n.º 15
0
Arquivo: autil.c Projeto: 0mp/freebsd
int
background(void)
{
  int pid = dofork();

  if (pid == 0) {
    dlog("backgrounded");
    foreground = 0;
  } else
    dlog("forked process %d", pid);
  return pid;
}
Exemplo n.º 16
0
int
background(void)
{
  int pid = dofork();

  if (pid == 0) {
#ifdef DEBUG
    dlog("backgrounded");
#endif /* DEBUG */
    foreground = 0;
  }
  return pid;
}
Exemplo n.º 17
0
/*
 * Actually run the test.
 */
static
void
test(int nowait)
{
	int pid0, pid1, pid2, pid3;

	/*
	 * Caution: This generates processes geometrically.
	 *
	 * It is unrolled to encourage gcc to registerize the pids,
	 * to prevent wait/exit problems if fork corrupts memory.
	 */

	pid0 = dofork();
	putchar('0');
	check();
	pid1 = dofork();
	putchar('1');
	check();
	pid2 = dofork();
	putchar('2');
	check();
	pid3 = dofork();
	putchar('3');
	check();

	/*
	 * These must be called in reverse order to avoid waiting
	 * improperly.
	 */
	dowait(nowait, pid3);
	dowait(nowait, pid2);
	dowait(nowait, pid1);
	dowait(nowait, pid0);

	putchar('\n');
}
Exemplo n.º 18
0
arg_t _fork(void)
{
	// allocate new process
	struct p_tab *new_process;
	arg_t r;
	irqflags_t irq;

	if (flags) {
		/* Brief period of grace... */
//		udata.u_error = EINVAL;
//		return -1;
		kputs("warning: rebuild libc\n");
	}

	new_process = ptab_alloc();
	if (!new_process)
		return -1;

	irq = di();
	// we're going to run our child process next, so mark this process as being ready to run
	udata.u_ptab->p_status = P_READY;
	// kick off the new process (the bifurcation happens inside here, we returns in both 
	// the child and parent contexts)
	r = dofork(new_process);
#ifdef DEBUG
	kprintf("Dofork %x (n %x)returns %d\n", udata.u_ptab,
		new_process, r);
	kprintf("udata.u_page %d p_page %d\n", udata.u_page,
		udata.u_ptab->p_page);
	kprintf("parent %x\n", udata.u_ptab->p_pptr);
#endif
	// if we fail this returns -1
	if (r == -1) {
		udata.u_ptab->p_status = P_RUNNING;
		pagemap_free(new_process);
		new_process->p_status = P_EMPTY;
		udata.u_error = ENOMEM;
		nproc--;
		nready--;
	}
	irqrestore(irq);

	return r;
}
Exemplo n.º 19
0
static
void
dotest(void)
{
	unsigned i, me;
	pid_t pids[BRANCHES];
	int t;

	me = 0;
	for (i=0; i<BRANCHES; i++) {
		pids[i] = dofork();
		if (pids[i] == 0) {
			me += 1U<<i;
		}
		grind();
		t = trace();
		if (t == right[i]) {
			tsay("Stage %u #%u done: %d\n", i, me, trace());
		}
		else {
			tsay("Stage %u #%u FAILED: got %d, expected %d\n",
				 i, me, t, right[i]);
			success(TEST161_FAIL, SECRET, "/testbin/bigfork");
			failures++;
		}
		TEST161_TPROGRESS(0);
	}

	for (i=BRANCHES; i-- > 0; ) {
		dowait(pids[i]);
	}

	if (failures > 0) {
		tprintf("%u failures.\n", failures);
		success(TEST161_FAIL, SECRET, "/testbin/bigfork");
	}
	else {
		tprintf("Done.\n");
		success(TEST161_SUCCESS, SECRET, "/testbin/bigfork");
	}
}
Exemplo n.º 20
0
int main()
{

        pid_p = getpid();
        putchar('a');
        pid_c = dofork();

        if (getpid() == pid_p) {
                check();
                putchar('t');
                _exit(0);
        } else {
                putchar('t');
                _exit(0);
        }

        putchar('e');
        putchar('\n');

        return 0;
}
Exemplo n.º 21
0
/*
 * Actually run the test for signals that should be ignored.
 */
static
void
testsig_ignore(int signum, const char *signame)
{
	int pid0, ret, status=123456;
	int i, ok=0;

	pid0 = dofork();
	warnx("Child %d created.",pid0);

	ret = kill(pid0, signum);
	if (ret == -1) {
		warn("kill failed.");
	}
	else {
		warnx("Child %d sent %s.",pid0,signame);
	}

	/* check repeatedly to make sure signaled child is still there */
	for (i=0; i < 100; i++) {
		ret = waitpid(pid0, &status, WNOHANG);
		if (ret != 0) {
			warn("waitpid with WNOHANG failed (%s)",signame);
		} else {
			ok++;
		}
	}
	if (ok == 100) {
		warnx("Success: signal %s appears to be ignored.",signame);
	}

	/* try killing child just to clean up */
	warnx("Sending SIGKILL to Child %d to clean up...",pid0);
	ret = kill(pid0, SIGKILL);
	if (ret == -1) {
		warn("kill failed.");
	}
	ret = waitpid(pid0, &status, 0);
	warnx("\tretrieved %d status from pid %d\n",status,pid0);
}
Exemplo n.º 22
0
void main() {
  int x = 1; // should not count as a guarded-by; not shared
  dofork(&x);
  x = 1; // race
}
Exemplo n.º 23
0
int
main(int argc, char *argv[])
{
	struct group *gr;
	struct stat st;
	int ask, ch, cnt, fflag, hflag, pflag, sflag, quietlog, rootlogin, rval;
	uid_t uid, saved_uid;
	gid_t saved_gid, saved_gids[NGROUPS_MAX];
	int nsaved_gids;
#ifdef notdef
	char *domain;
#endif
	char *p, *ttyn;
	const char *pwprompt;
	char tbuf[MAXPATHLEN + 2], tname[sizeof(_PATH_TTY) + 10];
	char localhost[MAXHOSTNAMELEN + 1];
	int need_chpass, require_chpass;
	int login_retries = DEFAULT_RETRIES, 
	    login_backoff = DEFAULT_BACKOFF;
	time_t pw_warntime = _PASSWORD_WARNDAYS * SECSPERDAY;
	char *loginname = NULL;
#ifdef KERBEROS5
	int Fflag;
	krb5_error_code kerror;
#endif
#if defined(KERBEROS5)
	int got_tickets = 0;
#endif
#ifdef LOGIN_CAP
	char *shell = NULL;
	login_cap_t *lc = NULL;
#endif

	tbuf[0] = '\0';
	rval = 0;
	pwprompt = NULL;
	nested = NULL;
	need_chpass = require_chpass = 0;

	(void)signal(SIGALRM, timedout);
	(void)alarm(timeout);
	(void)signal(SIGQUIT, SIG_IGN);
	(void)signal(SIGINT, SIG_IGN);
	(void)setpriority(PRIO_PROCESS, 0, 0);

	openlog("login", 0, LOG_AUTH);

	/*
	 * -p is used by getty to tell login not to destroy the environment
	 * -f is used to skip a second login authentication
	 * -h is used by other servers to pass the name of the remote host to
	 *    login so that it may be placed in utmp/utmpx and wtmp/wtmpx
	 * -a in addition to -h, a server may supply -a to pass the actual
	 *    server address.
	 * -s is used to force use of S/Key or equivalent.
	 */
	if (gethostname(localhost, sizeof(localhost)) < 0) {
		syslog(LOG_ERR, "couldn't get local hostname: %m");
		strcpy(hostname, "amnesiac");
	}
#ifdef notdef
	domain = strchr(localhost, '.');
#endif
	localhost[sizeof(localhost) - 1] = '\0';

	fflag = hflag = pflag = sflag = 0;
	have_ss = 0;
#ifdef KERBEROS5
	Fflag = 0;
	have_forward = 0;
#endif
	uid = getuid();
	while ((ch = getopt(argc, argv, "a:Ffh:ps")) != -1)
		switch (ch) {
		case 'a':
			if (uid)
				errx(EXIT_FAILURE, "-a option: %s", strerror(EPERM));
			decode_ss(optarg);
#ifdef notdef
			(void)sockaddr_snprintf(optarg,
			    sizeof(struct sockaddr_storage), "%a", (void *)&ss);
#endif
			break;
		case 'F':
#ifdef KERBEROS5
			Fflag = 1;
#endif
			/* FALLTHROUGH */
		case 'f':
			fflag = 1;
			break;
		case 'h':
			if (uid)
				errx(EXIT_FAILURE, "-h option: %s", strerror(EPERM));
			hflag = 1;
#ifdef notdef
			if (domain && (p = strchr(optarg, '.')) != NULL &&
			    strcasecmp(p, domain) == 0)
				*p = '\0';
#endif
			hostname = optarg;
			break;
		case 'p':
			pflag = 1;
			break;
		case 's':
			sflag = 1;
			break;
		default:
		case '?':
			usage();
			break;
		}

	setproctitle(NULL);
	argc -= optind;
	argv += optind;

	if (*argv) {
		username = loginname = *argv;
		ask = 0;
	} else
		ask = 1;

#ifdef F_CLOSEM
	(void)fcntl(3, F_CLOSEM, 0);
#else
	for (cnt = getdtablesize(); cnt > 2; cnt--)
		(void)close(cnt);
#endif

	ttyn = ttyname(STDIN_FILENO);
	if (ttyn == NULL || *ttyn == '\0') {
		(void)snprintf(tname, sizeof(tname), "%s??", _PATH_TTY);
		ttyn = tname;
	}
	if ((tty = strstr(ttyn, "/pts/")) != NULL)
		++tty;
	else if ((tty = strrchr(ttyn, '/')) != NULL)
		++tty;
	else
		tty = ttyn;

	if (issetugid()) {
		nested = strdup(user_from_uid(getuid(), 0));
		if (nested == NULL) {
			syslog(LOG_ERR, "strdup: %m");
			sleepexit(EXIT_FAILURE);
		}
	}

#ifdef LOGIN_CAP
	/* Get "login-retries" and "login-backoff" from default class */
	if ((lc = login_getclass(NULL)) != NULL) {
		login_retries = (int)login_getcapnum(lc, "login-retries",
		    DEFAULT_RETRIES, DEFAULT_RETRIES);
		login_backoff = (int)login_getcapnum(lc, "login-backoff", 
		    DEFAULT_BACKOFF, DEFAULT_BACKOFF);
		login_close(lc);
		lc = NULL;
	}
#endif

#ifdef KERBEROS5
	kerror = krb5_init_context(&kcontext);
	if (kerror) {
		/*
		 * If Kerberos is not configured, that is, we are
		 * not using Kerberos, do not log the error message.
		 * However, if Kerberos is configured,  and the
		 * context init fails for some other reason, we need
		 * to issue a no tickets warning to the user when the
		 * login succeeds.
		 */
		if (kerror != ENXIO) {	/* XXX NetBSD-local Heimdal hack */
			syslog(LOG_NOTICE,
			    "%s when initializing Kerberos context",
			    error_message(kerror));
			krb5_configured = 1;
		}
		login_krb5_get_tickets = 0;
	}
#endif /* KERBEROS5 */

	for (cnt = 0;; ask = 1) {
#if defined(KERBEROS5)
		if (login_krb5_get_tickets)
			k5destroy();
#endif
		if (ask) {
			fflag = 0;
			loginname = getloginname();
		}
		rootlogin = 0;
#ifdef KERBEROS5
		if ((instance = strchr(loginname, '/')) != NULL)
			*instance++ = '\0';
		else
			instance = __UNCONST("");
#endif
		username = trimloginname(loginname);
		/*
		 * Note if trying multiple user names; log failures for
		 * previous user name, but don't bother logging one failure
		 * for nonexistent name (mistyped username).
		 */
		if (failures && strcmp(tbuf, username)) {
			if (failures > (pwd ? 0 : 1))
				badlogin(tbuf);
			failures = 0;
		}
		(void)strlcpy(tbuf, username, sizeof(tbuf));

		pwd = getpwnam(username);

#ifdef LOGIN_CAP
		/*
		 * Establish the class now, before we might goto
		 * within the next block. pwd can be NULL since it
		 * falls back to the "default" class if it is.
		 */
		lc = login_getclass(pwd ? pwd->pw_class : NULL);
#endif
		/*
		 * if we have a valid account name, and it doesn't have a
		 * password, or the -f option was specified and the caller
		 * is root or the caller isn't changing their uid, don't
		 * authenticate.
		 */
		if (pwd) {
			if (pwd->pw_uid == 0)
				rootlogin = 1;

			if (fflag && (uid == 0 || uid == pwd->pw_uid)) {
				/* already authenticated */
#ifdef KERBEROS5
				if (login_krb5_get_tickets && Fflag)
					k5_read_creds(username);
#endif
				break;
			} else if (pwd->pw_passwd[0] == '\0') {
				/* pretend password okay */
				rval = 0;
				goto ttycheck;
			}
		}

		fflag = 0;

		(void)setpriority(PRIO_PROCESS, 0, -4);

#ifdef SKEY
		if (skey_haskey(username) == 0) {
			static char skprompt[80];
			const char *skinfo = skey_keyinfo(username);
				
			(void)snprintf(skprompt, sizeof(skprompt),
			    "Password [ %s ]:",
			    skinfo ? skinfo : "error getting challenge");
			pwprompt = skprompt;
		} else
#endif
			pwprompt = "Password:"******"Login incorrect or refused on this "
			    "terminal.\n");
			if (hostname)
				syslog(LOG_NOTICE,
				    "LOGIN %s REFUSED FROM %s ON TTY %s",
				    pwd->pw_name, hostname, tty);
			else
				syslog(LOG_NOTICE,
				    "LOGIN %s REFUSED ON TTY %s",
				     pwd->pw_name, tty);
			continue;
		}

		if (pwd && !rval)
			break;

		(void)printf("Login incorrect or refused on this "
		    "terminal.\n");
		failures++;
		cnt++;
		/*
		 * We allow login_retries tries, but after login_backoff
		 * we start backing off.  These default to 10 and 3
		 * respectively.
		 */
		if (cnt > login_backoff) {
			if (cnt >= login_retries) {
				badlogin(username);
				sleepexit(EXIT_FAILURE);
			}
			sleep((u_int)((cnt - login_backoff) * 5));
		}
	}

	/* committed to login -- turn off timeout */
	(void)alarm((u_int)0);

	endpwent();

	/* if user not super-user, check for disabled logins */
#ifdef LOGIN_CAP
	if (!login_getcapbool(lc, "ignorenologin", rootlogin))
		checknologin(login_getcapstr(lc, "nologin", NULL, NULL));
#else
	if (!rootlogin)
		checknologin(NULL);
#endif

#ifdef LOGIN_CAP
	quietlog = login_getcapbool(lc, "hushlogin", 0);
#else
	quietlog = 0;
#endif
	/* Temporarily give up special privileges so we can change */
	/* into NFS-mounted homes that are exported for non-root */
	/* access and have mode 7x0 */
	saved_uid = geteuid();
	saved_gid = getegid();
	nsaved_gids = getgroups(NGROUPS_MAX, saved_gids);
	
	(void)setegid(pwd->pw_gid);
	initgroups(username, pwd->pw_gid);
	(void)seteuid(pwd->pw_uid);
	
	if (chdir(pwd->pw_dir) < 0) {
#ifdef LOGIN_CAP
		if (login_getcapbool(lc, "requirehome", 0)) {
			(void)printf("Home directory %s required\n",
			    pwd->pw_dir);
			sleepexit(EXIT_FAILURE);
		}
#endif	
		(void)printf("No home directory %s!\n", pwd->pw_dir);
		if (chdir("/") == -1)
			exit(EXIT_FAILURE);
		pwd->pw_dir = __UNCONST("/");
		(void)printf("Logging in with home = \"/\".\n");
	}

	if (!quietlog)
		quietlog = access(_PATH_HUSHLOGIN, F_OK) == 0;

	/* regain special privileges */
	(void)seteuid(saved_uid);
	setgroups(nsaved_gids, saved_gids);
	(void)setegid(saved_gid);

#ifdef LOGIN_CAP
	pw_warntime = login_getcaptime(lc, "password-warn",
		_PASSWORD_WARNDAYS * SECSPERDAY,
		_PASSWORD_WARNDAYS * SECSPERDAY);
#endif

	(void)gettimeofday(&now, NULL);
	if (pwd->pw_expire) {
		if (now.tv_sec >= pwd->pw_expire) {
			(void)printf("Sorry -- your account has expired.\n");
			sleepexit(EXIT_FAILURE);
		} else if (pwd->pw_expire - now.tv_sec < pw_warntime && 
		    !quietlog)
			(void)printf("Warning: your account expires on %s",
			    ctime(&pwd->pw_expire));
	}
	if (pwd->pw_change) {
		if (pwd->pw_change == _PASSWORD_CHGNOW)
			need_chpass = 1;
		else if (now.tv_sec >= pwd->pw_change) {
			(void)printf("Sorry -- your password has expired.\n");
			sleepexit(EXIT_FAILURE);
		} else if (pwd->pw_change - now.tv_sec < pw_warntime && 
		    !quietlog)
			(void)printf("Warning: your password expires on %s",
			    ctime(&pwd->pw_change));

	}
	/* Nothing else left to fail -- really log in. */
	update_db(quietlog, rootlogin, fflag);

	(void)chown(ttyn, pwd->pw_uid,
	    (gr = getgrnam(TTYGRPNAME)) ? gr->gr_gid : pwd->pw_gid);

	if (ttyaction(ttyn, "login", pwd->pw_name))
		(void)printf("Warning: ttyaction failed.\n");

#if defined(KERBEROS5)
	/* Fork so that we can call kdestroy */
	if (! login_krb5_retain_ccache && has_ccache)
		dofork();
#endif

	/* Destroy environment unless user has requested its preservation. */
	if (!pflag)
		environ = envinit;

#ifdef LOGIN_CAP
	if (nested == NULL && setusercontext(lc, pwd, pwd->pw_uid,
	    LOGIN_SETLOGIN) != 0) {
		syslog(LOG_ERR, "setusercontext failed");
		exit(EXIT_FAILURE);
	}
	if (setusercontext(lc, pwd, pwd->pw_uid,
	    (LOGIN_SETALL & ~(LOGIN_SETPATH|LOGIN_SETLOGIN))) != 0) {
		syslog(LOG_ERR, "setusercontext failed");
		exit(EXIT_FAILURE);
	}
#else
	(void)setgid(pwd->pw_gid);

	initgroups(username, pwd->pw_gid);
	
	if (nested == NULL && setlogin(pwd->pw_name) < 0)
		syslog(LOG_ERR, "setlogin() failure: %m");

	/* Discard permissions last so can't get killed and drop core. */
	if (rootlogin)
		(void)setuid(0);
	else
		(void)setuid(pwd->pw_uid);
#endif

	if (*pwd->pw_shell == '\0')
		pwd->pw_shell = __UNCONST(_PATH_BSHELL);
#ifdef LOGIN_CAP
	if ((shell = login_getcapstr(lc, "shell", NULL, NULL)) != NULL) {
		if ((shell = strdup(shell)) == NULL) {
			syslog(LOG_ERR, "Cannot alloc mem");
			sleepexit(EXIT_FAILURE);
		}
		pwd->pw_shell = shell;
	}
#endif
	
	(void)setenv("HOME", pwd->pw_dir, 1);
	(void)setenv("SHELL", pwd->pw_shell, 1);
	if (term[0] == '\0') {
		const char *tt = stypeof(tty);
#ifdef LOGIN_CAP
		if (tt == NULL)
			tt = login_getcapstr(lc, "term", NULL, NULL);
#endif
		/* unknown term -> "su" */
		(void)strlcpy(term, tt != NULL ? tt : "su", sizeof(term));
	}
	(void)setenv("TERM", term, 0);
	(void)setenv("LOGNAME", pwd->pw_name, 1);
	(void)setenv("USER", pwd->pw_name, 1);

#ifdef LOGIN_CAP
	setusercontext(lc, pwd, pwd->pw_uid, LOGIN_SETPATH);
#else
	(void)setenv("PATH", _PATH_DEFPATH, 0);
#endif

#ifdef KERBEROS5
	if (krb5tkfile_env)
		(void)setenv("KRB5CCNAME", krb5tkfile_env, 1);
#endif

	/* If fflag is on, assume caller/authenticator has logged root login. */
	if (rootlogin && fflag == 0) {
		if (hostname)
			syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s FROM %s",
			    username, tty, hostname);
		else
			syslog(LOG_NOTICE, "ROOT LOGIN (%s) ON %s",
			    username, tty);
	}

#if defined(KERBEROS5)
	if (KERBEROS_CONFIGURED && !quietlog && notickets == 1)
		(void)printf("Warning: no Kerberos tickets issued.\n");
#endif

	if (!quietlog) {
		const char *fname;
#ifdef LOGIN_CAP
		fname = login_getcapstr(lc, "copyright", NULL, NULL);
		if (fname != NULL && access(fname, F_OK) == 0)
			motd(fname);
		else
#endif
			(void)printf("%s", copyrightstr);

#ifdef LOGIN_CAP
		fname = login_getcapstr(lc, "welcome", NULL, NULL);
		if (fname == NULL || access(fname, F_OK) != 0)
#endif
			fname = _PATH_MOTDFILE;
		motd(fname);

		(void)snprintf(tbuf,
		    sizeof(tbuf), "%s/%s", _PATH_MAILDIR, pwd->pw_name);
		if (stat(tbuf, &st) == 0 && st.st_size != 0)
			(void)printf("You have %smail.\n",
			    (st.st_mtime > st.st_atime) ? "new " : "");
	}

#ifdef LOGIN_CAP
	login_close(lc);
#endif

	(void)signal(SIGALRM, SIG_DFL);
	(void)signal(SIGQUIT, SIG_DFL);
	(void)signal(SIGINT, SIG_DFL);
	(void)signal(SIGTSTP, SIG_IGN);

	tbuf[0] = '-';
	(void)strlcpy(tbuf + 1, (p = strrchr(pwd->pw_shell, '/')) ?
	    p + 1 : pwd->pw_shell, sizeof(tbuf) - 1);

	/* Wait to change password until we're unprivileged */
	if (need_chpass) {
		if (!require_chpass)
			(void)printf(
"Warning: your password has expired. Please change it as soon as possible.\n");
		else {
			int	status;

			(void)printf(
		    "Your password has expired. Please choose a new one.\n");
			switch (fork()) {
			case -1:
				warn("fork");
				sleepexit(EXIT_FAILURE);
			case 0:
				execl(_PATH_BINPASSWD, "passwd", NULL);
				_exit(EXIT_FAILURE);
			default:
				if (wait(&status) == -1 ||
				    WEXITSTATUS(status))
					sleepexit(EXIT_FAILURE);
			}
		}
	}

#ifdef KERBEROS5
	if (login_krb5_get_tickets)
		k5_write_creds();
#endif
	execlp(pwd->pw_shell, tbuf, NULL);
	err(EXIT_FAILURE, "%s", pwd->pw_shell);
}
Exemplo n.º 24
0
extern bool walk(Node *n, bool parent) {
top:	sigchk();
	if (n == NULL) {
		if (!parent)
			exit(0);
		set(TRUE);
		return TRUE;
	}
	switch (n->type) {
	case nArgs: case nBackq: case nConcat: case nCount:
	case nFlat: case nLappend: case nRedir: case nVar:
	case nVarsub: case nWord:
		exec(glob(glom(n)), parent);	/* simple command */
		break;
	case nBody:
		walk(n->u[0].p, TRUE);
		WALK(n->u[1].p, parent);
		/* WALK doesn't fall through */
	case nNowait: {
		int pid;
		if ((pid = rc_fork()) == 0) {
#if defined(RC_JOB) && defined(SIGTTOU) && defined(SIGTTIN) && defined(SIGTSTP)
			setsigdefaults(FALSE);
			rc_signal(SIGTTOU, SIG_IGN);	/* Berkeleyized version: put it in a new pgroup. */
			rc_signal(SIGTTIN, SIG_IGN);
			rc_signal(SIGTSTP, SIG_IGN);
			setpgid(0, getpid());
#else
			setsigdefaults(TRUE);		/* ignore SIGINT, SIGQUIT, SIGTERM */
#endif
			mvfd(rc_open("/dev/null", rFrom), 0);
			walk(n->u[0].p, FALSE);
			exit(getstatus());
		}
		if (interactive)
			fprint(2, "%d\n", pid);
		varassign("apid", word(nprint("%d", pid), NULL), FALSE);
		redirq = NULL; /* kill pre-redir queue */
		break;
	}
	case nAndalso: {
		bool oldcond = cond;
		cond = TRUE;
		if (walk(n->u[0].p, TRUE)) {
			cond = oldcond;
			WALK(n->u[1].p, parent);
		} else
			cond = oldcond;
		break;
	}
	case nOrelse: {
		bool oldcond = cond;
		cond = TRUE;
		if (!walk(n->u[0].p, TRUE)) {
			cond = oldcond;
			WALK(n->u[1].p, parent);
		} else
			cond = oldcond;
		break;
	}
	case nBang:
		set(!walk(n->u[0].p, TRUE));
		break;
	case nIf: {
		bool oldcond = cond;
		Node *true_cmd = n->u[1].p, *false_cmd = NULL;
		if (true_cmd != NULL && true_cmd->type == nElse) {
			false_cmd = true_cmd->u[1].p;
			true_cmd = true_cmd->u[0].p;
		}
		cond = TRUE;
		if (!walk(n->u[0].p, TRUE))
			true_cmd = false_cmd; /* run the else clause */
		cond = oldcond;
		WALK(true_cmd, parent);
	}
	case nWhile: {
		Jbwrap j;
		Edata jbreak;
		Estack e1, e2;
		bool testtrue, oldcond = cond;
		cond = TRUE;
		if (!walk(n->u[0].p, TRUE)) { /* prevent spurious breaks inside test */
			cond = oldcond;
			break;
		}
		if (sigsetjmp(j.j, 1))
			break;
		jbreak.jb = &j;
		except(eBreak, jbreak, &e1);
		do {
			Edata block;
			block.b = newblock();
			cond = oldcond;
			except(eArena, block, &e2);
			walk(n->u[1].p, TRUE);
			testtrue = walk(n->u[0].p, TRUE);
			unexcept(); /* eArena */
			cond = TRUE;
		} while (testtrue);
		cond = oldcond;
		unexcept(); /* eBreak */
		break;
	}
	case nForin: {
		List *l, *var = glom(n->u[0].p);
		Jbwrap j;
		Estack e1, e2;
		Edata jbreak;
		if (sigsetjmp(j.j, 1))
			break;
		jbreak.jb = &j;
		except(eBreak, jbreak, &e1);
		for (l = listcpy(glob(glom(n->u[1].p)), nalloc); l != NULL; l = l->n) {
			Edata block;
			assign(var, word(l->w, NULL), FALSE);
			block.b = newblock();
			except(eArena, block, &e2);
			walk(n->u[2].p, TRUE);
			unexcept(); /* eArena */
		}
		unexcept(); /* eBreak */
		break;
	}
	case nSubshell:
		if (dofork(TRUE)) {
			setsigdefaults(FALSE);
			walk(n->u[0].p, FALSE);
			rc_exit(getstatus());
		}
		break;
	case nAssign:
		if (n->u[0].p == NULL)
			rc_error("null variable name");
		assign(glom(n->u[0].p), glob(glom(n->u[1].p)), FALSE);
		set(TRUE);
		break;
	case nPipe:
		dopipe(n);
		break;
	case nNewfn: {
		List *l = glom(n->u[0].p);
		if (l == NULL)
			rc_error("null function name");
		while (l != NULL) {
			if (dashex)
				prettyprint_fn(2, l->w, n->u[1].p);
			fnassign(l->w, n->u[1].p);
			l = l->n;
		}
		set(TRUE);
		break;
	}
	case nRmfn: {
		List *l = glom(n->u[0].p);
		while (l != NULL) {
			if (dashex)
				fprint(2, "fn %S\n", l->w);
			fnrm(l->w);
			l = l->n;
		}
		set(TRUE);
		break;
	}
	case nDup:
		redirq = NULL;
		break; /* Null command */
	case nMatch: {
		List *a = glob(glom(n->u[0].p)), *b = glom(n->u[1].p);
		if (dashex)
			fprint(2, (a != NULL && a->n != NULL) ? "~ (%L) %L\n" : "~ %L %L\n", a, " ", b, " ");
		set(lmatch(a, b));
		break;
	}
	case nSwitch: {
		List *v = glom(n->u[0].p);
		while (1) {
			do {
				n = n->u[1].p;
				if (n == NULL)
					return istrue();
			} while (n->u[0].p == NULL || n->u[0].p->type != nCase);
			if (lmatch(v, glom(n->u[0].p->u[0].p))) {
				for (n = n->u[1].p; n != NULL && (n->u[0].p == NULL || n->u[0].p->type != nCase); n = n->u[1].p)
					walk(n->u[0].p, TRUE);
				break;
			}
		}
		break;
	}
	case nPre: {
		List *v;
		if (n->u[0].p->type == nRedir || n->u[0].p->type == nDup) {
			if (redirq == NULL && !dofork(parent)) /* subshell on first preredir */
				break;
			setsigdefaults(FALSE);
			qredir(n->u[0].p);
			if (!haspreredir(n->u[1].p))
				doredirs(); /* no more preredirs, empty queue */
			walk(n->u[1].p, FALSE);
			rc_exit(getstatus());
			/* NOTREACHED */
		} else if (n->u[0].p->type == nAssign) {
			if (isallpre(n->u[1].p)) {
				walk(n->u[0].p, TRUE);
				WALK(n->u[1].p, parent);
			} else {
				Estack e;
				Edata var;
				v = glom(n->u[0].p->u[0].p);
				assign(v, glob(glom(n->u[0].p->u[1].p)), TRUE);
				var.name = v->w;
				except(eVarstack, var, &e);
				walk(n->u[1].p, parent);
				varrm(v->w, TRUE);
				unexcept(); /* eVarstack */
			}
		} else
			panic("unexpected node in preredir section of walk");
		break;
	}
	case nBrace:
		if (n->u[1].p == NULL) {
			WALK(n->u[0].p, parent);
		} else if (dofork(parent)) {
			setsigdefaults(FALSE);
			walk(n->u[1].p, TRUE); /* Do redirections */
			redirq = NULL;   /* Reset redirection queue */
			walk(n->u[0].p, FALSE); /* Do commands */
			rc_exit(getstatus());
			/* NOTREACHED */
		}
		break;
	case nEpilog:
		qredir(n->u[0].p);
		if (n->u[1].p != NULL) {
			WALK(n->u[1].p, parent); /* Do more redirections. */
		} else {
			doredirs();	/* Okay, we hit the bottom. */
		}
		break;
	case nNmpipe:
		rc_error("named pipes cannot be executed as commands");
		/* NOTREACHED */
	default:
		panic("unknown node in walk");
		/* NOTREACHED */
	}
	return istrue();
}
Exemplo n.º 25
0
static pid_t Make_lpd_call( const char *name, WorkerProc *proc, int passfd_count, int *passfd, struct line_list *args, int intern_logger, int intern_status, int intern_mail, int intern_lpd_request, int param_fd )
{
	int pid, fd, i, n, newfd;
	struct line_list env;

	Init_line_list(&env);
	pid = dofork(1);
	if( pid ){
		return(pid);
	}
	Name = "LPD_CALL";

	if(DEBUGL2){
		LOGDEBUG("Make_lpd_call: name '%s', lpd path '%s'", name, Lpd_path_DYN );
		LOGDEBUG("Make_lpd_call: passfd count %d", passfd_count );
		for( i = 0; i < passfd_count; ++i ){
			LOGDEBUG(" [%d] %d", i, passfd[i]);
		}
		Dump_line_list("Make_lpd_call - args", args );
	}
	for( i = 0; i < passfd_count; ++i ){
		fd = passfd[i];
		if( fd < i  ){
			/* we have fd 3 -> 4, but 3 gets wiped out */
			do{
				newfd = dup(fd);
				Max_open(newfd);
				if( newfd < 0 ){
					Errorcode = JABORT;
					logerr_die(LOG_INFO, "Make_lpd_call: dup failed");
				}
				DEBUG4("Make_lpd_call: fd [%d] = %d, dup2 -> %d",
					i, fd, newfd );
				passfd[i] = newfd;
			} while( newfd < i );
		}
	}
	if(DEBUGL2){
		LOGDEBUG("Make_lpd_call: after fixing fd count %d", passfd_count);
		for( i = 0 ; i < passfd_count; ++i ){
			fd = passfd[i];
			LOGDEBUG("  [%d]=%d",i,fd);
		}
	}
	for( i = 0; i < passfd_count; ++i ){
		fd = passfd[i];
		DEBUG2("Make_lpd_call: fd %d -> %d",fd, i );
		if( dup2( fd, i ) == -1 ){
			Errorcode = JABORT;
			logerr_die(LOG_INFO, "Make_lpd_call: dup2(%d,%d) failed",
				fd, i );
		}
	}
	/* close other ones to simulate close_on_exec() */
	n = Max_fd+10;
	for( i = passfd_count ; i < n; ++i ){
		close(i);
	}
	Do_work( name, args, proc,
			intern_logger, intern_status, intern_mail,
			intern_lpd_request, param_fd );
	/* not reached: */
	return(0);
}
Exemplo n.º 26
0
/*
 * Allocate and free in both the parent and the child, and do more
 * than one page.
 */
static
void
test15(void)
{
	unsigned num = 12;

	pid_t pid;
	unsigned i;
	void *p;

	tprintf("Allocating %u pages...\n", num);
	p = dosbrk(PAGE_SIZE * num);
	for (i=0; i<num; i++) {
		markpage(p, i);
	}
	for (i=0; i<num; i++) {
		if (checkpage(p, i, false)) {
			errx(1, "FAILED: data corrupt before forking");
		}
	}

	tprintf("Freeing one page...\n");
	(void)dosbrk(-PAGE_SIZE);
	num--;
	for (i=0; i<num; i++) {
		if (checkpage(p, i, false)) {
			errx(1, "FAILED: data corrupt before forking (2)");
		}
	}

	tprintf("Allocating two pages...\n");
	(void)dosbrk(PAGE_SIZE * 2);
	markpage(p, num++);
	markpage(p, num++);
	for (i=0; i<num; i++) {
		if (checkpage(p, i, false)) {
			errx(1, "FAILED: data corrupt before forking (3)");
		}
	}

	tprintf("Forking...\n");
	pid = dofork();
	if (pid == 0) {
		/* child */
		for (i=0; i<num; i++) {
			if (checkpage(p, i, false)) {
				errx(1, "FAILED: data corrupt in child");
			}
		}

		say("Child: freeing three pages\n");
		dosbrk(-PAGE_SIZE * 3);
		num -= 3;
		for (i=0; i<num; i++) {
			if (checkpage(p, i, false)) {
				errx(1, "FAILED: data corrupt in child (2)");
			}
		}

		say("Child: allocating two pages\n");
		dosbrk(PAGE_SIZE * 2);
		markpage(p, num++);
		markpage(p, num++);
		for (i=0; i<num; i++) {
			if (checkpage(p, i, false)) {
				errx(1, "FAILED: data corrupt in child (3)");
			}
		}

		say("Child: freeing all\n");
		dosbrk(-PAGE_SIZE * num);
		exit(0);
	}
	say("Parent: allocating four pages\n");
	dosbrk(PAGE_SIZE * 4);
	for (i=0; i<4; i++) {
		markpage(p, num++);
	}
	for (i=0; i<num; i++) {
		if (checkpage(p, i, false)) {
			errx(1, "FAILED: data corrupt in parent");
		}
	}

	say("Parent: waiting\n");
	dowait(pid);

	for (i=0; i<num; i++) {
		if (checkpage(p, i, false)) {
			errx(1, "FAILED: data corrupt after waiting");
		}
	}

	(void)dosbrk(-PAGE_SIZE * num);
	tprintf("Passed sbrk test 15.\n");
	success(TEST161_SUCCESS, SECRET, "/testbin/sbrktest");

}