xref: /original-bsd/sys/kern/vfs_vnops.c (revision 4b2c5e10)
1 /*	vfs_vnops.c	6.1	83/07/29	*/
2 
3 #include "../machine/reg.h"
4 
5 #include "../h/param.h"
6 #include "../h/systm.h"
7 #include "../h/dir.h"
8 #include "../h/user.h"
9 #include "../h/fs.h"
10 #include "../h/file.h"
11 #include "../h/conf.h"
12 #include "../h/inode.h"
13 #include "../h/acct.h"
14 #include "../h/mount.h"
15 #include "../h/socket.h"
16 #include "../h/socketvar.h"
17 #include "../h/proc.h"
18 #include "../h/nami.h"
19 
20 /*
21  * Check mode permission on inode pointer.
22  * Mode is READ, WRITE or EXEC.
23  * In the case of WRITE, the
24  * read-only status of the file
25  * system is checked.
26  * Also in WRITE, prototype text
27  * segments cannot be written.
28  * The mode is shifted to select
29  * the owner/group/other fields.
30  * The super user is granted all
31  * permissions.
32  */
33 access(ip, mode)
34 	register struct inode *ip;
35 	int mode;
36 {
37 	register m;
38 	register int *gp;
39 
40 	m = mode;
41 	if (m == IWRITE) {
42 		/*
43 		 * Disallow write attempts on read-only
44 		 * file systems; unless the file is a block
45 		 * or character device resident on the
46 		 * file system.
47 		 */
48 		if (ip->i_fs->fs_ronly != 0) {
49 			if ((ip->i_mode & IFMT) != IFCHR &&
50 			    (ip->i_mode & IFMT) != IFBLK) {
51 				u.u_error = EROFS;
52 				return (1);
53 			}
54 		}
55 		/*
56 		 * If there's shared text associated with
57 		 * the inode, try to free it up once.  If
58 		 * we fail, we can't allow writing.
59 		 */
60 		if (ip->i_flag&ITEXT)
61 			xrele(ip);
62 		if (ip->i_flag & ITEXT) {
63 			u.u_error = ETXTBSY;
64 			return (1);
65 		}
66 	}
67 	/*
68 	 * If you're the super-user,
69 	 * you always get access.
70 	 */
71 	if (u.u_uid == 0)
72 		return (0);
73 	/*
74 	 * Access check is based on only
75 	 * one of owner, group, public.
76 	 * If not owner, then check group.
77 	 * If not a member of the group, then
78 	 * check public access.
79 	 */
80 	if (u.u_uid != ip->i_uid) {
81 		m >>= 3;
82 		if (u.u_gid == ip->i_gid)
83 			goto found;
84 		gp = u.u_groups;
85 		for (; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++)
86 			if (ip->i_gid == *gp)
87 				goto found;
88 		m >>= 3;
89 found:
90 		;
91 	}
92 	if ((ip->i_mode&m) != 0)
93 		return (0);
94 	u.u_error = EACCES;
95 	return (1);
96 }
97 
98 /*
99  * Look up a pathname and test if
100  * the resultant inode is owned by the
101  * current user.
102  * If not, try for super-user.
103  * If permission is granted,
104  * return inode pointer.
105  */
106 struct inode *
107 owner(follow)
108 	int follow;
109 {
110 	register struct inode *ip;
111 
112 	ip = namei(uchar, LOOKUP, follow);
113 	if (ip == NULL)
114 		return (NULL);
115 	if (u.u_uid == ip->i_uid)
116 		return (ip);
117 	if (suser())
118 		return (ip);
119 	iput(ip);
120 	return (NULL);
121 }
122 
123 /*
124  * Test if the current user is the
125  * super user.
126  */
127 suser()
128 {
129 
130 	if (u.u_uid == 0) {
131 		u.u_acflag |= ASU;
132 		return (1);
133 	}
134 	u.u_error = EPERM;
135 	return (0);
136 }
137