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