1 /* fio.c 4.25 82/07/17 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/dir.h" 6 #include "../h/user.h" 7 #include "../h/fs.h" 8 #include "../h/file.h" 9 #include "../h/conf.h" 10 #include "../h/inode.h" 11 #include "../h/reg.h" 12 #include "../h/acct.h" 13 #include "../h/mount.h" 14 #include "../h/socket.h" 15 #include "../h/socketvar.h" 16 #include "../h/proc.h" 17 #ifdef EFS 18 #include "../net/in.h" 19 #include "../h/efs.h" 20 #endif 21 22 /* 23 * Openi called to allow handler 24 * of special files to initialize and 25 * validate before actual IO. 26 */ 27 #ifdef EFS 28 openi(ip, rw, trf) 29 #else 30 openi(ip, rw) 31 #endif 32 register struct inode *ip; 33 { 34 dev_t dev; 35 register unsigned int maj; 36 37 dev = (dev_t)ip->i_rdev; 38 maj = major(dev); 39 switch (ip->i_mode&IFMT) { 40 41 case IFCHR: 42 if (maj >= nchrdev) 43 goto bad; 44 #ifdef EFS 45 (*cdevsw[maj].d_open)(dev, rw, trf); 46 #else 47 (*cdevsw[maj].d_open)(dev, rw); 48 #endif 49 break; 50 51 case IFBLK: 52 if (maj >= nblkdev) 53 goto bad; 54 (*bdevsw[maj].d_open)(dev, rw); 55 } 56 return; 57 58 bad: 59 u.u_error = ENXIO; 60 } 61 62 /* 63 * Check mode permission on inode pointer. 64 * Mode is READ, WRITE or EXEC. 65 * In the case of WRITE, the 66 * read-only status of the file 67 * system is checked. 68 * Also in WRITE, prototype text 69 * segments cannot be written. 70 * The mode is shifted to select 71 * the owner/group/other fields. 72 * The super user is granted all 73 * permissions. 74 */ 75 access(ip, mode) 76 register struct inode *ip; 77 int mode; 78 { 79 register m; 80 81 m = mode; 82 if (m == IWRITE) { 83 if (ip->i_fs->fs_ronly != 0) { 84 u.u_error = EROFS; 85 return (1); 86 } 87 if (ip->i_flag&ITEXT) /* try to free text */ 88 xrele(ip); 89 if (ip->i_flag & ITEXT) { 90 u.u_error = ETXTBSY; 91 return (1); 92 } 93 } 94 if (u.u_uid == 0) 95 return (0); 96 if (u.u_uid != ip->i_uid) { 97 m >>= 3; 98 if (ip->i_gid >= NGRPS || 99 (u.u_grps[ip->i_gid/(sizeof(int)*8)] & 100 (1 << ip->i_gid%(sizeof(int)*8)) == 0)) 101 m >>= 3; 102 } 103 if ((ip->i_mode&m) != 0) 104 return (0); 105 u.u_error = EACCES; 106 return (1); 107 } 108 109 /* 110 * Look up a pathname and test if 111 * the resultant inode is owned by the 112 * current user. 113 * If not, try for super-user. 114 * If permission is granted, 115 * return inode pointer. 116 */ 117 struct inode * 118 owner(follow) 119 int follow; 120 { 121 register struct inode *ip; 122 123 ip = namei(uchar, 0, follow); 124 if (ip == NULL) 125 return (NULL); 126 #ifdef EFS 127 /* 128 * References to extended file system are 129 * returned to the caller. 130 */ 131 if (efsinode(ip)) 132 return (ip); 133 #endif 134 if (u.u_uid == ip->i_uid) 135 return (ip); 136 if (suser()) 137 return (ip); 138 iput(ip); 139 return (NULL); 140 } 141 142 /* 143 * Test if the current user is the 144 * super user. 145 */ 146 suser() 147 { 148 149 if (u.u_uid == 0) { 150 u.u_acflag |= ASU; 151 return (1); 152 } 153 u.u_error = EPERM; 154 return (0); 155 } 156