smw@maxwell.concordia.ca ( Steven Winikoff ) (02/03/90)
I've encountered a problem using getuid(), on both a Sun 4/280 under
SunOS 4.0 and a MIPS M-120/5 under MIPS RISC/os 4.0.1 (SVR3 plus BSD
compatibility). The following short program produces the same results
on both systems, and replicates the behaviour I've experienced in the
middle of a much larger application:
#include <stdio.h>
main()
{
int getuid();
printf("uid = %d\n", getuid());
}
When I log in as user "smw" (user index = 1000), the program does indeed
return "uid = 1000".
However, when I then execute the su command, I receive "uid = 0" instead
of the expected "uid = 1000".
Am I missing something? I thought that this was the expected behaviour
for geteuid() instead of getuid(), and that's why I used getuid() in the
first place!
Can anyone tell me if I'm just confused, or if I'm simply not doing it
right, or if there's actually a bug in the Sun and MIPS implementation
of these calls?
Thanks very much in advance!
Regards,
- Steven
------------------------------------------------------------------------
Steven Winikoff smw@maxwell.concordia.ca
Software Analyst
Dept. of Computing services
Concordia University voice: (514) 848-7619
Montreal, Quebec, Canada (10:00-18:00 EST)
tale@cs.rpi.edu (David C Lawrence) (02/03/90)
In <1836@clyde.concordia.ca> smw@maxwell.concordia.ca ( Steven Winikoff ): > When I log in as user "smw" (user index = 1000), the program does indeed > return "uid = 1000". > However, when I then execute the su command, I receive "uid = 0" instead > of the expected "uid = 1000". > Am I missing something? Yes. > I thought that this was the expected behaviour for geteuid() instead > of getuid(), No. > and that's why I used getuid() in the first place! You could use getlogin(), but be wary of it. It can fail under a lot of situations. @opinionated sidebar I personally loathe getlogin() and programmes that are concerned with what userid I might have started out as on some pre-su level, so I won't describe how to do it. One thing you might want to reconsider is why you are concerned with the userid of the login. When I su to someone else I want my userid to be that one, not the one that I was. (On very rare occasion I might want it to be the original, but I can deal with that in another way.) @end opinionated sidebar > Can anyone tell me if I'm just confused, or if I'm simply not doing it > right, or if there's actually a bug in the Sun and MIPS implementation > of these calls? If there was a bug in it then things would have been upchucking all over the place and people would be up in arms about it. geteuid() is used to get the userid of a setuid executable. getuid() is meant to return the userid that invoked the programme. For non-setuid executables they will always return the same number. Dave -- (setq mail '("tale@cs.rpi.edu" "tale@ai.mit.edu" "tale@rpitsmts.bitnet")) "Nice plant. Looks like a table cloth."
smw@maxwell.Concordia.CA ( Steven Winikoff ) (02/03/90)
In article <?_3}%-@rpi.edu> tale@cs.rpi.edu (David C Lawrence) writes: >@opinionated sidebar >I personally loathe getlogin() and programmes that are concerned with >what userid I might have started out as on some pre-su level, so I >won't describe how to do it. One thing you might want to reconsider >is why you are concerned with the userid of the login. When I su to >someone else I want my userid to be that one, not the one that I was. My problem is that there are several people at our site who are legitimately able to su root, working on different projects at the same time (perhaps that's a bad idea, but it's not under my control). In any case, the idea is to find some way to identify our printed output, from within a local customized print program. Several hundred (ok, I'm exaggerating!) listings all marked "root" are, IMHO, less useful than the same listings broken down by our real user name. Perhaps I'm going about this by trying to solve the wrong problem, but that's what I'm looking for. Thoughts? Comments? Ideas? All would be appreciated. >If there was a bug in it then things would have been upchucking all >over the place and people would be up in arms about it. That does make sense, I suppose :-) >geteuid() is >used to get the userid of a setuid executable. getuid() is meant to >return the userid that invoked the programme. For non-setuid >executables they will always return the same number. Thanks for the clarification! ------------------------------------------------------------------------ Steven Winikoff smw@maxwell.concordia.ca Software Analyst Dept. of Computing services Concordia University voice: (514) 848-7619 Montreal, Quebec, Canada (10:00-18:00 EST)
maart@cs.vu.nl (Maarten Litmaath) (02/06/90)
In article <1837@clyde.concordia.ca>, smw@maxwell.Concordia.CA ( Steven Winikoff ) writes: \In article <?_3}%-@rpi.edu> tale@cs.rpi.edu (David C Lawrence) writes: \ \>@opinionated sidebar \>I personally loathe getlogin() and programmes that are concerned with \>what userid I might have started out as on some pre-su level, [...] \... \My problem is that there are several people at our site who are legitimately \able to su root, working on different projects at the same time (perhaps \that's a bad idea, but it's not under my control). In any case, the idea \is to find some way to identify our printed output, [...] But that's precisely what UCB's lpr does! By means of getlogin()! :-( Anyway, you could always replace lpr by something like this: #include <pwd.h> #include <stdio.h> char My_lpr[] = "/path/of/my_lpr"; main(argc, argv) int argc; char **argv; { char *getenv(), *lprname = getenv("LPRNAME"); struct passwd *pw; if (lprname) { if (!(pw = getpwnam(lprname))) fprintf(stderr, "You don't exist. Go away.\n"); else if (setuid(pw->pw_uid) != 0) perror("setuid"); } argv[0] = My_lpr; execv(My_lpr, argv); perror(My_lpr); exit(1); } ...where `my_lpr' is: #!/bin/sh exec 3>&1 test -t 0 && exec < /dev/null (/usr/ucb/lpr ${1+"$@"} | cat >&3) 2>&1 | cat >&2 -- The meek get the earth, Henry the moon, the rest of us have other plans. | Maarten Litmaath @ VU Amsterdam: maart@cs.vu.nl, uunet!mcsun!botter!maart
smw@maxwell.Concordia.CA ( Steven Winikoff ) (02/08/90)
First, my apologies if this gets posted twice. The first one apparently vanished into the bit bucket. In article <5315@star.cs.vu.nl> maart@cs.vu.nl (Maarten Litmaath) writes: >In article <1837@clyde.concordia.ca>, > smw@maxwell.Concordia.CA ( Steven Winikoff ) writes: >\My problem is that there are several people at our site who are legitimately >\able to su root, working on different projects at the same time (perhaps >\that's a bad idea, but it's not under my control). In any case, the idea >\is to find some way to identify our printed output, [...] > >But that's precisely what UCB's lpr does! By means of getlogin()! :-( True. But if I could use lpr in the first place, none of this would have arisen... :-) Fact is that the printer I'm trying to reach is connected to a CDC Cyber under NOS (CDC's proprietary OS, for those unfamiliar with Control Data). The Cyber is connected to a VMS VAX 8550 via JNET, and my Unix system is connected to the VAX via a MicroVAX running Ultrix! Are you now as confused as I am? If not, all you have to do is reread the above paragraph a couple of dozen times, and then your head will be spinning just like mine! :-) No, there's no way I can get a printer closer than that. :-( And no, there's no way (at least none that our Powers That Be will agree to finance!) to bridge the gap between Unix and the Cyber directly. :-( So I'm stuck with writing an application that wants to send a file to the VAX via ftp, along with instructions re what to do with it when it gets there. A client process on the VAX takes the file and automagically routes it over the JNET link. (The VAX/Cyber link is maintained by our local VMS guru. My personal VMS knowledge ranges between poor and non-existent.) That's why I need some reliable way of determining who *really* sent a given file, simply because I'd like to be able to recognize my own output when I get it! When I began all this, I naively thought that getuid would do it for me. Now I know that it won't. Based on the suggestions of all the kind people who have so far responded to me, it seems that the best I can do in the case where getuid returns 0 is a tiered approach which begins with getlogin and falls back on logname (== value of $USER) when getlogin fails. >Anyway, you could always replace lpr by something like this: > > #include <pwd.h> > #include <stdio.h> > > char My_lpr[] = "/path/of/my_lpr"; > > main(argc, argv) > int argc; > char **argv; > { > char *getenv(), *lprname = getenv("LPRNAME"); > struct passwd *pw; > > if (lprname) { > if (!(pw = getpwnam(lprname))) > fprintf(stderr, > "You don't exist. Go away.\n"); > else if (setuid(pw->pw_uid) != 0) > perror("setuid"); > } > argv[0] = My_lpr; > execv(My_lpr, argv); > perror(My_lpr); > exit(1); > } > >...where `my_lpr' is: > > #!/bin/sh > > exec 3>&1 > > test -t 0 && exec < /dev/null > > (/usr/ucb/lpr ${1+"$@"} | cat >&3) 2>&1 | cat >&2 I'm not quite sure I understand your code. Who sets LPRNAME? In "my_lpr", what gets exec'd in line 2? Please excuse my ignorance, I'm only a wizard wanna-be! >-- > The meek get the earth, Henry the moon, the rest of us have other plans. | > Maarten Litmaath @ VU Amsterdam: maart@cs.vu.nl, uunet!mcsun!botter!maart Love your .sig! ------------------------------------------------------------------------ Steven Winikoff smw@maxwell.concordia.ca Software Analyst Concordia University Computer Centre voice: (514) 848-7619 Montreal, Quebec, Canada (10:00-18:00 EST)
maart@cs.vu.nl (Maarten Litmaath) (02/08/90)
In article <1844@clyde.concordia.ca>, smw@maxwell.Concordia.CA ( Steven Winikoff ) writes: \... \> char *getenv(), *lprname = getenv("LPRNAME"); \... \>...where `my_lpr' is: \> \> #!/bin/sh \> \> exec 3>&1 Dup(2) file descriptor 3 from 1. \> test -t 0 && exec < /dev/null If stdin is a terminal, connect stdin to /dev/null. \> (/usr/ucb/lpr ${1+"$@"} | cat >&3) 2>&1 | cat >&2 Feed lpr's stdout to the first cat, whose stdout is dupped to the original (saved) stdout; feed lpr's stderr to the second cat (mjum), whose droppings go to the original stderr. Now none of lpr's stdin/stdout/stderr points to a terminal, so lpr will use getpwuid(getuid()), as getlogin() fails. Piece of cake, right? \I'm not quite sure I understand your code. Who sets LPRNAME? In "my_lpr", \what gets exec'd in line 2? Please excuse my ignorance, I'm only a wizard \wanna-be! Each user himself should set LPRNAME (.profile/.login) and change it accordingly after a su (it's easy to write a wrapper for su which sets LPRNAME beforehand). You could use USER or LOGNAME, but beware: there are programs which expect those to contain *login names* (e.g. inews). :-( \... \Love your .sig! Thanks. -- The meek get the earth, Henry the moon, the rest of us have other plans. | Maarten Litmaath @ VU Amsterdam: maart@cs.vu.nl, uunet!mcsun!botter!maart
les@chinet.chi.il.us (Leslie Mikesell) (02/09/90)
In article <1837@clyde.concordia.ca> smw@maxwell.Concordia.CA ( Steven Winikoff ) writes: >My problem is that there are several people at our site who are legitimately >able to su root, working on different projects at the same time (perhaps >that's a bad idea, but it's not under my control). In any case, the idea >is to find some way to identify our printed output, from within a local >customized print program. Since it's not really a security issue, why don't you just use the environment variable LOGNAME? If it's good enough for SysV mail to identify the sender perhaps it will work for you as well. You might want to designate another variable to be checked first so you can type something like: PRID=some_else lp file when you want a print job delivered to some else. Les Mikesell les@chinet.chi.il.us