aboutsummaryrefslogtreecommitdiff
path: root/libtrivfs/io-restrict-auth.c
diff options
context:
space:
mode:
Diffstat (limited to 'libtrivfs/io-restrict-auth.c')
-rw-r--r--libtrivfs/io-restrict-auth.c100
1 files changed, 66 insertions, 34 deletions
diff --git a/libtrivfs/io-restrict-auth.c b/libtrivfs/io-restrict-auth.c
index ac915896..98a80a13 100644
--- a/libtrivfs/io-restrict-auth.c
+++ b/libtrivfs/io-restrict-auth.c
@@ -1,5 +1,5 @@
/*
- Copyright (C) 1993, 1994, 1995 Free Software Foundation
+ Copyright (C) 1993,94,95,96,2001,02 Free Software Foundation, Inc.
This file is part of the GNU Hurd.
@@ -8,7 +8,7 @@ it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
-The GNU Hurd is distributed in the hope that it will be useful,
+The GNU Hurd is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
@@ -20,7 +20,6 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Written by Michael I. Bushnell. */
#include "priv.h"
-#include "io_S.h"
#include <string.h>
/* Tell if the array LIST (of size N) contains a member equal to QUERY. */
@@ -40,55 +39,88 @@ trivfs_S_io_restrict_auth (struct trivfs_protid *cred,
mach_msg_type_name_t replytype,
mach_port_t *newport,
mach_msg_type_name_t *newporttype,
- uid_t *uids, u_int nuids,
- uid_t *gids, u_int ngids)
+ uid_t *uids, size_t nuids,
+ uid_t *gids, size_t ngids)
{
int i;
- error_t err = 0;
+ error_t err;
struct trivfs_protid *newcred;
- uid_t *newuids, *newgids;
- int newnuids, newngids;
-
+ struct idvec *uvec, *gvec;
+ struct iouser *user;
+
if (!cred)
return EOPNOTSUPP;
-
- newuids = alloca (sizeof (uid_t) * cred->nuids);
- newgids = alloca (sizeof (uid_t) * cred->ngids);
- for (i = newnuids = 0; i < cred->nuids; i++)
- if (listmember (uids, cred->uids[i], nuids))
- newuids[newnuids++] = cred->uids[i];
- for (i = newngids = 0; i < cred->gids[i]; i++)
- if (listmember (gids, cred->gids[i], ngids))
- newgids[newngids++] = cred->gids[i];
+
+ if (cred->isroot)
+ /* CRED has root access, and so may use any ids. */
+ {
+ err = iohelp_create_complex_iouser (&user, uids, nuids, gids, ngids);
+ if (err)
+ return err;
+ }
+ else
+ {
+ uvec = make_idvec ();
+ if (! uvec)
+ return ENOMEM;
+
+ gvec = make_idvec ();
+ if (! gvec)
+ {
+ idvec_free (uvec);
+ return ENOMEM;
+ }
+
+ /* Otherwise, use any of the requested ids that CRED already has. */
+ for (i = 0; i < cred->user->uids->num; i++)
+ if (listmember (uids, cred->user->uids->ids[i], nuids))
+ {
+ err = idvec_add (uvec, cred->user->uids->ids[i]);
+ if (err)
+ goto out;
+ }
+
+ for (i = 0; i < cred->user->gids->num; i++)
+ if (listmember (gids, cred->user->gids->ids[i], ngids))
+ {
+ err = idvec_add (gvec, cred->user->gids->ids[i]);
+ if (err)
+ goto out;
+ }
+
+ err = iohelp_create_iouser (&user, uvec, gvec);
+ if (err)
+ {
+ out:
+ idvec_free (uvec);
+ idvec_free (gvec);
+ return err;
+ }
+ }
err = ports_create_port (cred->po->cntl->protid_class,
cred->po->cntl->protid_bucket,
- sizeof (struct trivfs_protid),
+ sizeof (struct trivfs_protid),
&newcred);
if (err)
- return err;
+ {
+ iohelp_free_iouser (user);
+ return err;
+ }
newcred->isroot = 0;
mutex_lock (&cred->po->cntl->lock);
newcred->po = cred->po;
newcred->po->refcnt++;
mutex_unlock (&cred->po->cntl->lock);
- if (cred->isroot)
- {
- for (i = 0; i < nuids; i++)
- if (uids[i] == 0)
- newcred->isroot = 1;
- }
- newcred->gids = malloc (newngids * sizeof (uid_t));
- newcred->uids = malloc (newnuids * sizeof (uid_t));
- bcopy (newuids, newcred->uids, newnuids * sizeof (uid_t));
- bcopy (newgids, newcred->gids, newngids * sizeof (uid_t));
- newcred->ngids = newngids;
- newcred->nuids = newnuids;
+ if (cred->isroot && idvec_contains (user->uids, 0))
+ newcred->isroot = 1;
+ newcred->user = user;
newcred->hook = cred->hook;
- err = io_restrict_auth (cred->realnode, &newcred->realnode,
- newuids, newnuids, newgids, newngids);
+ err = io_restrict_auth (cred->realnode, &newcred->realnode,
+ user->uids->ids, user->uids->num,
+ user->gids->ids, user->gids->num);
if (!err && trivfs_protid_create_hook)
{
err = (*trivfs_protid_create_hook) (newcred);