pmode is the existing mode (we only want to overwrite part of this
bits to set can be: S_IRWXU, S_IRWXG or S_IRWXO ie 00700 or 00070 or 00007
*/
-static void access_flags_to_mode(__u32 ace_flags, int type, umode_t *pmode,
+static void access_flags_to_mode(__le32 ace_flags, int type, umode_t *pmode,
umode_t *pbits_to_set)
{
+ __u32 flags = le32_to_cpu(ace_flags);
/* the order of ACEs is important. The canonical order is to begin with
- DENY entries then follow with ALLOW, otherwise an allow entry could be
+ DENY entries followed by ALLOW, otherwise an allow entry could be
encountered first, making the subsequent deny entry like "dead code"
- which would be superflous since Windows stops when a match is made
+ which would be superflous since Windows stops when a match is made
for the operation you are trying to perform for your user */
/* For deny ACEs we change the mask so that subsequent allow access
control entries do not turn on the bits we are denying */
if (type == ACCESS_DENIED) {
- if (ace_flags & GENERIC_ALL) {
+ if (flags & GENERIC_ALL) {
*pbits_to_set &= ~S_IRWXUGO;
}
- if ((ace_flags & GENERIC_WRITE) ||
- ((ace_flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
+ if ((flags & GENERIC_WRITE) ||
+ ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
*pbits_to_set &= ~S_IWUGO;
- if ((ace_flags & GENERIC_READ) ||
- ((ace_flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
+ if ((flags & GENERIC_READ) ||
+ ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
*pbits_to_set &= ~S_IRUGO;
- if ((ace_flags & GENERIC_EXECUTE) ||
- ((ace_flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
+ if ((flags & GENERIC_EXECUTE) ||
+ ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
*pbits_to_set &= ~S_IXUGO;
return;
} else if (type != ACCESS_ALLOWED) {
}
/* else ACCESS_ALLOWED type */
- if (ace_flags & GENERIC_ALL) {
+ if (flags & GENERIC_ALL) {
*pmode |= (S_IRWXUGO & (*pbits_to_set));
#ifdef CONFIG_CIFS_DEBUG2
cFYI(1, ("all perms"));
#endif
return;
}
- if ((ace_flags & GENERIC_WRITE) ||
- ((ace_flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
+ if ((flags & GENERIC_WRITE) ||
+ ((flags & FILE_WRITE_RIGHTS) == FILE_WRITE_RIGHTS))
*pmode |= (S_IWUGO & (*pbits_to_set));
- if ((ace_flags & GENERIC_READ) ||
- ((ace_flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
+ if ((flags & GENERIC_READ) ||
+ ((flags & FILE_READ_RIGHTS) == FILE_READ_RIGHTS))
*pmode |= (S_IRUGO & (*pbits_to_set));
- if ((ace_flags & GENERIC_EXECUTE) ||
- ((ace_flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
+ if ((flags & GENERIC_EXECUTE) ||
+ ((flags & FILE_EXEC_RIGHTS) == FILE_EXEC_RIGHTS))
*pmode |= (S_IXUGO & (*pbits_to_set));
#ifdef CONFIG_CIFS_DEBUG2
- cFYI(1, ("access flags 0x%x mode now 0x%x", ace_flags, *pmode));
+ cFYI(1, ("access flags 0x%x mode now 0x%x", flags, *pmode));
+#endif
+ return;
+}
+
+/*
+ Generate access flags to reflect permissions mode is the existing mode.
+ This function is called for every ACE in the DACL whose SID matches
+ with either owner or group or everyone.
+*/
+
+static void mode_to_access_flags(umode_t mode, umode_t bits_to_use,
+ __u32 *pace_flags)
+{
+ /* reset access mask */
+ *pace_flags = 0x0;
+
+ /* bits to use are either S_IRWXU or S_IRWXG or S_IRWXO */
+ mode &= bits_to_use;
+
+ /* check for R/W/X UGO since we do not know whose flags
+ is this but we have cleared all the bits sans RWX for
+ either user or group or other as per bits_to_use */
+ if (mode & S_IRUGO)
+ *pace_flags |= SET_FILE_READ_RIGHTS;
+ if (mode & S_IWUGO)
+ *pace_flags |= SET_FILE_WRITE_RIGHTS;
+ if (mode & S_IXUGO)
+ *pace_flags |= SET_FILE_EXEC_RIGHTS;
+
+#ifdef CONFIG_CIFS_DEBUG2
+ cFYI(1, ("mode: 0x%x, access flags now 0x%x", mode, *pace_flags));
#endif
return;
}
/* BB need to add parm so we can store the SID BB */
+ if (!pdacl) {
+ /* no DACL in the security descriptor, set
+ all the permissions for user/group/other */
+ inode->i_mode |= S_IRWXUGO;
+ return;
+ }
+
/* validate that we do not go past end of acl */
if (end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
cERROR(1, ("ACL too small to parse DACL"));
user/group/other have no permissions */
inode->i_mode &= ~(S_IRWXUGO);
- if (!pdacl) {
- /* no DACL in the security descriptor, set
- all the permissions for user/group/other */
- inode->i_mode |= S_IRWXUGO;
- return;
- }
acl_base = (char *)pdacl;
acl_size = sizeof(struct cifs_acl);