philip@cs.vu.nl (Philip Homburg) (02/24/90)
Description: su should create a new process group for the new shell, and wait for the new shell to finish in order to reset the tty process group to its old value. Repeat-By: % sh $ su somebody-ELSE-with-a-Bourne-shell Password: $ csh # any shell with job control % exit % $ Stopped (tty input) # or Stopped (tty output), depending on % # the status of the tostop bit Fix: ----------cut here---------- *** su.c.old Sat Feb 24 00:06:13 1990 --- su.c Sat Feb 24 05:43:11 1990 *************** *** 18,26 **** --- 18,29 ---- #include <pwd.h> #include <grp.h> #include <syslog.h> + #include <signal.h> #include <sys/types.h> #include <sys/time.h> #include <sys/resource.h> + #include <sys/ioctl.h> + #include <sys/wait.h> char userbuf[16] = "USER="; char homebuf[128] = "HOME="; *************** *** 111,128 **** syslog(LOG_NOTICE, "%s on %s", Getlogin(), ttyname(2)); closelog(); } - if (setgid(pwd->pw_gid) < 0) { - perror("su: setgid"); - exit(3); - } - if (initgroups(user, pwd->pw_gid)) { - fprintf(stderr, "su: initgroups failed\n"); - exit(4); - } - if (setuid(pwd->pw_uid) < 0) { - perror("su: setuid"); - exit(5); - } if (pwd->pw_shell && *pwd->pw_shell) shell = pwd->pw_shell; if (fulllogin) { --- 114,119 ---- *************** *** 145,153 **** *argv = "-su"; } else *argv = "su"; ! execv(shell, argv); ! fprintf(stderr, "No shell\n"); ! exit(7); } setenv(ename, eval, buf) --- 136,193 ---- *argv = "-su"; } else *argv = "su"; ! { ! int opgrp, npgrp, fd; ! union wait w; ! ! fd = open("/dev/tty", 0); ! ! if (fd >= 0) ! (void) ioctl(fd, TIOCGPGRP, &opgrp); ! ! switch (fork()) { ! case -1: ! perror("fork"); ! exit(1); ! case 0: ! if (setgid(pwd->pw_gid) < 0) { ! perror("su: setgid"); ! exit(3); ! } ! if (initgroups(user, pwd->pw_gid)) { ! perror("su: initgroups failed"); ! exit(4); ! } ! if (setuid(pwd->pw_uid) < 0) { ! perror("su: setuid"); ! exit(5); ! } ! npgrp = getpid(); ! if (fd >= 0) { ! if (ioctl(fd, TIOCSPGRP, &npgrp) < 0) { ! perror("ioctl TIOCSPGRP"); ! exit(99); ! } ! close(fd); ! } ! setpgrp(0, npgrp); ! execv(shell, argv); ! perror(shell); ! exit(7); ! default: ! (void) wait3(&w, 0, (struct rusage *) 0); ! setuid(getuid()); ! setgid(getgid()); ! if (fd >= 0) { ! sigblock(sigmask(SIGTTOU)); ! (void) ioctl(fd, TIOCSPGRP, &opgrp); ! } ! if (WIFEXITED(w)) ! exit(w.w_retcode); ! else ! exit(0200 + w.w_termsig); ! } ! } } setenv(ename, eval, buf) ----------cut here----------
casey@gauss.llnl.gov (Casey Leedom) (02/25/90)
| From: philip@cs.vu.nl (Philip Homburg) | Description: | su should create a new process group for the new shell, | and wait for the new shell to finish in order to reset | the tty process group to its old value. | | Repeat-By: | % sh | $ su somebody-ELSE-with-a-Bourne-shell | Password: | $ csh # any shell with job control | % exit | % $ | Stopped (tty input) # or Stopped (tty output), depending on | % # the status of the tostop bit This isn't a bug in su. It's a bug in the shell.