Commit | Line | Data |
---|---|---|
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 | */ | |
38 | access(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; | |
94 | found: | |
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 | */ | |
111 | struct inode * | |
715baff1 KM |
112 | owner(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 |
137 | suser(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 | } |