3 #include <minix/callnr.h>
7 #include <minix/vfsif.h>
9 FORWARD
_PROTOTYPE( in_group
, (gid_t grp
) );
12 /*===========================================================================*
14 *===========================================================================*/
17 /* Perform the chmod(name, mode) system call. */
19 register struct inode
*rip
;
22 /* Temporarily open the file. */
23 if( (rip
= get_inode(fs_dev
, fs_m_in
.REQ_INODE_NR
)) == NIL_INODE
)
26 /* Now make the change. Clear setgid bit if file is not in caller's grp */
27 rip
->i_mode
= (rip
->i_mode
& ~ALL_MODES
) | (fs_m_in
.REQ_MODE
& ALL_MODES
);
28 rip
->i_update
|= CTIME
;
31 /* Return full new mode to caller. */
32 fs_m_out
.RES_MODE
= rip
->i_mode
;
39 /*===========================================================================*
41 *===========================================================================*/
44 register struct inode
*rip
;
47 /* Temporarily open the file. */
48 if( (rip
= get_inode(fs_dev
, fs_m_in
.REQ_INODE_NR
)) == NIL_INODE
)
51 /* Not permitted to change the owner of a file on a read-only file sys. */
54 rip
->i_uid
= fs_m_in
.REQ_UID
;
55 rip
->i_gid
= fs_m_in
.REQ_GID
;
56 rip
->i_mode
&= ~(I_SET_UID_BIT
| I_SET_GID_BIT
);
57 rip
->i_update
|= CTIME
;
61 /* Update caller on current mode, as it may have changed. */
62 fs_m_out
.RES_MODE
= rip
->i_mode
;
69 /*===========================================================================*
71 *===========================================================================*/
72 PUBLIC
int forbidden(register struct inode
*rip
, mode_t access_desired
)
74 /* Given a pointer to an inode, 'rip', and the access desired, determine
75 * if the access is allowed, and if not why not. The routine looks up the
76 * caller's uid in the 'fproc' table. If access is allowed, OK is returned
77 * if it is forbidden, EACCES is returned.
80 register struct inode
*old_rip
= rip
;
81 register struct super_block
*sp
;
82 register mode_t bits
, perm_bits
;
85 /* Isolate the relevant rwx bits from the mode. */
87 if (caller_uid
== SU_UID
) {
88 /* Grant read and write permission. Grant search permission for
89 * directories. Grant execute permission (for non-directories) if
90 * and only if one of the 'X' bits is set.
92 if ( (bits
& I_TYPE
) == I_DIRECTORY
||
93 bits
& ((X_BIT
<< 6) | (X_BIT
<< 3) | X_BIT
))
94 perm_bits
= R_BIT
| W_BIT
| X_BIT
;
96 perm_bits
= R_BIT
| W_BIT
;
98 if (caller_uid
== rip
->i_uid
) shift
= 6; /* owner */
99 else if (caller_gid
== rip
->i_gid
) shift
= 3; /* group */
100 else if (in_group(rip
->i_gid
) == OK
) shift
= 3; /* other groups */
101 else shift
= 0; /* other */
102 perm_bits
= (bits
>> shift
) & (R_BIT
| W_BIT
| X_BIT
);
105 /* If access desired is not a subset of what is allowed, it is refused. */
107 if ((perm_bits
| access_desired
) != perm_bits
) r
= EACCES
;
109 /* Check to see if someone is trying to write on a file system that is
113 if (access_desired
& W_BIT
)
116 if (rip
!= old_rip
) put_inode(rip
);
122 /*===========================================================================*
124 *===========================================================================*/
125 PRIVATE
int in_group(gid_t grp
)
128 for(i
= 0; i
< credentials
.vu_ngroups
; i
++)
129 if (credentials
.vu_sgroups
[i
] == grp
)
136 /*===========================================================================*
138 *===========================================================================*/
139 PUBLIC
int read_only(ip
)
140 struct inode
*ip
; /* ptr to inode whose file sys is to be cked */
142 /* Check to see if the file system on which the inode 'ip' resides is mounted
143 * read only. If so, return EROFS, else return OK.
146 register struct super_block
*sp
;
149 return(sp
->s_rd_only
? EROFS
: OK
);