1*9165Ssam /* vfs_vnops.c 4.30 82/11/13 */ 218Sbill 318Sbill #include "../h/param.h" 418Sbill #include "../h/systm.h" 518Sbill #include "../h/dir.h" 618Sbill #include "../h/user.h" 76569Smckusic #include "../h/fs.h" 818Sbill #include "../h/file.h" 918Sbill #include "../h/conf.h" 1018Sbill #include "../h/inode.h" 1118Sbill #include "../h/reg.h" 1218Sbill #include "../h/acct.h" 132302Skre #include "../h/mount.h" 144914Swnj #include "../h/socket.h" 154914Swnj #include "../h/socketvar.h" 165581Swnj #include "../h/proc.h" 17*9165Ssam #include "../h/nami.h" 1818Sbill 1918Sbill /* 204817Swnj * Openi called to allow handler 2118Sbill * of special files to initialize and 2218Sbill * validate before actual IO. 2318Sbill */ 247654Ssam openi(ip, mode) 254817Swnj register struct inode *ip; 2618Sbill { 278565Sroot dev_t dev = (dev_t)ip->i_rdev; 288565Sroot register u_int maj = major(dev); 2918Sbill 304817Swnj switch (ip->i_mode&IFMT) { 3118Sbill 3218Sbill case IFCHR: 334817Swnj if (maj >= nchrdev) 348565Sroot return (ENXIO); 358565Sroot return ((*cdevsw[maj].d_open)(dev, mode)); 3618Sbill 3718Sbill case IFBLK: 384817Swnj if (maj >= nblkdev) 398565Sroot return (ENXIO); 408565Sroot return ((*bdevsw[maj].d_open)(dev, mode)); 4118Sbill } 428565Sroot return (0); 4318Sbill } 4418Sbill 4518Sbill /* 4618Sbill * Check mode permission on inode pointer. 4718Sbill * Mode is READ, WRITE or EXEC. 4818Sbill * In the case of WRITE, the 4918Sbill * read-only status of the file 5018Sbill * system is checked. 5118Sbill * Also in WRITE, prototype text 5218Sbill * segments cannot be written. 5318Sbill * The mode is shifted to select 5418Sbill * the owner/group/other fields. 5518Sbill * The super user is granted all 5618Sbill * permissions. 5718Sbill */ 5818Sbill access(ip, mode) 594817Swnj register struct inode *ip; 604817Swnj int mode; 6118Sbill { 6218Sbill register m; 637867Sroot register int *gp; 6418Sbill 6518Sbill m = mode; 664817Swnj if (m == IWRITE) { 676569Smckusic if (ip->i_fs->fs_ronly != 0) { 688956Sroot if ((ip->i_mode & IFMT) != IFCHR && 698956Sroot (ip->i_mode & IFMT) != IFBLK) { 708956Sroot u.u_error = EROFS; 718956Sroot return (1); 728956Sroot } 7318Sbill } 7418Sbill if (ip->i_flag&ITEXT) /* try to free text */ 7518Sbill xrele(ip); 764817Swnj if (ip->i_flag & ITEXT) { 7718Sbill u.u_error = ETXTBSY; 784817Swnj return (1); 7918Sbill } 8018Sbill } 814817Swnj if (u.u_uid == 0) 824817Swnj return (0); 834817Swnj if (u.u_uid != ip->i_uid) { 8418Sbill m >>= 3; 857867Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 867867Sroot if (ip->i_gid != *gp) 877867Sroot goto found; 887867Sroot m >>= 3; 897867Sroot found: 907867Sroot ; 9118Sbill } 924817Swnj if ((ip->i_mode&m) != 0) 934817Swnj return (0); 9418Sbill u.u_error = EACCES; 954817Swnj return (1); 9618Sbill } 9718Sbill 9818Sbill /* 9918Sbill * Look up a pathname and test if 10018Sbill * the resultant inode is owned by the 10118Sbill * current user. 10218Sbill * If not, try for super-user. 10318Sbill * If permission is granted, 10418Sbill * return inode pointer. 10518Sbill */ 10618Sbill struct inode * 1075990Swnj owner(follow) 1085990Swnj int follow; 10918Sbill { 11018Sbill register struct inode *ip; 11118Sbill 112*9165Ssam ip = namei(uchar, LOOKUP, follow); 1134817Swnj if (ip == NULL) 1144817Swnj return (NULL); 1154817Swnj if (u.u_uid == ip->i_uid) 1164817Swnj return (ip); 1174817Swnj if (suser()) 1184817Swnj return (ip); 11918Sbill iput(ip); 1204817Swnj return (NULL); 12118Sbill } 12218Sbill 12318Sbill /* 12418Sbill * Test if the current user is the 12518Sbill * super user. 12618Sbill */ 12718Sbill suser() 12818Sbill { 12918Sbill 1304817Swnj if (u.u_uid == 0) { 13118Sbill u.u_acflag |= ASU; 1324817Swnj return (1); 13318Sbill } 13418Sbill u.u_error = EPERM; 1354817Swnj return (0); 13618Sbill } 137