summaryrefslogtreecommitdiff
path: root/libdiskfs
diff options
context:
space:
mode:
authorMichael I. Bushnell <mib@gnu.org>1995-03-17 18:54:45 +0000
committerMichael I. Bushnell <mib@gnu.org>1995-03-17 18:54:45 +0000
commit3cf17d30fac99853c5324167d35ba4db667cd819 (patch)
tree92526529b6ce8e89fcfea7a2d70ef9b1c94cc3a7 /libdiskfs
parente29bc1efcfafc4c96f3be04fefa0590906c35ea9 (diff)
Back out changes to protid and associated permission checking
functions.
Diffstat (limited to 'libdiskfs')
-rw-r--r--libdiskfs/diskfs.h134
1 files changed, 33 insertions, 101 deletions
diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h
index 5735bee0..1d24661d 100644
--- a/libdiskfs/diskfs.h
+++ b/libdiskfs/diskfs.h
@@ -20,24 +20,15 @@
#include <assert.h>
-/* Identifies a given user; these are chained for the implementation
- of the layering semantics of io_restrict_auth. */
-struct userid
-{
- int refcnt;
- uid_t *uids, *gids;
- int nuids, ngids;
- struct userid *next;
-};
-
/* Each user port referring to a file points to one of these
(with the aid of the ports library. */
struct protid
{
struct port_info pi; /* libports info block */
- /* Identifies chain of user ids. */
- struct userid *id;
+ /* User identification */
+ uid_t *uids, *gids;
+ int nuids, ngids;
/* Object this refers to */
struct peropen *po;
@@ -134,7 +125,10 @@ extern volatile struct mapped_time_value *diskfs_mtime;
extern int diskfs_bootflags;
extern char *diskfs_bootflagarg;
-/* True iff we should do every operation synchronously. */
+/* True iff we should do every operation synchronously. It
+ is the format-specific code's responsibility to keep allocation
+ information permanently in sync if this is set; the rest will
+ be done by format independent code. */
extern int diskfs_synchronous;
extern spin_lock_t diskfs_node_refcnt_lock;
@@ -627,142 +621,80 @@ diskfs_nrele_light (struct node *np)
spin_unlock (&diskfs_node_refcnt_lock);
}
-/* Return nonzero iff the user identified by ID has uid UID. */
+/* Return nonzero iff the user identified by CRED has uid UID. */
extern inline int
-diskfs_idhasuid (uid_t uid, struct userid *id)
+diskfs_isuid (uid_t uid, struct protid *cred)
{
int i;
-
- for (i = 0; i < id->nuids; i++)
- if (id->uids[i] == uid)
+ for (i = 0; i < cred->nuids; i++)
+ if (cred->uids[i] == uid)
return 1;
return 0;
}
-/* Return nonzero iff the user identified by ID has gid GRP. */
+/* Return nonzero iff the user identified by CRED has group GRP. */
extern inline int
-diskfs_idhasgid (uid_t grp, struct userid *id)
+diskfs_groupmember (uid_t grp, struct protid *cred)
{
int i;
-
- for (i = 0; i < id->ngids; i++)
- if (id->gids[i] == grp)
+ for (i = 0; i < cred->ngids; i++)
+ if (cred->gids[i] == grp)
return 1;
return 0;
}
-/* Check to see if the user identified by ID is permitted to do
+/* Check to see if the user identified by CRED is permitted to do
owner-only operations on node NP; if so, return 0; if not, return
EPERM. */
extern inline error_t
-_diskfs_idisowner (struct node *np, struct userid *id)
+diskfs_isowner (struct node *np, struct protid *cred)
{
/* Permitted if the user is the owner, superuser, or if the user
is in the group of the file and has the group ID as their user
ID. (This last is colloquially known as `group leader'.) */
- if (diskfs_idhasuid (np->dn_stat.st_uid, id) || diskfs_idhasuid (0, id)
- || (diskfs_idhasgid (np->dn_stat.st_gid, id)
- && diskfs_idhasuid (np->dn_stat.st_gid, id)))
+ if (diskfs_isuid (np->dn_stat.st_uid, cred) || diskfs_isuid (0, cred)
+ || (diskfs_groupmember (np->dn_stat.st_gid, cred)
+ && diskfs_isuid (np->dn_stat.st_gid, cred)))
return 0;
else
return EPERM;
}
-/* Check to see is the user identified by ID is permitted to do
+/* Check to see is the user identified by CRED is permitted to do
operation OP on node NP. Op is one of S_IREAD, S_IWRITE, or S_IEXEC.
Return 0 if the operation is permitted and EACCES if not. */
extern inline error_t
-_diskfs_idaccess (struct node *np, int op, struct userid *id)
+diskfs_access (struct node *np, int op, struct protid *cred)
{
int gotit;
-
- if (diskfs_idhasuid (0, id))
+ if (diskfs_isuid (0, cred))
gotit = 1;
- else if (id->nuids == 0 && (np->dn_stat.st_mode & S_IUSEUNK))
+ else if (cred->nuids == 0 && (np->dn_stat.st_mode & S_IUSEUNK))
gotit = np->dn_stat.st_mode & (op << S_IUNKSHIFT);
- else if (!_diskfs_idisowner (np, id))
+ else if (!diskfs_isowner (np, cred))
gotit = np->dn_stat.st_mode & op;
- else if (diskfs_idhasgid (np->dn_stat.st_gid, id))
+ else if (diskfs_groupmember (np->dn_stat.st_gid, cred))
gotit = np->dn_stat.st_mode & (op >> 3);
else
gotit = np->dn_stat.st_mode & (op >> 6);
-
- /* I learned this kind of thing from APL. Cool, huh? */
- return (!gotit) * EACCES;
+ return gotit ? 0 : EACCES;
}
-/* Check to see if the user identified by ID is allowed to modify
+/* Check to see if the user identified by CRED is allowed to modify
directory DP with respect to existing file NP. This is the same
as diskfs_access (dp, S_IWRITE, cred), except when the directory
has the sticky bit set. (If there is no existing file NP, then
0 can be passed.) */
extern inline error_t
-_diskfs_idcheckdirmod (struct node *dp, struct node *np,
- struct userid *id)
+diskfs_checkdirmod (struct node *dp, struct node *np,
+ struct protid *cred)
{
/* The user must be able to write the directory, but if the directory
is sticky, then the user must also be either the owner of the directory
or the file. */
- return (_diskfs_idaccess (dp, S_IWRITE, id)
- && (!(dp->dn_stat.st_mode & S_ISVTX) || !np
- || diskfs_idhasuid (0, id) || _diskfs_idisowner (dp, id)
- || _diskfs_idisowner (np, id)));
-}
-
-/* Return if the calling user CRED should be permitted to do an owner
- only operation on NP. If so, return 0; if not, return EPERM. */
-extern inline error_t
-diskfs_isowner (struct node *np, struct protid *cred)
-{
- struct userid *id;
- error_t err;
-
- assert (cred->id);
- for (id = cred->id; id; id = id->next)
- {
- err = _diskfs_idisowner (np, id);
- if (err)
- return err;
- }
- return 0;
-}
-
-/* Check to see if the calling user identified by CRED is permitted to
- do operation OP on node NP. OP is one of S_IREAD, S_IWRITE, or S_IEXEC.
- Return 0 if the operation is permitted and EACCES if not. */
-extern inline error_t
-diskfs_access (struct node *np, int op, struct protid *cred)
-{
- struct userid *id;
- error_t err;
-
- assert (cred->id);
- for (id = cred->id; id; id = id->next)
- {
- err = _diskfs_idaccess (np, op, id);
- if (err)
- return err;
- }
- return 0;
-}
-
-/* Check to see if the calling user identified by CRED is allowed to
- modify directory DY with respect to existing file NP. Return zero
- if permitted and an appropriate error if not. */
-extern inline error_t
-diskfs_checkdirmod (struct node *dp, struct node *np, struct protid *cred)
-{
- struct userid *id;
- error_t err;
-
- assert (cred->id);
- for (id = cred->id; id; id = id->next)
- {
- err = _diskfs_idcheckdirmod (dp, np, id);
- if (err)
- return err;
- }
- return 0;
+ return (diskfs_access (dp, S_IWRITE, cred)
+ && (!(dp->dn_stat.st_mode & S_ISVTX) || !np || diskfs_isuid (0,cred)
+ || diskfs_isowner (dp, cred) || diskfs_isowner (np, cred)));
}
/* Reading and writing of files. this is called by other filesystem