HP3000-L Archives

August 2001, Week 2

HP3000-L@RAVEN.UTC.EDU

Options: Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Message: [<< First] [< Prev] [Next >] [Last >>]
Topic: [<< First] [< Prev] [Next >] [Last >>]
Author: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Subject:
From:
Mark Bixby <[log in to unmask]>
Reply To:
Mark Bixby <[log in to unmask]>
Date:
Fri, 10 Aug 2001 13:30:31 -0700
Content-Type:
text/plain
Parts/Attachments:
text/plain (121 lines)
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 *

ATOM RSS1 RSS2