[comp.unix.xenix] setuid

tony@ajfcal.UUCP (Tony Field) (06/09/89)

Is there any way to do a   setuid(geteuid())   when geteuid() != 0  ???

System: Xenix 2.2.3/386.

I have a shell script that is running an effective uid of "news". The
script calls a process that has a real uid of a "user". The process can
create directories with mkdir that belong to "user", however it cannot
create a file.

If the process is setuid to root, then I can create the directores and
the files, however the owner becomes "root", and I would prefer the
owner be "news".

The shell script could pass it's uid to the process as a parameter, and
the process could do a "chown" however there must be a better way:  I would
prefer not to run setuid root.

thanks a bunch...        tony....
-- 
+------------------------------------
|  Tony Field                             ..uunet!utai!calgary!ajfcal!tony
|  Co-Design Information Systems Ltd.
|  Calgary, Alberta, Canada                 voice: (403) 266-3239

maart@cs.vu.nl (Maarten Litmaath) (06/13/89)

tony@ajfcal.UUCP (Tony Field) writes:
\Is there any way to do a   setuid(geteuid())   when geteuid() != 0  ???

setuid() to either geteuid() or getuid() must ALWAYS succeed. Elementary.

\System: Xenix 2.2.3/386.
\
\I have a shell script that is running an effective uid of "news". The
\script calls a process that has a real uid of a "user". The process can
\create directories with mkdir that belong to "user", however it cannot
\create a file.

This is due to the new effective uid OVERWRITING of the old effective uid.
One might consider this a BAD feature...
Now let's take a look at `mkdir': I assume your version of Xenix doesn't have
the mkdir() system call, i.e. /bin/mkdir has to be setuid root.
Scheme:
			real uid - effective uid
	shell script	user       news
	> program 	user       news
	>> mkdir	user       root

whereas one would like
			real uid - effective uid
	shell script	user       news
	> program 	user       news
	>> mkdir	news       root

Alas! `mkdir' will chown() the directory to `user', notwithstanding `program'
having effective uid `news'!
On the other hand `program' (setuid `news') cannot create FILES in the
current directory, because the latter is owned by `user'.

\If the process is setuid to root, then I can create the directores and
\the files, however the owner becomes "root", and I would prefer the
\owner be "news". [...]

A solution: let the shell script invoke some `wrapper', which in turn
executes `program', AFTER having issued a setuid(geteuid()) to set the
REAL uid to the EFFECTIVE uid.
Scheme:
			real uid - effective uid
	shell script	user       news
	> wrapper	user       news
			 |
			 v
			news       news
	>> program 	news       news
	>>> mkdir	news       root

Of course `program' could do the setuid() as well.
-- 
"I HATE arbitrary limits, especially when |Maarten Litmaath @ VU Amsterdam:
   they're small."  (Stephen Savitzky)    |maart@cs.vu.nl, mcvax!botter!maart

clewis@eci386.uucp (Chris Lewis) (06/15/89)

In article <2733@piraat.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
>tony@ajfcal.UUCP (Tony Field) writes:
>\Is there any way to do a   setuid(geteuid())   when geteuid() != 0  ???

>setuid() to either geteuid() or getuid() must ALWAYS succeed. Elementary.

Maarten's usually right, but in this case he isn't.  *Most* versions of
UNIX (eg: Xenix and SV, but I think BSD may be the opposite) do not allow
you to setuid() to anything other than getuid() unless geteuid() != 0.
(SVID and System V also include something called the saved userid, but
this doesn't apply here.).  

On the other hand, BSD can do this quite easily as Maarten
suggests with things like seteuid() and setruid().

Maarten's right in the rest of his article (except for being able
to in general say setuid(geteuid()), however...

The easiest way to get a mkdir to get the ownership the way you want it
is to write a setuid root wrapper that invokes mkdir and then chown's 
the created directory to "news" explicitly.

eg, compile and make setuserid root:

	main(argc, argv) int argc; char **argv; {
	    int pid;
	    if ((pid = fork()) == 0)
		exec("/bin/mkdir", argv[1], 0);
	    while(wait(0) != pid);
	    exec("/bin/chown", "news", argv[1], 0);
	}

(error checking and strong typing left as an exercise to the reader.)

Grotty and inefficient but effective and small.
-- 
Chris Lewis, R.H. Lathwell & Associates: Elegant Communications Inc.
UUCP: {uunet!mnetor, utcsri!utzoo}!lsuc!eci386!clewis
Phone: (416)-595-5425

clewis@eci386.uucp (Chris Lewis) (06/15/89)

In article <2733@piraat.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes:
>tony@ajfcal.UUCP (Tony Field) writes:
>\Is there any way to do a   setuid(geteuid())   when geteuid() != 0  ???

>setuid() to either geteuid() or getuid() must ALWAYS succeed. Elementary.

Maarten's usually right, but in this case he isn't.  *Most* versions of
UNIX (eg: Xenix and SV, but I think BSD may be the opposite) do not allow
you to setuid() to anything other than getuid() unless geteuid() == 0.
(SVID and System V also include something called the saved userid, but
this doesn't apply here.).  

On the other hand, BSD can do this quite easily as Maarten
suggests with things like seteuid() and setruid().

Maarten's right in the rest of his article (except for being able
to in general say setuid(geteuid()), however...

The easiest way to get a mkdir to get the ownership the way you want it
is to write a setuid root wrapper that invokes mkdir and then chown's 
the created directory to "news" explicitly.

eg, compile and make setuserid root:

	main(argc, argv) int argc; char **argv; {
	    int pid;
	    if ((pid = fork()) == 0)
		exec("/bin/mkdir", argv[1], 0);
	    while(wait(0) != pid);
	    exec("/bin/chown", "news", argv[1], 0);
	}

(error checking and strong typing left as an exercise to the reader.)

Grotty and inefficient but effective and small.
-- 
Chris Lewis, R.H. Lathwell & Associates: Elegant Communications Inc.
UUCP: {uunet!mnetor, utcsri!utzoo}!lsuc!eci386!clewis
Phone: (416)-595-5425


-- 
Chris Lewis, R.H. Lathwell & Associates: Elegant Communications Inc.
UUCP: {uunet!mnetor, utcsri!utzoo}!lsuc!eci386!clewis
Phone: (416)-595-5425

chip@ateng.com (Chip Salzenberg) (06/15/89)

According to tony@ajfcal.UUCP (Tony Field):
>System: Xenix 2.2.3/386.
>Is there any way to do a   setuid(geteuid())   when geteuid() != 0  ???

No.

Not only does "setuid(geteuid())" fail, but under SCO Xenix 2.3.1 at least,
it returns ZERO when it fails.

"Error codes?  We don't need no stinking error codes!"
-- 
You may redistribute this article only to those who may freely do likewise.
Chip Salzenberg         |       <chip@ateng.com> or <uunet!ateng!chip>
A T Engineering         |       Me?  Speak for my company?  Surely you jest!

skl@van-bc.UUCP (Samuel Lam) (10/10/89)

Could some setuid() or Xenix expert please help?

I am trying to port the letest (Rick Adams) version of the Berkeley FTP
server to run on SCO Xenix 386 2.3.2 and need to imitate the seteuid()
calls in the code with setuid()'s, since Xenix doesn't have seteuid().

What I need to be able to do is essentially the following:

 - Start with euid(root).
 - ...
 - Switch to euid(arbitrary_uid).
 - ...
 - Revert back to euid(root).
 - ...

Through the course of the program, the real uid can either remain
root or switches following the euid.

I have already spent part of the night trying out various schemes
which I thought would work, but none of them did -- I always had
trouble switching back to root after switching to the arbitrary
uid.  Could someone tell me how this is done?

Thank you very much for your help.

...Sam
-- 
Samuel Lam     <skl@wimsey.bc.ca> or {uunet,ubc-cs}!wimsey.bc.ca!skl