merge in vnode changes
[unix-history] / usr / src / sys / kern / vfs_vnops.c
CommitLineData
da7c5cc6 1/*
0880b18e 2 * Copyright (c) 1982, 1986 Regents of the University of California.
da7c5cc6
KM
3 * All rights reserved. The Berkeley software License Agreement
4 * specifies the terms and conditions for redistribution.
5 *
849cbd39 6 * @(#)vfs_vnops.c 7.3 (Berkeley) %G%
da7c5cc6 7 */
961945a8 8
94368568
JB
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"
fc96c615 22
d301d150
KM
23#include "machine/reg.h"
24
fc96c615
BJ
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 */
38access(ip, mode)
fdd90ee3
BJ
39 register struct inode *ip;
40 int mode;
fc96c615
BJ
41{
42 register m;
38b6104c 43 register gid_t *gp;
fc96c615
BJ
44
45 m = mode;
fdd90ee3 46 if (m == IWRITE) {
40123f2c
SL
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 */
6459ebe0 53 if (ip->i_fs->fs_ronly != 0) {
77cc8249
BJ
54 if ((ip->i_mode & IFMT) != IFCHR &&
55 (ip->i_mode & IFMT) != IFBLK) {
56 u.u_error = EROFS;
57 return (1);
58 }
fc96c615 59 }
40123f2c
SL
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)
fc96c615 66 xrele(ip);
fdd90ee3 67 if (ip->i_flag & ITEXT) {
fc96c615 68 u.u_error = ETXTBSY;
fdd90ee3 69 return (1);
fc96c615
BJ
70 }
71 }
40123f2c
SL
72 /*
73 * If you're the super-user,
74 * you always get access.
75 */
fdd90ee3
BJ
76 if (u.u_uid == 0)
77 return (0);
40123f2c
SL
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 */
fdd90ee3 85 if (u.u_uid != ip->i_uid) {
fc96c615 86 m >>= 3;
40123f2c
SL
87 if (u.u_gid == ip->i_gid)
88 goto found;
8f3338c3
SL
89 gp = u.u_groups;
90 for (; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++)
4060c051 91 if (ip->i_gid == *gp)
197da11b
BJ
92 goto found;
93 m >>= 3;
94found:
95 ;
fc96c615 96 }
fdd90ee3
BJ
97 if ((ip->i_mode&m) != 0)
98 return (0);
fc96c615 99 u.u_error = EACCES;
fdd90ee3 100 return (1);
fc96c615
BJ
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 */
111struct inode *
715baff1
KM
112owner(fname, follow)
113 caddr_t fname;
5485e062 114 int follow;
fc96c615
BJ
115{
116 register struct inode *ip;
715baff1 117 register struct nameidata *ndp = &u.u_nd;
fc96c615 118
715baff1
KM
119 ndp->ni_nameiop = LOOKUP | follow;
120 ndp->ni_segflg = UIO_USERSPACE;
121 ndp->ni_dirp = fname;
122 ip = namei(ndp);
fdd90ee3
BJ
123 if (ip == NULL)
124 return (NULL);
125 if (u.u_uid == ip->i_uid)
126 return (ip);
849cbd39
KM
127 if (u.u_error = suser(u.u_cred, &u.u_acflag)) {
128 iput(ip);
129 return (NULL);
130 }
131 return (ip);
fc96c615
BJ
132}
133
134/*
849cbd39 135 * Test if the current user is the super user.
fc96c615 136 */
849cbd39
KM
137suser(uid, acflag)
138 uid_t uid;
139 short *acflag;
fc96c615
BJ
140{
141
849cbd39
KM
142 if (uid == 0) {
143 if (acflag)
144 *acflag |= ASU;
145 return (0);
fc96c615 146 }
849cbd39 147 return (EPERM);
fc96c615 148}