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