add Berkeley specific copyright
[unix-history] / usr / src / usr.bin / tip / tip.c
index dc2efae..e36593a 100644 (file)
@@ -1,6 +1,29 @@
+/*
+ * Copyright (c) 1983 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that the above copyright notice and this paragraph are
+ * duplicated in all such forms and that any documentation,
+ * advertising materials, and other materials related to such
+ * distribution and use acknowledge that the software was developed
+ * by the University of California, Berkeley.  The name of the
+ * University may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
+ */
+
+#ifndef lint
+char copyright[] =
+"@(#) Copyright (c) 1983 The Regents of the University of California.\n\
+ All rights reserved.\n";
+#endif /* not lint */
+
 #ifndef lint
 #ifndef lint
-static char sccsid[] = "@(#)tip.c      4.17 (Berkeley) %G%";
-#endif
+static char sccsid[] = "@(#)tip.c      5.8 (Berkeley) %G%";
+#endif /* not lint */
 
 /*
  * tip - UNIX link to other systems
 
 /*
  * tip - UNIX link to other systems
@@ -23,7 +46,7 @@ int   intprompt();
 int    timeout();
 int    cleanup();
 char   *sname();
 int    timeout();
 int    cleanup();
 char   *sname();
-extern char *sprintf();
+char   PNbuf[256];                     /* This limits the size of a number */
 
 main(argc, argv)
        char *argv[];
 
 main(argc, argv)
        char *argv[];
@@ -33,9 +56,13 @@ main(argc, argv)
        register char *p;
        char sbuf[12];
 
        register char *p;
        char sbuf[12];
 
+       gid = getgid();
+       egid = getegid();
+       uid = getuid();
+       euid = geteuid();
        if (equal(sname(argv[0]), "cu")) {
        if (equal(sname(argv[0]), "cu")) {
-               cumain(argc, argv);
                cumode = 1;
                cumode = 1;
+               cumain(argc, argv);
                goto cucommon;
        }
 
                goto cucommon;
        }
 
@@ -70,11 +97,24 @@ main(argc, argv)
 
        if (system == NOSTR)
                goto notnumber;
 
        if (system == NOSTR)
                goto notnumber;
+       if (isalpha(*system))
+               goto notnumber;
+       /*
+        * System name is really a phone number...
+        * Copy the number then stomp on the original (in case the number
+        *      is private, we don't want 'ps' or 'w' to find it).
+        */
+       if (strlen(system) > sizeof PNbuf - 1) {
+               fprintf(stderr, "tip: phone number too long (max = %d bytes)\n",
+                       sizeof PNbuf - 1);
+               exit(1);
+       }
+       strncpy( PNbuf, system, sizeof PNbuf - 1 );
        for (p = system; *p; p++)
        for (p = system; *p; p++)
-               if (isalpha(*p))
-                       goto notnumber;
-       PN = system;            /* system name is really a phone number */
-       system = sprintf(sbuf, "tip%d", BR);
+               *p = '\0';
+       PN = PNbuf;
+       (void)sprintf(sbuf, "tip%d", BR);
+       system = sbuf;
 
 notnumber:
        signal(SIGINT, cleanup);
 
 notnumber:
        signal(SIGINT, cleanup);
@@ -88,20 +128,11 @@ notnumber:
        }
        if (i == -1) {
                printf("link down\n");
        }
        if (i == -1) {
                printf("link down\n");
-               delock(uucplock);
+               (void)uu_unlock(uucplock);
                exit(3);
        }
        setbuf(stdout, NULL);
        loginit();
                exit(3);
        }
        setbuf(stdout, NULL);
        loginit();
-       /*
-        * Now that we have the logfile and the ACU open
-        *  return to the real uid and gid.  These things will
-        *  be closed on exit.  Note that we can't run as root,
-        *  because locking mechanism on the tty and the accounting
-        *  will be bypassed.
-        */
-       setgid(getgid());
-       setuid(getuid());
 
        /*
         * Kludge, their's no easy way to get the initialization
 
        /*
         * Kludge, their's no easy way to get the initialization
@@ -113,10 +144,19 @@ notnumber:
        setparity("even");                      /* set the parity table */
        if ((i = speed(number(value(BAUDRATE)))) == NULL) {
                printf("tip: bad baud rate %d\n", number(value(BAUDRATE)));
        setparity("even");                      /* set the parity table */
        if ((i = speed(number(value(BAUDRATE)))) == NULL) {
                printf("tip: bad baud rate %d\n", number(value(BAUDRATE)));
-               delock(uucplock);
+               (void)uu_unlock(uucplock);
                exit(3);
        }
 
                exit(3);
        }
 
+       /*
+        * Now that we have the logfile and the ACU open
+        *  return to the real uid and gid.  These things will
+        *  be closed on exit.  Swap real and effective uid's
+        *  so we can get the original permissions back
+        *  for removing the uucp lock.
+        */
+       user_uid();
+
        /*
         * Hardwired connections require the
         *  line speed set before they make any transmissions
        /*
         * Hardwired connections require the
         *  line speed set before they make any transmissions
@@ -126,7 +166,8 @@ notnumber:
                ttysetup(i);
        if (p = connect()) {
                printf("\07%s\n[EOT]\n", p);
                ttysetup(i);
        if (p = connect()) {
                printf("\07%s\n[EOT]\n", p);
-               delock(uucplock);
+               daemon_uid();
+               (void)uu_unlock(uucplock);
                exit(1);
        }
        if (!HW)
                exit(1);
        }
        if (!HW)
@@ -136,6 +177,7 @@ cucommon:
         * From here down the code is shared with
         * the "cu" version of tip.
         */
         * From here down the code is shared with
         * the "cu" version of tip.
         */
+
        ioctl(0, TIOCGETP, (char *)&defarg);
        ioctl(0, TIOCGETC, (char *)&defchars);
        ioctl(0, TIOCGLTC, (char *)&deflchars);
        ioctl(0, TIOCGETP, (char *)&defarg);
        ioctl(0, TIOCGETC, (char *)&defchars);
        ioctl(0, TIOCGLTC, (char *)&deflchars);
@@ -154,7 +196,7 @@ cucommon:
 
        /*
         * Everything's set up now:
 
        /*
         * Everything's set up now:
-        *      connection established (hardwired or diaulup)
+        *      connection established (hardwired or dialup)
         *      line conditioned (baud rate, mode, etc.)
         *      internal data structures (variables)
         * so, fork one process for local side and one for remote.
         *      line conditioned (baud rate, mode, etc.)
         *      internal data structures (variables)
         * so, fork one process for local side and one for remote.
@@ -170,12 +212,49 @@ cucommon:
 cleanup()
 {
 
 cleanup()
 {
 
-       delock(uucplock);
+       daemon_uid();
+       (void)uu_unlock(uucplock);
        if (odisc)
                ioctl(0, TIOCSETD, (char *)&odisc);
        exit(0);
 }
 
        if (odisc)
                ioctl(0, TIOCSETD, (char *)&odisc);
        exit(0);
 }
 
+/*
+ * Muck with user ID's.  We are setuid to the owner of the lock
+ * directory when we start.  user_uid() reverses real and effective
+ * ID's after startup, to run with the user's permissions.
+ * daemon_uid() switches back to the privileged uid for unlocking.
+ * Finally, to avoid running a shell with the wrong real uid,
+ * shell_uid() sets real and effective uid's to the user's real ID.
+ */
+static int uidswapped;
+
+user_uid()
+{
+       if (uidswapped == 0) {
+               setregid(egid, gid);
+               setreuid(euid, uid);
+               uidswapped = 1;
+       }
+}
+
+daemon_uid()
+{
+
+       if (uidswapped) {
+               setreuid(uid, euid);
+               setregid(gid, egid);
+               uidswapped = 0;
+       }
+}
+
+shell_uid()
+{
+
+       setreuid(uid, uid);
+       setregid(gid, gid);
+}
+
 /*
  * put the controlling keyboard into raw mode
  */
 /*
  * put the controlling keyboard into raw mode
  */
@@ -301,7 +380,7 @@ escape()
        gch = (getchar()&0177);
        for (p = etable; p->e_char; p++)
                if (p->e_char == gch) {
        gch = (getchar()&0177);
        for (p = etable; p->e_char; p++)
                if (p->e_char == gch) {
-                       if ((p->e_flags&PRIV) && getuid())
+                       if ((p->e_flags&PRIV) && uid)
                                continue;
                        printf("%s", ctrl(c));
                        (*p->e_func)(gch);
                                continue;
                        printf("%s", ctrl(c));
                        (*p->e_func)(gch);
@@ -397,7 +476,7 @@ help(c)
 
        printf("%c\r\n", c);
        for (p = etable; p->e_char; p++) {
 
        printf("%c\r\n", c);
        for (p = etable; p->e_char; p++) {
-               if ((p->e_flags&PRIV) && getuid())
+               if ((p->e_flags&PRIV) && uid)
                        continue;
                printf("%2s", ctrl(character(value(ESCAPE))));
                printf("%-2s %c   %s\r\n", ctrl(p->e_char),
                        continue;
                printf("%2s", ctrl(character(value(ESCAPE))));
                printf("%-2s %c   %s\r\n", ctrl(p->e_char),