1 /* This file deals with protection in the file system. It contains the code
2 * for four system calls that relate to protection.
3 *
4 * The entry points into this file are
5 * do_chmod: perform the CHMOD system call
6 * do_chown: perform the CHOWN system call
7 * do_umask: perform the UMASK system call
8 * do_access: perform the ACCESS system call
9 * forbidden: check to see if a given access is allowed on a given inode
10 */
11
12 #include "fs.h"
13 #include <unistd.h>
14 #include <minix/callnr.h>
15 #include "buf.h"
16 #include "file.h"
17 #include "fproc.h"
18 #include "inode.h"
19 #include "param.h"
20 #include "super.h"
21
22 /*===========================================================================*
23 * do_chmod *
24 *===========================================================================*/
25 PUBLIC int do_chmod()
26 {
27 /* Perform the chmod(name, mode) system call. */
28
29 register struct inode *rip;
30 register int r;
31
32 /* Temporarily open the file. */
33 if (fetch_name(name, name_length, M3) != OK) return(err_code);
34 if ( (rip = eat_path(user_path)) == NIL_INODE) return(err_code);
35
36 /* Only the owner or the super_user may change the mode of a file.
37 * No one may change the mode of a file on a read-only file system.
38 */
39 if (rip->i_uid != fp->fp_effuid && !super_user)
40 r = EPERM;
41 else
42 r = read_only(rip);
43
44 /* If error, return inode. */
45 if (r != OK) {
46 put_inode(rip);
47 return(r);
48 }
49
50 /* Now make the change. Clear setgid bit if file is not in caller's grp */
51 rip->i_mode = (rip->i_mode & ~ALL_MODES) | (mode & ALL_MODES);
52 if (!super_user && rip->i_gid != fp->fp_effgid)rip->i_mode &= ~I_SET_GID_BIT;
53 rip->i_update |= CTIME;
54 rip->i_dirt = DIRTY;
55
56 put_inode(rip);
57 return(OK);
58 }
59
60
61 /*===========================================================================*
62 * do_chown *
63 *===========================================================================*/
64 PUBLIC int do_chown()
65 {
66 /* Perform the chown(name, owner, group) system call. */
67
68 register struct inode *rip;
69 register int r;
70
71 /* Temporarily open the file. */
72 if (fetch_name(name1, name1_length, M1) != OK) return(err_code);
73 if ( (rip = eat_path(user_path)) == NIL_INODE) return(err_code);
74
75 /* Not permitted to change the owner of a file on a read-only file sys. */
76 r = read_only(rip);
77 if (r == OK) {
78 /* FS is R/W. Whether call is allowed depends on ownership, etc. */
79 if (super_user) {
80 /* The super user can do anything. */
81 rip->i_uid = owner; /* others later */
82 } else {
83 /* Regular users can only change groups of their own files. */
84 if (rip->i_uid != fp->fp_effuid) r = EPERM;
85 if (rip->i_uid != owner) r = EPERM; /* no giving away */
86 if (fp->fp_effgid != group) r = EPERM;
87 }
88 }
89 if (r == OK) {
90 rip->i_gid = group;
91 rip->i_mode &= ~(I_SET_UID_BIT | I_SET_GID_BIT);
92 rip->i_update |= CTIME;
93 rip->i_dirt = DIRTY;
94 }
95
96 put_inode(rip);
97 return(r);
98 }
99
100
101 /*===========================================================================*
102 * do_umask *
103 *===========================================================================*/
104 PUBLIC int do_umask()
105 {
106 /* Perform the umask(co_mode) system call. */
107 register mode_t r;
108
109 r = ~fp->fp_umask; /* set 'r' to complement of old mask */
110 fp->fp_umask = ~(co_mode & RWX_MODES);
111 return(r); /* return complement of old mask */
112 }
113
114
115 /*===========================================================================*
116 * do_access *
117 *===========================================================================*/
118 PUBLIC int do_access()
119 {
120 /* Perform the access(name, mode) system call. */
121
122 struct inode *rip;
123 register int r;
124
125 /* First check to see if the mode is correct. */
126 if ( (mode & ~(R_OK | W_OK | X_OK)) != 0 && mode != F_OK)
127 return(EINVAL);
128
129 /* Temporarily open the file whose access is to be checked. */
130 if (fetch_name(name, name_length, M3) != OK) return(err_code);
131 if ( (rip = eat_path(user_path)) == NIL_INODE) return(err_code);
132
133 /* Now check the permissions. */
134 r = forbidden(rip, (mode_t) mode);
135 put_inode(rip);
136 return(r);
137 }
138
139
140 /*===========================================================================*
141 * forbidden *
142 *===========================================================================*/
143 PUBLIC int forbidden(rip, access_desired)
144 register struct inode *rip; /* pointer to inode to be checked */
145 mode_t access_desired; /* RWX bits */
146 {
147 /* Given a pointer to an inode, 'rip', and the access desired, determine
148 * if the access is allowed, and if not why not. The routine looks up the
149 * caller's uid in the 'fproc' table. If access is allowed, OK is returned
150 * if it is forbidden, EACCES is returned.
151 */
152
153 register struct inode *old_rip = rip;
154 register struct super_block *sp;
155 register mode_t bits, perm_bits;
156 int r, shift, test_uid, test_gid;
157
158 if (rip->i_mount == I_MOUNT) /* The inode is mounted on. */
159 for (sp = &super_block[1]; sp < &super_block[NR_SUPERS]; sp++)
160 if (sp->s_imount == rip) {
161 rip = get_inode(sp->s_dev, ROOT_INODE);
162 break;
163 } /* if */
164
165 /* Isolate the relevant rwx bits from the mode. */
166 bits = rip->i_mode;
167 test_uid = (fs_call == ACCESS ? fp->fp_realuid : fp->fp_effuid);
168 test_gid = (fs_call == ACCESS ? fp->fp_realgid : fp->fp_effgid);
169 if (test_uid == SU_UID) {
170 /* Grant read and write permission. Grant search permission for
171 * directories. Grant execute permission (for non-directories) if
172 * and only if one of the 'X' bits is set.
173 */
174 if ( (bits & I_TYPE) == I_DIRECTORY ||
175 bits & ((X_BIT << 6) | (X_BIT << 3) | X_BIT))
176 perm_bits = R_BIT | W_BIT | X_BIT;
177 else
178 perm_bits = R_BIT | W_BIT;
179 } else {
180 if (test_uid == rip->i_uid) shift = 6; /* owner */
181 else if (test_gid == rip->i_gid ) shift = 3; /* group */
182 else shift = 0; /* other */
183 perm_bits = (bits >> shift) & (R_BIT | W_BIT | X_BIT);
184 }
185
186 /* If access desired is not a subset of what is allowed, it is refused. */
187 r = OK;
188 if ((perm_bits | access_desired) != perm_bits) r = EACCES;
189
190 /* Check to see if someone is trying to write on a file system that is
191 * mounted read-only.
192 */
193 if (r == OK)
194 if (access_desired & W_BIT) r = read_only(rip);
195
196 if (rip != old_rip) put_inode(rip);
197
198 return(r);
199 }
200
201
202 /*===========================================================================*
203 * read_only *
204 *===========================================================================*/
205 PUBLIC int read_only(ip)
206 struct inode *ip; /* ptr to inode whose file sys is to be cked */
207 {
208 /* Check to see if the file system on which the inode 'ip' resides is mounted
209 * read only. If so, return EROFS, else return OK.
210 */
211
212 register struct super_block *sp;
213
214 sp = ip->i_sp;
215 return(sp->s_rd_only ? EROFS : OK);
216 }
217
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.