Applied patch from Scott Schwartz <schwartz@galapagos.cse.psu.edu>
authorTheodore Tso <tytso@mit.edu>
Fri, 1 Dec 1995 22:35:35 +0000 (22:35 +0000)
committerTheodore Tso <tytso@mit.edu>
Fri, 1 Dec 1995 22:35:35 +0000 (22:35 +0000)
Under SunOS, and maybe other systems, there is a a problem with
krlogind.c and a similar problem with login.c as distributed with
K5.5.

The bug is that rlogind forks a child but retains a controlling tty.
If the child is in the same process group as the parent, which is will
if you don't use a job control shell (chsh /bin/rc), keyboard signals
will kill the daemon.  telnetd dissociates itself properly, but then
login.krb5 waits for the shell to finish, but login.krb5 has the same
ctty as the shell and is in the same process group, so it has the same
problem.

In BSD you used to be able to give up your ctty at will, but SunOS
seems to have setsid as the only mechanism to perform that action, and
setsid can only succeed in limited circumstances.  Rlogind ought to be
fixed to behave more like telnetd, but independent of that, login.krb5
needs to be patched if kerberos is to work properly under SunOS.

git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@7154 dc483132-0cff-0310-8789-dd5450dbe970

src/appl/bsd/ChangeLog
src/appl/bsd/login.c

index 74119d64a90938892e1185bdf9cb35a9dd050770..9f39893436da83c9f1286f427f455175541312d8 100644 (file)
@@ -1,3 +1,29 @@
+Fri Dec  1 17:25:02 1995  Theodore Y. Ts'o  <tytso@dcl>
+
+       * login.c (main, dofork): Applied patch from Scott Schwartz
+               <schwartz@galapagos.cse.psu.edu>
+
+               Under SunOS, and maybe other systems, there is a a problem
+               with krlogind.c and a similar problem with login.c as
+               distributed with K5.5.
+
+               The bug is that rlogind forks a child but retains a
+               controlling tty.  If the child is in the same process
+               group as the parent, which is will if you don't use a job
+               control shell (chsh /bin/rc), keyboard signals will kill
+               the daemon.  telnetd dissociates itself properly, but then
+               login.krb5 waits for the shell to finish, but login.krb5
+               has the same ctty as the shell and is in the same process
+               group, so it has the same problem.
+
+               In BSD you used to be able to give up your ctty at will,
+               but SunOS seems to have setsid as the only mechanism to
+               perform that action, and setsid can only succeed in
+               limited circumstances.  Rlogind ought to be fixed to
+               behave more like telnetd, but independent of that,
+               login.krb5 needs to be patched if kerberos is to work
+               properly under SunOS.
+
 Sun Nov 12 12:39:23 1995  Sam Hartman  <hartmans@tertius.mit.edu>
 
        * krlogind.c (doit): Clear iextn for NetBSD and other 4.4-based
index 2f74563791b6cc400b8f26c528661889bdcc446b..536d2bd30aaadf9157b28be78297db22307e3a50 100644 (file)
@@ -813,6 +813,31 @@ bad_login:
 #endif
        /* Fork so that we can call kdestroy */
        dofork();
+
+/* If the user's shell does not do job control we should put it in a
+   different process group than than us, and set the tty process group
+   to match, otherwise stray signals may be delivered to login.krb5 or
+   telnetd or rlogind if they don't properly detach from their
+   controlling tty, which is the case (under SunOS at least.) */
+
+       { int p = getpid(); 
+          if (setpgrp(p,p) < 0) perror("login.krb5: setpgrp");
+         if (ioctl(0, TIOCSPGRP, &p) < 0) perror("login.krb5: tiocspgrp");
+        }
+
+/* SunOS has an ioctl which can set the controlling tty and make sure
+   that no other process also has it.  That's exactly what we want to
+   do for the shell we are about to exec, since it is the documented
+   way to avoid the problem noted just above. */
+
+#ifdef sun
+#ifdef TIOCSCTTY
+       { if (setsid() < 0) perror("login.krb5: setsid");
+         if (ioctl(0, TIOCSCTTY, 1) < 0) perror("login.krb5: tiocsctty");
+        }
+#endif
+#endif
+
 #endif /* KRB4 */
        (void)setgid((gid_t) pwd->pw_gid);
        (void) initgroups(username, pwd->pw_gid);
@@ -1382,6 +1407,22 @@ dofork()
     if(!(child=fork()))
            return; /* Child process */
 
+    { /* Try and get rid of our controlling tty.  On SunOS, this may or may
+       not work depending on if our parent did a setsid before exec-ing us. */
+#ifdef TIOCNOTTY
+      { int fd;
+        if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
+          ioctl(fd, TIOCNOTTY, 0);
+          close(fd);
+        }
+      }
+#endif
+#ifdef HAVE_SETSID
+      (void)setsid();
+#endif
+      (void)setpgrp(0, 0);
+    } 
+
     /* Setup stuff?  This would be things we could do in parallel with login */
     (void) chdir("/"); /* Let's not keep the fs busy... */