Subject: some NetBSD and 4.4BSD set*id nits for C-Kermit 5a190 beta

From: John Kohl <[email-masked]>

Hi Frank,

You may recall I sent you some patches for BSD/386 C-Kermit.  Well, I"m
now running NetBSD 1.0_BETA, and I have some more patches for you.

Primarily they're to use the proper set*id() function calls to actually
change the user ID's as intended.  setreuid() on NetBSD no longer does
what you might think its name implies, due to POSIXifcation of the
set*id() stuff.  You now have to use sete*id() or straight set*id().

So, there is a Makefile addition (what I used to build C-Kermit on my
NetBSD box), plus a bunch of changes for the set*id() changes.

Note that NOCOTFMC is now needed on NetBSD-1.0_BETA.

With these changes, I believe it's safe to install kermit set-uid or
set-gid on NetBSD 1.0_BETA.

These diffs are off a c-kermit 5a(190) from a couple months ago, so
hopefully they still fit the current stuff.

==John

===================================================================
RCS file: RCS/ckucon.c,v
retrieving revision 1.1
diff -c -r1.1 ckucon.c
*** 1.1	1994/07/31 14:08:06
--- ckucon.c	1994/07/31 14:16:04
***************
*** 1245,1253 ****
  	goto conret1;
  
      } else {	/* *** */		/* Inferior reads, prints port input */
! 
! 	if (priv_can()) {		/* Cancel all privs */
! 	    printf("?setuid error - fatal\n");
  	    doexit(BAD_EXIT,-1);
  	}
  	signal(SIGINT, SIG_IGN);	/* In case these haven't been */
--- 1245,1253 ----
  	goto conret1;
  
      } else {	/* *** */		/* Inferior reads, prints port input */
! 	int xxxx;
! 	if (xxxx = priv_can()) {		/* Cancel all privs */
! 	    printf("?setuid error - fatal (%x)\n", xxxx);
  	    doexit(BAD_EXIT,-1);
  	}
  	signal(SIGINT, SIG_IGN);	/* In case these haven't been */
***************
*** 7163,7169 ****
  #define switchgid(hidden,active)	setregid(hidden,active)
  #endif
  
! #else /* !SETREUID, !SAVEDUID */
  
  /* On System V and POSIX, the only thing we can change is the effective UID
   * (unless the current effective UID is "root", but initsuid() avoids that for
--- 7197,7207 ----
  #define switchgid(hidden,active)	setregid(hidden,active)
  #endif
  
! #else /* !SETREUID */
! #if defined(SETEUID) && defined(SAVEDUID)
! #define switchuid(hidden,active)        seteuid(active)
! #define switchgid(hidden,active)        setegid(active)
! #else /* !SETREUID, !(SETEUID && SAVEDUID) */
  
  /* On System V and POSIX, the only thing we can change is the effective UID
   * (unless the current effective UID is "root", but initsuid() avoids that for
***************
*** 7178,7183 ****
--- 7216,7222 ----
   */
  #define switchuid(hidden,active)	setuid(active)
  #define switchgid(hidden,active)	setgid(active)
+ #endif /* SETEUID */
  #endif /* SETREUID */

***************
*** 7245,7262 ****
  #ifdef SETREUID
      int err = 0;
      if (privuid != (UID_T) -1)
!        if (setreuid(realuid,realuid))
! 	  err |= 1;
! 
      if (privgid != (GID_T) -1)
!         if (setregid(realgid,realgid))
!  	  err |= 2;
! 
      return(err);
  
  #else
      /* Easy way of using setuid()/setgid() instead of setreuid()/setregid().*/
      return(priv_off());
  
  #endif /* SETREUID */
  }
--- 7284,7330 ----
  #ifdef SETREUID
      int err = 0;
      if (privuid != (UID_T) -1)
! 	if (setreuid(realuid,realuid)) {
! 	    debug(F101,"setreuid failed","",errno);
! 	    err |= 1;
! 	    debug(F101,"ruid","",getuid());
! 	    debug(F101,"euid","",geteuid());
! 	}
!     debug(F101,"setreuid","",realuid);
      if (privgid != (GID_T) -1)
!         if (setregid(realgid,realgid)) {
! 	    debug(F101,"setregid failed","",errno);
! 	    err |= 2;
! 	    debug(F101,"rgid","",getgid());
! 	    debug(F101,"egid","",getegid());
! 	}
!     debug(F101,"setregid","",realgid);
      return(err);
  
  #else
+ #ifdef SETEUID
+     int err = 0;
+     if (privuid != (UID_T) -1)
+ 	if (setuid(realuid)) {
+ 	    debug(F101,"setuid failed","",errno);
+ 	    err |= 1;
+ 	    debug(F101,"ruid","",getuid());
+ 	    debug(F101,"euid","",geteuid());
+ 	}
+     debug(F101,"setuid","",realuid);
+     if (privgid != (GID_T) -1)
+         if (setgid(realgid)) {
+ 	    debug(F101,"setgid failed","",errno);
+ 	    err |= 2;
+ 	    debug(F101,"rgid","",getgid());
+ 	    debug(F101,"egid","",getegid());
+ 	}
+     debug(F101,"setgid","",realgid);
+     return(err);
+ #else
      /* Easy way of using setuid()/setgid() instead of setreuid()/setregid().*/
      return(priv_off());
+ #endif
  
  #endif /* SETREUID */
  }
===================================================================
RCS file: RCS/ckuuid.c,v
retrieving revision 1.1
diff -c -r1.1 ckuuid.c
*** 1.1	1994/07/31 14:27:27
--- ckuuid.c	1994/07/31 14:38:56
***************
*** 478,485 ****
  
  /* On systems with setreXid() but without the saved-UID feature, notably
   * BSD 4.2, we swap the real and effective UIDs each time.  It's
!  * the effective UID that we are interested in, but we have to retain the
!  * unused UID somewhere to enable us to restore it later, and we do this
   * in the real UID.  The kernel only allows switching to either the current 
   * real or the effective UID, unless you're "root".
   */
--- 478,485 ----
  
  /* On systems with setreXid() but without the saved-UID feature, notably
   * BSD 4.2, we swap the real and effective UIDs each time.  It's
!  * the effective UID that we are interested in, but we have to retain the
!  * unused UID somewhere to enable us to restore it later, and that we do this
   * in the real UID.  The kernel only allows switching to either the current 
   * real or the effective UID, unless you're "root".
   */
***************
*** 487,493 ****
  #define switchgid(hidden,active)	setregid(hidden,active)
  #endif
  
! #else /* !SETREUID, !SAVEDUID */
  
  /* On System V and POSIX, the only thing we can change is the effective UID
   * (unless the current effective UID is "root", but initsuid() avoids that for
--- 487,497 ----
  #define switchgid(hidden,active)	setregid(hidden,active)
  #endif
  
! #else /* !SETREUID */
! #if defined(SETEUID) && defined(SAVEDUID)
! #define switchuid(hidden,active)        seteuid(active)
! #define switchgid(hidden,active)        setegid(active)
! #else /* !SETREUID, !(SETEUID && SAVEDUID) */
  
  /* On System V and POSIX, the only thing we can change is the effective UID
   * (unless the current effective UID is "root", but initsuid() avoids that for
***************
*** 502,509 ****
   */
  #define switchuid(hidden,active)	setuid(active)
  #define switchgid(hidden,active)	setgid(active)
  #endif /* SETREUID */
-   
  
  /* P R I V _ O N  --  Turn on the setuid and/or setgid */
  
--- 506,513 ----
   */
  #define switchuid(hidden,active)	setuid(active)
  #define switchgid(hidden,active)	setgid(active)
+ #endif /* SETEUID */
  #endif /* SETREUID */
  
  /* P R I V _ O N  --  Turn on the setuid and/or setgid */
  
***************
*** 579,586 ****
--- 583,602 ----
      return(err);
  
  #else
+ #ifdef SETEUID
+     int err = 0;
+     if (privuid != (UID_T) -1)
+        if (setuid(realuid))
+ 	  err |= 1;
+ 
+     if (privgid != (GID_T) -1)
+         if (setgid(realgid))
+  	  err |= 2;
+     return(err);
+ #else
      /* Easy way of using setuid()/setgid() instead of setreuid()/setregid().*/
      return(priv_off());
+ #endif
  
  #endif /* SETREUID */
  }
===================================================================
RCS file: RCS/makefile,v
retrieving revision 1.1
diff -c -r1.1 makefile
*** 1.1	1994/07/31 14:08:06
--- makefile	1994/09/21 00:26:09
***************
*** 336,342 ****
  #       ln /usr/include/arpa/inet.h /usr/include/sys/inet.h
  #       ln /usr/include/sys/termiox.h /usr/include/termiox.h
  # + for NCR System 3000, NCR UNIX 02.02.01, same as above.
! # + for NetBSD on PC 386/486, Amiga, Mac, etc, "make bsd44c"
  # + for NeXT with NeXTSTEP 1.0 through 3.2, "make next" (on a NeXT)
  # + for NeXTSTEP/486, "make next" (on a PC)
  # + for NeXTSTEP portable binary (runs on Intel or Motorola), "make nextfat"
--- 336,342 ----
  #       ln /usr/include/arpa/inet.h /usr/include/sys/inet.h
  #       ln /usr/include/sys/termiox.h /usr/include/termiox.h
  # + for NCR System 3000, NCR UNIX 02.02.01, same as above.
! # + for NetBSD on PC 386/486, Amiga, Mac, etc, "make netbsd"
  # + for NeXT with NeXTSTEP 1.0 through 3.2, "make next" (on a NeXT)
  # + for NeXTSTEP/486, "make next" (on a PC)
  # + for NeXTSTEP portable binary (runs on Intel or Motorola), "make nextfat"
***************
*** 815,820 ****
--- 815,829 ----
  	@echo Making C-Kermit $(CKVER) for 4.4BSD with curses...
  	$(MAKE) wermit \
  	"CFLAGS= -DBSD44 -DCK_CURSES -DDYNAMIC -DTCPSOCKET \
+ 	$(KFLAGS) -O" "LIBS= -lcurses -ltermcap"
+ 
+ #NetBSD: like BSD UNIX 4.4, but needs defines for NOCOTFMC, SAVEDUID, SETEUID,
+ # NOSETREU, plus we add other goodies
+ netbsd:
+ 	@echo Making C-Kermit $(CKVER) for NetBSD...
+ 	$(MAKE) wermit \
+ 	"CFLAGS= -DFUNNEL -DUSLEEP -DSAVEDUID -DSETEUID -DNOSETREU \
+ 	-DBSD44 -DCK_CURSES -DDYNAMIC -DTCPSOCKET -DNOCOTFMC \
  	$(KFLAGS) -O" "LIBS= -lcurses -ltermcap"
  
  #Tektronix 6130, 4319, 4301, etc, with UTek OS, /usr/spool/uucp/LCK./...

---

From: John Kohl <[email-masked]>

Well, I should have taken the latest stuff on kermit.columbia.edu before
sending earlier diffs.

Here are updated patches for the latest stuff on
kermit.columbia.edu:kermit/test/bin/cku190.tar.gz

===================================================================
RCS file: RCS/ckutio.c,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 ckutio.c
*** 1.1.1.1	1994/09/21 03:11:10
--- ckutio.c	1994/09/21 03:29:09
***************
*** 7779,7786 ****
  
!  * the effective UID that we are interrested in, but we have to retain the
--- 7779,7786 ----
  
*** 7893,7901 ****
      return(err);
  
  #else
  
--- 7893,7921 ----
      return(err);
  
  #else
+ #ifdef SETEUID
+     int err = 0;
! #endif /* SETEUID */
  #endif /* SETREUID */
  }
  
===================================================================
RCS file: RCS/makefile,v
retrieving revision 1.1.1.1
diff -c -r1.1.1.1 makefile
*** 1.1.1.1	1994/09/21 03:11:52
--- makefile	1994/09/21 03:13:17
***************
*** 830,836 ****
  	"LIBS= -lcurses -ltermcap"
  
  netbsd:
! 	$(MAKE) bsd44c "KFLAGS=$(KFLAGS)"
  
  #Tektronix 6130, 4319, 4301, etc, with UTek OS, /usr/spool/uucp/LCK./...
  #The models that support hardware flow control.
--- 830,836 ----
  	"LIBS= -lcurses -ltermcap"
  
  netbsd:
! 	$(MAKE) bsd44c "KFLAGS=$(KFLAGS) -DNOCOTFMC"
  
  #Tektronix 6130, 4319, 4301, etc, with UTek OS, /usr/spool/uucp/LCK./...
  #The models that support hardware flow control.
***************
*** 3435,3440 ****
--- 3435,3450 ----
  	@echo 'Running lint on C-Kermit $(CKVER) sources for MIPS version...'
  	lint -DMIPS -DDIRENT -DPID_T=int -DGID_T=gid_t \
  	-DUID_T=uid_t -DNOJC ck[cu]*.c > ckuker.lint.mips
+ 
+ ckuuid:
+ 	@echo 'building C-Kermit $(CKVER) set-UID/set-GID test programs'
+ 	$(CC) -DANYBSD -DSAVEDUID -o ckuuid1 ckuuid.c
+ 	$(CC) -DANYBSD -o ckuuid2 ckuuid.c
+ 	$(CC) -DANYBSD -DNOSETREU -o ckuuid3 ckuuid.c
+ 	$(CC) -DANYBSD -DSETEUID -DNOSETREU -o ckuuid4 ckuuid.c
+ 	$(CC) -o ckuuid5 ckuuid.c
+ 	@echo 'Read the top of ckuuid.c for directions...for testing'
+ 	@echo 'you must make these programs setuid and setgid'
  
  #Anybody remember TECO?
  love:
===================================================================
RCS file: RCS/ckuuid.c,v
retrieving revision 1.1
diff -c -r1.1 ckuuid.c
*** 1.1	1994/09/21 02:30:54
--- ckuuid.c	1994/09/21 03:11:35
***************
*** 5,15 ****
  /* Modified ske, fdc, 6-10-90 */
  /* Modified to check access() and state conclusions, fdc, 12-29-92 */
  
- /*
-   NOTE: This program is now somewhat obsolete since it does not include
-   the 4.4BSD method, in which sete[ug]id are used like System V set[ug]id.
-   Easy to fix.  See ckutio.c, comments around definition of SETEUID symbol.
- */
  
  /*
  INSTRUCTIONS
--- 5,10 ----
***************
*** 19,25 ****
     $ cc -DANYBSD -DSAVEDUID -o ckuuid1 ckuuid.c     (1)
     $ cc -DANYBSD -o ckuuid2 ckuuid.c                (2)
     $ cc -DANYBSD -DNOSETREU -o ckuuid3 ckuuid.c     (3)
!    $ cc -o ckuuid4 ckuuid.c                         (4)
  
  (1) is for Berkeley-based systems that have setregid() and setreuid() and that
      have the saved-original-effective-uid feature, similar to AT&T System V.
--- 14,21 ----
     $ cc -DANYBSD -DSAVEDUID -o ckuuid1 ckuuid.c     (1)
     $ cc -DANYBSD -o ckuuid2 ckuuid.c                (2)
     $ cc -DANYBSD -DNOSETREU -o ckuuid3 ckuuid.c     (3)
!    $ cc -DANYBSD -DSETEUID -DNOSETREU -o ckuuid5 ckuuid.c     (4)
!    $ cc -o ckuuid4 ckuuid.c                         (5)
  
  (1) is for Berkeley-based systems that have setregid() and setreuid() and that
      have the saved-original-effective-uid feature, similar to AT&T System V.
***************
*** 29,35 ****
  
  (3) is for Berkeley-based systems that don't have setregid() and setreuid().
  
! (4) is for all others, including all AT&T-based versions, Xenix, etc.
  
  After building the program, run it to make sure that the uid's don't change
  (they shouldn't if the program is not setuid'd).
--- 25,34 ----
  
  (3) is for Berkeley-based systems that don't have setregid() and setreuid().
  
! (4) is for BSD4.4 and others that have seteuid()/setegid() and
!     saved-original-effective-uid feature.
! 
! (5) is for all others, including all AT&T-based versions, Xenix, etc.
  
  After building the program, run it to make sure that the uid's don't change
  (they shouldn't if the program is not setuid'd).
***************
*** 187,193 ****
      x = priv_on();
      printf("   priv_on returns %d\n",x);
      chuid();
! #ifdef SAVEDUID
      printf("   saved-original-effective-uid feature %s present\n",
  	   (uidb == euid) ? "IS" : "is NOT");
      printf("   saved-original-effective-gid feature %s present\n",
--- 186,192 ----
      x = priv_on();
      printf("   priv_on returns %d\n",x);
      chuid();
! #if defined(SAVEDUID) || defined(SETEUID)
      printf("   saved-original-effective-uid feature %s present\n",
  	   (uidb == euid) ? "IS" : "is NOT");
      printf("   saved-original-effective-gid feature %s present\n",
***************
*** 282,287 ****
--- 281,291 ----
  #else
      printf("   -DSW_ACC_ID omitted\n");
  #endif
+ #ifdef SETEUID
+     printf("   -DSETEUID included\n");
+ #else
+     printf("   -DSETEUID omitted\n");
+ #endif
  #else
      printf("...when built in the System V or POSIX environment\n");
  #endif /* ANYBSD */
***************
*** 495,500 ****
--- 499,515 ----
  
  #else /* !SETREUID, !SAVEDUID */
  
+ #ifdef SETEUID
+ /*
+   BSD 4.4 works similarly to System V and POSIX (see below), but uses
+   seteXid() instead of setXid() to change effective IDs.  In addition, the
+   seteXid() functions work the same for "root" as for other users.
+ */
+ #define switchuid(hidden,active)	seteuid(active)
+ #define switchgid(hidden,active)	setegid(active)
+ 
+ #else /* !SETEUID */
+ 
  /* On System V and POSIX, the only thing we can change is the effective UID
   * (unless the current effective UID is "root", but initsuid() avoids that for
   * us).  The kernel allows switching to the current real UID or to the saved
***************
*** 503,515 ****
   * the current effective UID is "root", though, because for "root" setuid/gid
   * becomes more powerful, which is why initsuid() treats "root" specially.
   * Note: That special treatment maybe could be ignored for BSD?  Note: For
!  * systems that don't fit any of these three cases, we simply can't support
   * set-UID.
   */
  #define switchuid(hidden,active)	setuid(active)
  #define switchgid(hidden,active)	setgid(active)
  #endif /* SETREUID */
-   

--- 518,530 ----
   * the current effective UID is "root", though, because for "root" setuid/gid
   * becomes more powerful, which is why initsuid() treats "root" specially.
   * Note: That special treatment maybe could be ignored for BSD?  Note: For
!  * systems that don't fit any of these four cases, we simply can't support
   * set-UID.
   */
  #define switchuid(hidden,active)	setuid(active)
  #define switchgid(hidden,active)	setgid(active)
+ #endif /* SETEUID */
  #endif /* SETREUID */

***************
*** 585,593 ****
      return(err);
  
  #else
  
--- 600,619 ----
      return(err);
  
  #else
+ #ifdef SETEUID
+     int err = 0;
! #endif /* SETEUID */
  #endif /* SETREUID */
  }