Curtis Larsen wrote:
>
> Let me elaborate a little: I figure I can just call the
> GETPRIVMODE/GETUSERMODE around the code something like:
>
> /*
> * Change UID/GID here so that the following tests work over NFS.
> *
> * Initialize the group access list for the target user,
> * and setgid() to the target group. If unsuccessful, error out.
> */
> #if defined(MPE)
> getprivmode;
> #end
> if (((setgid(gid)) != 0) || (initgroups(actual_uname, gid) != 0))
> {
> log_err("emerg: failed to setgid (%ld: %s)\n", gid, cmd);
> exit(109);
> }
>
> /*
> * setuid() to the target user. Error out on fail.
> */
> if ((setuid(uid)) != 0) {
> log_err("emerg: failed to setuid (%ld: %s)\n", uid, cmd);
> exit(110);
> }
>
> #if defined(MPE)
> getusermode;
> #end
>
> ...but this seems a little too quick-and-dirty.
> Shouldn't I put some status-checking code in here to make sure we got
> into/out of PRIVMODE OK?
As somebody else has already explained, don't bother with the status checking
for GETPRIVMODE and GETUSERMODE for this particular case.
My own style for GETPRIVMODE/GETUSERMODE in POSIX porting is to keep the
duration of priv-mode as short as possible around ONLY the functions that
require it, i.e. instead of:
GETPRIVMODE();
if (foo() == abc) {
do something
}
do something else;
if (bar() == xyz) {
do something
}
GETUSERMODE();
I prefer:
GETPRIVMODE();
if (foo() == abc) {
GETUSERMODE();
do something
}
GETUSERMODE();
do something else;
GETPRIVMODE();
if (bar() == xyz) {
GETUSERMODE();
do something
}
GETUSERMODE();
Yes, it's more keystrokes, but paranoia for privileged open source network apps
is a good thing. ;-)
Here's a real life example of GETPRIVMODE/setuid/GETUSERMODE from BIND:
int __bind_mpe_setuid(uid_t uid) {
char *cwd;
char cwd_buf[PATH_MAX+1];
int result;
extern GETPRIVMODE();
extern GETUSERMODE();
/*
** setuid() is broken as of MPE 5.5 in that it changes the current
** working directory to be the home directory of the new uid. Thus
** we must obtain the cwd and restore it after the setuid().
*/
cwd = getcwd(cwd_buf, PATH_MAX+1); /* Preserve the current working directory */
GETPRIVMODE();
result = setuid(uid);
GETUSERMODE();
chdir(cwd_buf); /* Restore the current working directory */
return result;
}
The approach used here is that of a porting wrapper. I.e. I create my own
setuid lookalike called __bind_mpe_setuid, stick it in a common NMRL *.a
archive library used by the rest of BIND, then modify a common #include file
used by the rest of BIND to do:
#define setuid __bind_mpe_setuid
This method avoid the needs to modify all of the individual setuid() calls
through BIND, and by the magic of the #define, those calls now call my
__bind_mpe_setuid version instead.
--
[log in to unmask]
Remainder of .sig suppressed to conserve scarce California electrons...
* To join/leave the list, search archives, change list settings, *
* etc., please visit http://raven.utc.edu/archives/hp3000-l.html *
|