rework `namei' interface to eliminate global variables
[unix-history] / usr / src / sys / kern / vfs_vnops.c
CommitLineData
715baff1 1/* vfs_vnops.c 6.2 84/07/08 */
961945a8
SL
2
3#include "../machine/reg.h"
fc96c615
BJ
4
5#include "../h/param.h"
6#include "../h/systm.h"
7#include "../h/dir.h"
8#include "../h/user.h"
6459ebe0 9#include "../h/fs.h"
fc96c615
BJ
10#include "../h/file.h"
11#include "../h/conf.h"
12#include "../h/inode.h"
fc96c615 13#include "../h/acct.h"
f5b8937b 14#include "../h/mount.h"
ae921915
BJ
15#include "../h/socket.h"
16#include "../h/socketvar.h"
f3156a73 17#include "../h/proc.h"
fc96c615 18
fc96c615
BJ
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 */
32access(ip, mode)
fdd90ee3
BJ
33 register struct inode *ip;
34 int mode;
fc96c615
BJ
35{
36 register m;
197da11b 37 register int *gp;
fc96c615
BJ
38
39 m = mode;
fdd90ee3 40 if (m == IWRITE) {
40123f2c
SL
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 */
6459ebe0 47 if (ip->i_fs->fs_ronly != 0) {
77cc8249
BJ
48 if ((ip->i_mode & IFMT) != IFCHR &&
49 (ip->i_mode & IFMT) != IFBLK) {
50 u.u_error = EROFS;
51 return (1);
52 }
fc96c615 53 }
40123f2c
SL
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)
fc96c615 60 xrele(ip);
fdd90ee3 61 if (ip->i_flag & ITEXT) {
fc96c615 62 u.u_error = ETXTBSY;
fdd90ee3 63 return (1);
fc96c615
BJ
64 }
65 }
40123f2c
SL
66 /*
67 * If you're the super-user,
68 * you always get access.
69 */
fdd90ee3
BJ
70 if (u.u_uid == 0)
71 return (0);
40123f2c
SL
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 */
fdd90ee3 79 if (u.u_uid != ip->i_uid) {
fc96c615 80 m >>= 3;
40123f2c
SL
81 if (u.u_gid == ip->i_gid)
82 goto found;
8f3338c3
SL
83 gp = u.u_groups;
84 for (; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++)
4060c051 85 if (ip->i_gid == *gp)
197da11b
BJ
86 goto found;
87 m >>= 3;
88found:
89 ;
fc96c615 90 }
fdd90ee3
BJ
91 if ((ip->i_mode&m) != 0)
92 return (0);
fc96c615 93 u.u_error = EACCES;
fdd90ee3 94 return (1);
fc96c615
BJ
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 */
105struct inode *
715baff1
KM
106owner(fname, follow)
107 caddr_t fname;
5485e062 108 int follow;
fc96c615
BJ
109{
110 register struct inode *ip;
715baff1 111 register struct nameidata *ndp = &u.u_nd;
fc96c615 112
715baff1
KM
113 ndp->ni_nameiop = LOOKUP | follow;
114 ndp->ni_segflg = UIO_USERSPACE;
115 ndp->ni_dirp = fname;
116 ip = namei(ndp);
fdd90ee3
BJ
117 if (ip == NULL)
118 return (NULL);
119 if (u.u_uid == ip->i_uid)
120 return (ip);
121 if (suser())
122 return (ip);
fc96c615 123 iput(ip);
fdd90ee3 124 return (NULL);
fc96c615
BJ
125}
126
127/*
128 * Test if the current user is the
129 * super user.
130 */
131suser()
132{
133
fdd90ee3 134 if (u.u_uid == 0) {
fc96c615 135 u.u_acflag |= ASU;
fdd90ee3 136 return (1);
fc96c615
BJ
137 }
138 u.u_error = EPERM;
fdd90ee3 139 return (0);
fc96c615 140}