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