23,116
社区成员
发帖
与我相关
我的任务
分享
/*
* We must fork before setuid() because we need to call
* pam_close_session() as root.
*/
child_pid = fork();
if (child_pid < 0) {
int errsv = errno;
/* error in fork() */
fprintf(stderr, _("login: failure forking: %s"), strerror(errsv));
PAM_END;
exit(0);
}
if (child_pid) {
/* parent - wait for child to finish, then cleanup session */
close(0);
close(1);
close(2);
sa.sa_handler = SIG_IGN;
sigaction(SIGQUIT, &sa, NULL);
sigaction(SIGINT, &sa, NULL);
/* wait as long as any child is there */
while(wait(NULL) == -1 && errno == EINTR)
;
openlog("login", LOG_ODELAY, LOG_AUTHPRIV);
PAM_END;
exit(0);
}
/* child */
/* restore to old state */
sigaction(SIGHUP, &oldsa_hup, NULL);
sigaction(SIGTERM, &oldsa_term, NULL);
if(got_sig)
exit(1);
/*
* Problem: if the user's shell is a shell like ash that doesnt do
* setsid() or setpgrp(), then a ctrl-\, sending SIGQUIT to every
* process in the pgrp, will kill us.
*/
/* start new session */
setsid();
/* make sure we have a controlling tty */
opentty(ttyn);
openlog("login", LOG_ODELAY, LOG_AUTHPRIV); /* reopen */
/*
* TIOCSCTTY: steal tty from other process group.
*/
if (ioctl(0, TIOCSCTTY, 1))
syslog(LOG_ERR, _("TIOCSCTTY failed: %m"));
#endif
signal(SIGINT, SIG_DFL);
/* discard permissions last so can't get killed and drop core */
if(setuid(pwd->pw_uid) < 0 && pwd->pw_uid) {
syslog(LOG_ALERT, _("setuid() failed"));
exit(1);
}
/* wait until here to change directory! */
if (chdir(pwd->pw_dir) < 0) {
printf(_("No directory %s!\n"), pwd->pw_dir);
if (chdir("/"))
exit(0);
pwd->pw_dir = "/";
printf(_("Logging in with home = \"/\".\n"));
}
/* if the shell field has a space: treat it like a shell script */
if (strchr(pwd->pw_shell, ' ')) {
buff = malloc(strlen(pwd->pw_shell) + 6);
if (!buff) {
fprintf(stderr, _("login: no memory for shell script.\n"));
exit(0);
}
strcpy(buff, "exec ");
strcat(buff, pwd->pw_shell);
childArgv[childArgc++] = "/bin/sh";
childArgv[childArgc++] = "-sh";
childArgv[childArgc++] = "-c";
childArgv[childArgc++] = buff;
} else {
tbuf[0] = '-';
xstrncpy(tbuf + 1, ((p = rindex(pwd->pw_shell, '/')) ?
p + 1 : pwd->pw_shell),
sizeof(tbuf)-1);
childArgv[childArgc++] = pwd->pw_shell;
childArgv[childArgc++] = tbuf;
}
childArgv[childArgc++] = NULL;
execvp(childArgv[0], childArgv + 1);
errsv = errno;
if (!strcmp(childArgv[0], "/bin/sh"))
fprintf(stderr, _("login: couldn't exec shell script: %s.\n"),
strerror(errsv));
else
fprintf(stderr, _("login: no shell: %s.\n"), strerror(errsv));
exit(0);
}