access() and security
Chris Torek
chris at mimsy.UUCP
Wed Apr 27 10:27:32 AEST 1988
In article <13113 at brl-adm.ARPA> mouse at larry.mcrcim.mcgill.edu (der Mouse)
writes:
>What we need, it seems, is a way to say "I wish to restrict myself to
>the real user's access privileges" for a time, with the potential to
>revert back to the previous state. 4.3's setreuid() appears to be
>exactly this
It does.
>though I seem to recall that if the real uid is 0, the process has
>superuser access even if the effective uid is not 0 ...
Not so.
The proper way to test the validity of operation X `before' doing
operation X is to write:
uid_t ruid, euid; gid_t rgid, egid;
ruid = getuid(), euid = geteuid(); /* there should be getreuid */
rgid = getgid(), egid = getegid(); /* and getregid interfaces. */
...
int
do_restricted_operation(op, arg)
int (*op)();
caddr_t arg;
{
int result, saverr;
/* this should never fail */
if (setregid(egid, rgid) || setreuid(euid, ruid))
panic("setre?id 1");
result = (*op)(arg);
/* note that successful syscalls are allowed to alter errno */
saverr = errno;
if (setregid(rgid, egid) || setreuid(ruid, euid))
panic("setre?id 2");
errno = saverr;
return (result);
}
In practise, one would just do the desired operation directly.
To use this particular encapsulation correctly, one must write,
for instance,
struct open_context {
char *path;
int flags;
int mode;
};
int
do_open(arg)
caddr_t arg;
{
struct open_context *c = (struct open_context *)arg;
return (open(c->path, c->flags, c->mode));
}
...
struct open_context c;
int fd;
c.path = "/some/file/name";
c.flags = O_CREAT|O_RDWR|O_EXCL;
c.mode = 0600;
fd = do_restricted_operation(do_open, (caddr_t)&c);
This is quite a bother; it would be nice if C had a `package
up some arguments into a generic argument blob' operation and
an `expand generic argument blob into real arguments' operation,
so that one could write instead
fd = do_restricted_operation(open,
[["/some/file/name", O_CREAT|O_RDWR|O_EXCL, 0600]]);
and inside do_restricted_operation itself,
result = (*op)(<< arg);
(presuming that [[...]] is the argument-builder and unary << is the
argument exploder). An equivalent if less compact representation
would be unnamed functions (a C version of lambda :-) ) and aggregates:
fd = do_restricted_operation(
int (void *arg) {
struct open_context *c = arg;
return (open(c->path, c->flags, c->mode));
},
(void *) &(struct open_context) {
"/some/file/name", O_CREAT|O_RDWR|O_EXCL, 0600
});
which requires no exploder operation.
--
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7163)
Domain: chris at mimsy.umd.edu Path: uunet!mimsy!chris
More information about the Comp.unix.wizards
mailing list