1*11162Ssam /* vfs_vnops.c 4.33 83/02/20 */ 218Sbill 39764Ssam #include "../machine/reg.h" 49764Ssam 518Sbill #include "../h/param.h" 618Sbill #include "../h/systm.h" 718Sbill #include "../h/dir.h" 818Sbill #include "../h/user.h" 96569Smckusic #include "../h/fs.h" 1018Sbill #include "../h/file.h" 1118Sbill #include "../h/conf.h" 1218Sbill #include "../h/inode.h" 1318Sbill #include "../h/acct.h" 142302Skre #include "../h/mount.h" 154914Swnj #include "../h/socket.h" 164914Swnj #include "../h/socketvar.h" 175581Swnj #include "../h/proc.h" 189165Ssam #include "../h/nami.h" 1918Sbill 2018Sbill /* 214817Swnj * Openi called to allow handler 2218Sbill * of special files to initialize and 2318Sbill * validate before actual IO. 2418Sbill */ 257654Ssam openi(ip, mode) 264817Swnj register struct inode *ip; 2718Sbill { 288565Sroot dev_t dev = (dev_t)ip->i_rdev; 298565Sroot register u_int maj = major(dev); 3018Sbill 314817Swnj switch (ip->i_mode&IFMT) { 3218Sbill 3318Sbill case IFCHR: 344817Swnj if (maj >= nchrdev) 358565Sroot return (ENXIO); 368565Sroot return ((*cdevsw[maj].d_open)(dev, mode)); 3718Sbill 3818Sbill case IFBLK: 394817Swnj if (maj >= nblkdev) 408565Sroot return (ENXIO); 418565Sroot return ((*bdevsw[maj].d_open)(dev, mode)); 4218Sbill } 438565Sroot return (0); 4418Sbill } 4518Sbill 4618Sbill /* 4718Sbill * Check mode permission on inode pointer. 4818Sbill * Mode is READ, WRITE or EXEC. 4918Sbill * In the case of WRITE, the 5018Sbill * read-only status of the file 5118Sbill * system is checked. 5218Sbill * Also in WRITE, prototype text 5318Sbill * segments cannot be written. 5418Sbill * The mode is shifted to select 5518Sbill * the owner/group/other fields. 5618Sbill * The super user is granted all 5718Sbill * permissions. 5818Sbill */ 5918Sbill access(ip, mode) 604817Swnj register struct inode *ip; 614817Swnj int mode; 6218Sbill { 6318Sbill register m; 647867Sroot register int *gp; 6518Sbill 6618Sbill m = mode; 674817Swnj if (m == IWRITE) { 68*11162Ssam /* 69*11162Ssam * Disallow write attempts on read-only 70*11162Ssam * file systems; unless the file is a block 71*11162Ssam * or character device resident on the 72*11162Ssam * file system. 73*11162Ssam */ 746569Smckusic if (ip->i_fs->fs_ronly != 0) { 758956Sroot if ((ip->i_mode & IFMT) != IFCHR && 768956Sroot (ip->i_mode & IFMT) != IFBLK) { 778956Sroot u.u_error = EROFS; 788956Sroot return (1); 798956Sroot } 8018Sbill } 81*11162Ssam /* 82*11162Ssam * If there's shared text associated with 83*11162Ssam * the inode, try to free it up once. If 84*11162Ssam * we fail, we can't allow writing. 85*11162Ssam */ 86*11162Ssam if (ip->i_flag&ITEXT) 8718Sbill xrele(ip); 884817Swnj if (ip->i_flag & ITEXT) { 8918Sbill u.u_error = ETXTBSY; 904817Swnj return (1); 9118Sbill } 9218Sbill } 93*11162Ssam /* 94*11162Ssam * If you're the super-user, 95*11162Ssam * you always get access. 96*11162Ssam */ 974817Swnj if (u.u_uid == 0) 984817Swnj return (0); 99*11162Ssam /* 100*11162Ssam * Access check is based on only 101*11162Ssam * one of owner, group, public. 102*11162Ssam * If not owner, then check group. 103*11162Ssam * If not a member of the group, then 104*11162Ssam * check public access. 105*11162Ssam */ 1064817Swnj if (u.u_uid != ip->i_uid) { 10718Sbill m >>= 3; 108*11162Ssam if (u.u_gid == ip->i_gid) 109*11162Ssam goto found; 1107867Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 11110044Ssam if (ip->i_gid == *gp) 1127867Sroot goto found; 1137867Sroot m >>= 3; 1147867Sroot found: 1157867Sroot ; 11618Sbill } 1174817Swnj if ((ip->i_mode&m) != 0) 1184817Swnj return (0); 11918Sbill u.u_error = EACCES; 1204817Swnj return (1); 12118Sbill } 12218Sbill 12318Sbill /* 12418Sbill * Look up a pathname and test if 12518Sbill * the resultant inode is owned by the 12618Sbill * current user. 12718Sbill * If not, try for super-user. 12818Sbill * If permission is granted, 12918Sbill * return inode pointer. 13018Sbill */ 13118Sbill struct inode * 1325990Swnj owner(follow) 1335990Swnj int follow; 13418Sbill { 13518Sbill register struct inode *ip; 13618Sbill 1379165Ssam ip = namei(uchar, LOOKUP, follow); 1384817Swnj if (ip == NULL) 1394817Swnj return (NULL); 1404817Swnj if (u.u_uid == ip->i_uid) 1414817Swnj return (ip); 1424817Swnj if (suser()) 1434817Swnj return (ip); 14418Sbill iput(ip); 1454817Swnj return (NULL); 14618Sbill } 14718Sbill 14818Sbill /* 14918Sbill * Test if the current user is the 15018Sbill * super user. 15118Sbill */ 15218Sbill suser() 15318Sbill { 15418Sbill 1554817Swnj if (u.u_uid == 0) { 15618Sbill u.u_acflag |= ASU; 1574817Swnj return (1); 15818Sbill } 15918Sbill u.u_error = EPERM; 1604817Swnj return (0); 16118Sbill } 162