mkfs: drop support for running on DOS
[minix.git] / servers / ext2 / protect.c
blobc7dd839cce0272b6599c0034c0b744edb64a5888
1 /* Created (MFS based):
2 * February 2010 (Evgeniy Ivanov)
3 */
5 #include "fs.h"
6 #include "inode.h"
7 #include "super.h"
8 #include <minix/vfsif.h>
10 static int in_group(gid_t grp);
13 /*===========================================================================*
14 * fs_chmod *
15 *===========================================================================*/
16 int fs_chmod()
18 /* Perform the chmod(name, mode) system call. */
20 register struct inode *rip;
21 mode_t mode;
23 mode = (mode_t) fs_m_in.REQ_MODE;
25 /* Temporarily open the file. */
26 if( (rip = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
27 return(EINVAL);
29 /* Now make the change. Clear setgid bit if file is not in caller's grp */
30 rip->i_mode = (rip->i_mode & ~ALL_MODES) | (mode & ALL_MODES);
31 rip->i_update |= CTIME;
32 rip->i_dirt = IN_DIRTY;
34 /* Return full new mode to caller. */
35 fs_m_out.RES_MODE = rip->i_mode;
37 put_inode(rip);
38 return(OK);
42 /*===========================================================================*
43 * fs_chown *
44 *===========================================================================*/
45 int fs_chown()
47 register struct inode *rip;
48 register int r;
50 /* Temporarily open the file. */
51 if( (rip = get_inode(fs_dev, (ino_t) fs_m_in.REQ_INODE_NR)) == NULL)
52 return(EINVAL);
54 /* Not permitted to change the owner of a file on a read-only file sys. */
55 r = read_only(rip);
56 if (r == OK) {
57 rip->i_uid = fs_m_in.REQ_UID;
58 rip->i_gid = fs_m_in.REQ_GID;
59 rip->i_mode &= ~(I_SET_UID_BIT | I_SET_GID_BIT);
60 rip->i_update |= CTIME;
61 rip->i_dirt = IN_DIRTY;
64 /* Update caller on current mode, as it may have changed. */
65 fs_m_out.RES_MODE = rip->i_mode;
66 put_inode(rip);
68 return(r);
72 /*===========================================================================*
73 * forbidden *
74 *===========================================================================*/
75 int forbidden(register struct inode *rip, mode_t access_desired)
77 /* Given a pointer to an inode, 'rip', and the access desired, determine
78 * if the access is allowed, and if not why not. The routine looks up the
79 * caller's uid in the 'fproc' table. If access is allowed, OK is returned
80 * if it is forbidden, EACCES is returned.
83 register struct inode *old_rip = rip;
84 register mode_t bits, perm_bits;
85 int r, shift;
87 /* Isolate the relevant rwx bits from the mode. */
88 bits = rip->i_mode;
89 if (caller_uid == SU_UID) {
90 /* Grant read and write permission. Grant search permission for
91 * directories. Grant execute permission (for non-directories) if
92 * and only if one of the 'X' bits is set.
94 if ( (bits & I_TYPE) == I_DIRECTORY ||
95 bits & ((X_BIT << 6) | (X_BIT << 3) | X_BIT))
96 perm_bits = R_BIT | W_BIT | X_BIT;
97 else
98 perm_bits = R_BIT | W_BIT;
99 } else {
100 if (caller_uid == rip->i_uid) shift = 6; /* owner */
101 else if (caller_gid == rip->i_gid) shift = 3; /* group */
102 else if (in_group(rip->i_gid) == OK) shift = 3; /* other groups */
103 else shift = 0; /* other */
104 perm_bits = (bits >> shift) & (R_BIT | W_BIT | X_BIT);
107 /* If access desired is not a subset of what is allowed, it is refused. */
108 r = OK;
109 if ((perm_bits | access_desired) != perm_bits) r = EACCES;
111 /* Check to see if someone is trying to write on a file system that is
112 * mounted read-only.
114 if (r == OK) {
115 if (access_desired & W_BIT) {
116 r = read_only(rip);
120 if (rip != old_rip) put_inode(rip);
122 return(r);
126 /*===========================================================================*
127 * in_group *
128 *===========================================================================*/
129 static int in_group(gid_t grp)
131 int i;
133 if (credentials.vu_ngroups > NGROUPS_MAX)
134 return(EINVAL);
136 for (i = 0; i < credentials.vu_ngroups; i++)
137 if (credentials.vu_sgroups[i] == grp)
138 return(OK);
140 return(EINVAL);
144 /*===========================================================================*
145 * read_only *
146 *===========================================================================*/
147 int read_only(ip)
148 struct inode *ip; /* ptr to inode whose file sys is to be cked */
150 /* Check to see if the file system on which the inode 'ip' resides is mounted
151 * read only. If so, return EROFS, else return OK.
154 register struct super_block *sp;
156 sp = ip->i_sp;
157 return(sp->s_rd_only ? EROFS : OK);