1*7867Sroot /* vfs_vnops.c 4.27 82/08/24 */ 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" 1718Sbill 1818Sbill /* 194817Swnj * Openi called to allow handler 2018Sbill * of special files to initialize and 2118Sbill * validate before actual IO. 2218Sbill */ 237654Ssam openi(ip, mode) 244817Swnj register struct inode *ip; 2518Sbill { 2618Sbill dev_t dev; 2718Sbill register unsigned int maj; 2818Sbill 296569Smckusic dev = (dev_t)ip->i_rdev; 3018Sbill maj = major(dev); 314817Swnj switch (ip->i_mode&IFMT) { 3218Sbill 3318Sbill case IFCHR: 344817Swnj if (maj >= nchrdev) 3518Sbill goto bad; 367654Ssam (*cdevsw[maj].d_open)(dev, mode); 3718Sbill break; 3818Sbill 3918Sbill case IFBLK: 404817Swnj if (maj >= nblkdev) 4118Sbill goto bad; 427654Ssam (*bdevsw[maj].d_open)(dev, mode); 4318Sbill } 4418Sbill return; 4518Sbill 4618Sbill bad: 4718Sbill u.u_error = ENXIO; 4818Sbill } 4918Sbill 5018Sbill /* 5118Sbill * Check mode permission on inode pointer. 5218Sbill * Mode is READ, WRITE or EXEC. 5318Sbill * In the case of WRITE, the 5418Sbill * read-only status of the file 5518Sbill * system is checked. 5618Sbill * Also in WRITE, prototype text 5718Sbill * segments cannot be written. 5818Sbill * The mode is shifted to select 5918Sbill * the owner/group/other fields. 6018Sbill * The super user is granted all 6118Sbill * permissions. 6218Sbill */ 6318Sbill access(ip, mode) 644817Swnj register struct inode *ip; 654817Swnj int mode; 6618Sbill { 6718Sbill register m; 68*7867Sroot register int *gp; 6918Sbill 7018Sbill m = mode; 714817Swnj if (m == IWRITE) { 726569Smckusic if (ip->i_fs->fs_ronly != 0) { 7318Sbill u.u_error = EROFS; 744817Swnj return (1); 7518Sbill } 7618Sbill if (ip->i_flag&ITEXT) /* try to free text */ 7718Sbill xrele(ip); 784817Swnj if (ip->i_flag & ITEXT) { 7918Sbill u.u_error = ETXTBSY; 804817Swnj return (1); 8118Sbill } 8218Sbill } 834817Swnj if (u.u_uid == 0) 844817Swnj return (0); 854817Swnj if (u.u_uid != ip->i_uid) { 8618Sbill m >>= 3; 87*7867Sroot for (gp = u.u_groups; gp < &u.u_groups[NGROUPS]; gp++) 88*7867Sroot if (ip->i_gid != *gp) 89*7867Sroot goto found; 90*7867Sroot m >>= 3; 91*7867Sroot found: 92*7867Sroot ; 9318Sbill } 944817Swnj if ((ip->i_mode&m) != 0) 954817Swnj return (0); 9618Sbill u.u_error = EACCES; 974817Swnj return (1); 9818Sbill } 9918Sbill 10018Sbill /* 10118Sbill * Look up a pathname and test if 10218Sbill * the resultant inode is owned by the 10318Sbill * current user. 10418Sbill * If not, try for super-user. 10518Sbill * If permission is granted, 10618Sbill * return inode pointer. 10718Sbill */ 10818Sbill struct inode * 1095990Swnj owner(follow) 1105990Swnj int follow; 11118Sbill { 11218Sbill register struct inode *ip; 11318Sbill 1145990Swnj ip = namei(uchar, 0, follow); 1154817Swnj if (ip == NULL) 1164817Swnj return (NULL); 1174817Swnj if (u.u_uid == ip->i_uid) 1184817Swnj return (ip); 1194817Swnj if (suser()) 1204817Swnj return (ip); 12118Sbill iput(ip); 1224817Swnj return (NULL); 12318Sbill } 12418Sbill 12518Sbill /* 12618Sbill * Test if the current user is the 12718Sbill * super user. 12818Sbill */ 12918Sbill suser() 13018Sbill { 13118Sbill 1324817Swnj if (u.u_uid == 0) { 13318Sbill u.u_acflag |= ASU; 1344817Swnj return (1); 13518Sbill } 13618Sbill u.u_error = EPERM; 1374817Swnj return (0); 13818Sbill } 139