1: /*
   2:  * Copyright (c) 1986 Regents of the University of California.
   3:  * All rights reserved.  The Berkeley software License Agreement
   4:  * specifies the terms and conditions for redistribution.
   5:  *
   6:  *	@(#)ufs_fio.c	1.6 (2.11BSD GTE) 1997/11/28
   7:  */
   8: 
   9: #include "param.h"
  10: #include "user.h"
  11: #include "fs.h"
  12: #include "inode.h"
  13: #include "mount.h"
  14: #include "namei.h"
  15: #include "systm.h"
  16: #include "acct.h"
  17: #include "stat.h"
  18: 
  19: /*
  20:  * Check mode permission on inode pointer.
  21:  * Mode is READ, WRITE or EXEC.
  22:  * In the case of WRITE, the
  23:  * read-only status of the file
  24:  * system is checked.
  25:  * Also in WRITE, prototype text
  26:  * segments cannot be written.
  27:  * The mode is shifted to select
  28:  * the owner/group/other fields.
  29:  * The super user is granted all
  30:  * permissions.
  31:  */
  32: access(ip, mode)
  33:     register struct inode *ip;
  34:     int mode;
  35: {
  36:     register m;
  37:     register gid_t *gp;
  38: 
  39:     m = mode;
  40:     if (m == IWRITE) {
  41:         if (ip->i_flags & IMMUTABLE) {
  42:             u.u_error = EPERM;
  43:             return(1);
  44:         }
  45:         /*
  46: 		 * Disallow write attempts on read-only
  47: 		 * file systems; unless the file is a block
  48: 		 * or character device resident on the
  49: 		 * file system.
  50: 		 */
  51:         if (ip->i_fs->fs_ronly != 0) {
  52:             if ((ip->i_mode & IFMT) != IFCHR &&
  53:                 (ip->i_mode & IFMT) != IFBLK) {
  54:                 u.u_error = EROFS;
  55:                 return (1);
  56:             }
  57:         }
  58:         /*
  59: 		 * If there's shared text associated with
  60: 		 * the inode, try to free it up once.  If
  61: 		 * we fail, we can't allow writing.
  62: 		 */
  63:         if (ip->i_flag&ITEXT)
  64:             xuntext(ip->i_text);
  65:         if (ip->i_flag & ITEXT) {
  66:             u.u_error = ETXTBSY;
  67:             return (1);
  68:         }
  69:     }
  70:     /*
  71: 	 * If you're the super-user,
  72: 	 * you always get access.
  73: 	 */
  74:     if (u.u_uid == 0)
  75:         return (0);
  76:     /*
  77: 	 * Access check is based on only
  78: 	 * one of owner, group, public.
  79: 	 * If not owner, then check group.
  80: 	 * If not a member of the group, then
  81: 	 * check public access.
  82: 	 */
  83:     if (u.u_uid != ip->i_uid) {
  84:         m >>= 3;
  85:         gp = u.u_groups;
  86:         for (; gp < &u.u_groups[NGROUPS] && *gp != NOGROUP; gp++)
  87:             if (ip->i_gid == *gp)
  88:                 goto found;
  89:         m >>= 3;
  90: found:
  91:         ;
  92:     }
  93:     if ((ip->i_mode&m) != 0)
  94:         return (0);
  95:     u.u_error = EACCES;
  96:     return (1);
  97: }
  98: 
  99: /* copied, for supervisory networking, to sys_net.c */
 100: /*
 101:  * Test if the current user is the
 102:  * super user.
 103:  */
 104: suser()
 105: {
 106: 
 107:     if (u.u_uid == 0) {
 108:         u.u_acflag |= ASU;
 109:         return (1);
 110:     }
 111:     u.u_error = EPERM;
 112:     return (0);
 113: }
 114: 
 115: /*
 116:  * Set the attributes on a file.  This was placed here because ufs_syscalls
 117:  * is too large already (it will probably be split into two files eventually).
 118: */
 119: 
 120: ufs_setattr(ip, vap)
 121:     register struct inode *ip;
 122:     register struct vattr *vap;
 123:     {
 124:     int error;
 125:     struct  timeval atimeval, mtimeval;
 126: 
 127:     if  (ip->i_fs->fs_ronly)    /* can't change anything on a RO fs */
 128:         return(EROFS);
 129:     if  (vap->va_flags != VNOVAL)
 130:         {
 131:         if  (u.u_uid != ip->i_uid && !suser())
 132:             return(u.u_error);
 133:         if  (u.u_uid == 0)
 134:             {
 135:             if  ((ip->i_flags & (SF_IMMUTABLE|SF_APPEND)) &&
 136:                     securelevel > 0)
 137:                 return(EPERM);
 138:             ip->i_flags = vap->va_flags;
 139:             }
 140:         else
 141:             {
 142:             if  (ip->i_flags & (SF_IMMUTABLE|SF_APPEND))
 143:                 return(EPERM);
 144:             ip->i_flags &= SF_SETTABLE;
 145:             ip->i_flags |= (vap->va_flags & UF_SETTABLE);
 146:             }
 147:         ip->i_flag |= ICHG;
 148:         if  (vap->va_flags & (IMMUTABLE|APPEND))
 149:             return(0);
 150:         }
 151:     if  (ip->i_flags & (IMMUTABLE|APPEND))
 152:         return(EPERM);
 153: /*
 154:  * Go thru the fields (other than 'flags') and update iff not VNOVAL.
 155: */
 156:     if  (vap->va_uid != (uid_t)VNOVAL || vap->va_gid != (gid_t)VNOVAL)
 157:         if  (error = chown1(ip, vap->va_uid, vap->va_gid))
 158:             return(error);
 159:     if  (vap->va_size != (off_t)VNOVAL)
 160:         {
 161:         if  ((ip->i_mode & IFMT) == IFDIR)
 162:             return(EISDIR);
 163:         itrunc(ip, vap->va_size, 0);
 164:         if  (u.u_error)
 165:             return(u.u_error);
 166:         }
 167:     if  (vap->va_atime != (time_t)VNOVAL ||
 168:          vap->va_mtime != (time_t)VNOVAL)
 169:         {
 170:         if  (u.u_uid != ip->i_uid && !suser() &&
 171:              ((vap->va_vaflags & VA_UTIMES_NULL) == 0 ||
 172:              access(ip, IWRITE)))
 173:             return(u.u_error);
 174:         if  (vap->va_atime != (time_t)VNOVAL &&
 175:                 !(ip->i_fs->fs_flags & MNT_NOATIME))
 176:             ip->i_flag |= IACC;
 177:         if  (vap->va_mtime != (time_t)VNOVAL)
 178:             ip->i_flag |= (IUPD|ICHG);
 179:         atimeval.tv_sec = vap->va_atime;
 180:         mtimeval.tv_sec = vap->va_mtime;
 181:         iupdat(ip, &atimeval, &mtimeval, 1);
 182:         }
 183:     if  (vap->va_mode != (mode_t)VNOVAL)
 184:         return(chmod1(ip, vap->va_mode));
 185:     return(0);
 186:     }
 187: 
 188: ufs_mountedon(dev)
 189:     dev_t dev;
 190:     {
 191:     register struct mount *mp;
 192: 
 193:     for (mp = mount; mp < &mount[NMOUNT]; mp++)
 194:         {
 195:         if  (mp->m_inodp == NULL)
 196:             continue;
 197:         if  (mp->m_dev == dev)
 198:             return(EBUSY);
 199:         }
 200:     return(0);
 201:     }

Defined functions

ufs_mountedon defined in line 188; used 2 times
Last modified: 1997-11-29
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3480
Valid CSS Valid XHTML 1.0 Strict