4 #include <minix/vfsif.h>
6 static int in_group(gid_t grp
);
9 /*===========================================================================*
11 *===========================================================================*/
14 /* Perform the chmod(name, mode) system call. */
16 register struct inode
*rip
;
19 mode
= (mode_t
) fs_m_in
.REQ_MODE
;
21 /* Temporarily open the file. */
22 if( (rip
= get_inode(fs_dev
, (ino_t
) fs_m_in
.REQ_INODE_NR
)) == NULL
)
25 if(rip
->i_sp
->s_rd_only
) {
30 /* Now make the change. Clear setgid bit if file is not in caller's grp */
31 rip
->i_mode
= (rip
->i_mode
& ~ALL_MODES
) | (mode
& ALL_MODES
);
32 rip
->i_update
|= CTIME
;
35 /* Return full new mode to caller. */
36 fs_m_out
.RES_MODE
= rip
->i_mode
;
43 /*===========================================================================*
45 *===========================================================================*/
48 register struct inode
*rip
;
51 /* Temporarily open the file. */
52 if( (rip
= get_inode(fs_dev
, (ino_t
) fs_m_in
.REQ_INODE_NR
)) == NULL
)
55 /* Not permitted to change the owner of a file on a read-only file sys. */
58 rip
->i_uid
= (uid_t
) fs_m_in
.REQ_UID
;
59 rip
->i_gid
= (gid_t
) fs_m_in
.REQ_GID
;
60 rip
->i_mode
&= ~(I_SET_UID_BIT
| I_SET_GID_BIT
);
61 rip
->i_update
|= CTIME
;
65 /* Update caller on current mode, as it may have changed. */
66 fs_m_out
.RES_MODE
= rip
->i_mode
;
73 /*===========================================================================*
75 *===========================================================================*/
76 int forbidden(register struct inode
*rip
, mode_t access_desired
)
78 /* Given a pointer to an inode, 'rip', and the access desired, determine
79 * if the access is allowed, and if not why not. The routine looks up the
80 * caller's uid in the 'fproc' table. If access is allowed, OK is returned
81 * if it is forbidden, EACCES is returned.
84 register struct inode
*old_rip
= rip
;
85 register mode_t bits
, perm_bits
;
88 /* Isolate the relevant rwx bits from the mode. */
90 if (caller_uid
== SU_UID
) {
91 /* Grant read and write permission. Grant search permission for
92 * directories. Grant execute permission (for non-directories) if
93 * and only if one of the 'X' bits is set.
95 if ( (bits
& I_TYPE
) == I_DIRECTORY
||
96 bits
& ((X_BIT
<< 6) | (X_BIT
<< 3) | X_BIT
))
97 perm_bits
= R_BIT
| W_BIT
| X_BIT
;
99 perm_bits
= R_BIT
| W_BIT
;
101 if (caller_uid
== rip
->i_uid
) shift
= 6; /* owner */
102 else if (caller_gid
== rip
->i_gid
) shift
= 3; /* group */
103 else if (in_group(rip
->i_gid
) == OK
) shift
= 3; /* other groups */
104 else shift
= 0; /* other */
105 perm_bits
= (bits
>> shift
) & (R_BIT
| W_BIT
| X_BIT
);
108 /* If access desired is not a subset of what is allowed, it is refused. */
110 if ((perm_bits
| access_desired
) != perm_bits
) r
= EACCES
;
112 /* Check to see if someone is trying to write on a file system that is
116 if (access_desired
& W_BIT
)
119 if (rip
!= old_rip
) put_inode(rip
);
125 /*===========================================================================*
127 *===========================================================================*/
128 static int in_group(gid_t grp
)
132 if (credentials
.vu_ngroups
> NGROUPS_MAX
)
135 for (i
= 0; i
< credentials
.vu_ngroups
; i
++)
136 if (credentials
.vu_sgroups
[i
] == grp
)
143 /*===========================================================================*
145 *===========================================================================*/
147 struct inode
*ip
; /* ptr to inode whose file sys is to be cked */
149 /* Check to see if the file system on which the inode 'ip' resides is mounted
150 * read only. If so, return EROFS, else return OK.
153 register struct super_block
*sp
;
156 return(sp
->s_rd_only
? EROFS
: OK
);