Subject: Re: some NetBSD and 4.4BSD set*id nits for C-Kermit 5a190 beta
To: None <current-users@netbsd.org>
From: John Kohl <jtk@kolvir.blrc.ma.us>
List: current-users
Date: 09/20/1994 23:31:43
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 ****
  
  /* 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 interrested 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".
   */
--- 7779,7786 ----
  
  /* 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".
   */
***************
*** 7893,7901 ****
      return(err);
  
  #else
      /* Easy way of using setuid()/setgid() instead of setreuid()/setregid().*/
      return(priv_off());
! 
  #endif /* SETREUID */
  }
  
--- 7893,7921 ----
      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 /* 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 */
-   
  
  /* P R I V _ O N  --  Turn on the setuid and/or setgid */
  
--- 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 */
  
  /* P R I V _ O N  --  Turn on the setuid and/or setgid */
  
***************
*** 585,593 ****
      return(err);
  
  #else
      /* Easy way of using setuid()/setgid() instead of setreuid()/setregid().*/
      return(priv_off());
! 
  #endif /* SETREUID */
  }
  
--- 600,619 ----
      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 /* SETEUID */
  #endif /* SETREUID */
  }