Merge tag 'acpi-5.15-rc1-3' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael...
[linux-2.6-microblaze.git] / fs / ksmbd / smbacl.c
index 5456e3a..0a95cde 100644 (file)
@@ -274,24 +274,34 @@ static int sid_to_id(struct user_namespace *user_ns,
                uid_t id;
 
                id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
-               if (id > 0) {
-                       uid = make_kuid(user_ns, id);
-                       if (uid_valid(uid) && kuid_has_mapping(user_ns, uid)) {
-                               fattr->cf_uid = uid;
-                               rc = 0;
-                       }
+               /*
+                * Translate raw sid into kuid in the server's user
+                * namespace.
+                */
+               uid = make_kuid(&init_user_ns, id);
+
+               /* If this is an idmapped mount, apply the idmapping. */
+               uid = kuid_from_mnt(user_ns, uid);
+               if (uid_valid(uid)) {
+                       fattr->cf_uid = uid;
+                       rc = 0;
                }
        } else {
                kgid_t gid;
                gid_t id;
 
                id = le32_to_cpu(psid->sub_auth[psid->num_subauth - 1]);
-               if (id > 0) {
-                       gid = make_kgid(user_ns, id);
-                       if (gid_valid(gid) && kgid_has_mapping(user_ns, gid)) {
-                               fattr->cf_gid = gid;
-                               rc = 0;
-                       }
+               /*
+                * Translate raw sid into kgid in the server's user
+                * namespace.
+                */
+               gid = make_kgid(&init_user_ns, id);
+
+               /* If this is an idmapped mount, apply the idmapping. */
+               gid = kgid_from_mnt(user_ns, gid);
+               if (gid_valid(gid)) {
+                       fattr->cf_gid = gid;
+                       rc = 0;
                }
        }
 
@@ -587,14 +597,14 @@ static void set_posix_acl_entries_dacl(struct user_namespace *user_ns,
                        uid_t uid;
                        unsigned int sid_type = SIDOWNER;
 
-                       uid = from_kuid(user_ns, pace->e_uid);
+                       uid = posix_acl_uid_translate(user_ns, pace);
                        if (!uid)
                                sid_type = SIDUNIX_USER;
                        id_to_sid(uid, sid_type, sid);
                } else if (pace->e_tag == ACL_GROUP) {
                        gid_t gid;
 
-                       gid = from_kgid(user_ns, pace->e_gid);
+                       gid = posix_acl_gid_translate(user_ns, pace);
                        id_to_sid(gid, SIDUNIX_GROUP, sid);
                } else if (pace->e_tag == ACL_OTHER && !nt_aces_num) {
                        smb_copy_sid(sid, &sid_everyone);
@@ -653,12 +663,12 @@ posix_default_acl:
                if (pace->e_tag == ACL_USER) {
                        uid_t uid;
 
-                       uid = from_kuid(user_ns, pace->e_uid);
+                       uid = posix_acl_uid_translate(user_ns, pace);
                        id_to_sid(uid, SIDCREATOR_OWNER, sid);
                } else if (pace->e_tag == ACL_GROUP) {
                        gid_t gid;
 
-                       gid = from_kgid(user_ns, pace->e_gid);
+                       gid = posix_acl_gid_translate(user_ns, pace);
                        id_to_sid(gid, SIDCREATOR_GROUP, sid);
                } else {
                        kfree(sid);
@@ -723,7 +733,7 @@ static void set_mode_dacl(struct user_namespace *user_ns,
        }
 
        /* owner RID */
-       uid = from_kuid(user_ns, fattr->cf_uid);
+       uid = from_kuid(&init_user_ns, fattr->cf_uid);
        if (uid)
                sid = &server_conf.domain_sid;
        else
@@ -739,7 +749,7 @@ static void set_mode_dacl(struct user_namespace *user_ns,
        ace_size = fill_ace_for_sid(pace, &sid_unix_groups,
                                    ACCESS_ALLOWED, 0, fattr->cf_mode, 0070);
        pace->sid.sub_auth[pace->sid.num_subauth++] =
-               cpu_to_le32(from_kgid(user_ns, fattr->cf_gid));
+               cpu_to_le32(from_kgid(&init_user_ns, fattr->cf_gid));
        pace->size = cpu_to_le16(ace_size + 4);
        size += le16_to_cpu(pace->size);
        pace = (struct smb_ace *)((char *)pndace + size);
@@ -880,7 +890,7 @@ int build_sec_desc(struct user_namespace *user_ns,
        if (!nowner_sid_ptr)
                return -ENOMEM;
 
-       uid = from_kuid(user_ns, fattr->cf_uid);
+       uid = from_kuid(&init_user_ns, fattr->cf_uid);
        if (!uid)
                sid_type = SIDUNIX_USER;
        id_to_sid(uid, sid_type, nowner_sid_ptr);
@@ -891,7 +901,7 @@ int build_sec_desc(struct user_namespace *user_ns,
                return -ENOMEM;
        }
 
-       gid = from_kgid(user_ns, fattr->cf_gid);
+       gid = from_kgid(&init_user_ns, fattr->cf_gid);
        id_to_sid(gid, SIDUNIX_GROUP, ngroup_sid_ptr);
 
        offset = sizeof(struct smb_ntsd);
@@ -1234,11 +1244,9 @@ int smb_check_perm_dacl(struct ksmbd_conn *conn, struct path *path,
                        pa_entry = posix_acls->a_entries;
                        for (i = 0; i < posix_acls->a_count; i++, pa_entry++) {
                                if (pa_entry->e_tag == ACL_USER)
-                                       id = from_kuid(user_ns,
-                                                      pa_entry->e_uid);
+                                       id = posix_acl_uid_translate(user_ns, pa_entry);
                                else if (pa_entry->e_tag == ACL_GROUP)
-                                       id = from_kgid(user_ns,
-                                                      pa_entry->e_gid);
+                                       id = posix_acl_gid_translate(user_ns, pa_entry);
                                else
                                        continue;
 
@@ -1322,22 +1330,31 @@ int set_info_sec(struct ksmbd_conn *conn, struct ksmbd_tree_connect *tcon,
        newattrs.ia_valid |= ATTR_MODE;
        newattrs.ia_mode = (inode->i_mode & ~0777) | (fattr.cf_mode & 0777);
 
-       inode_lock(inode);
-       rc = notify_change(user_ns, path->dentry, &newattrs, NULL);
-       inode_unlock(inode);
-       if (rc)
-               goto out;
-
        ksmbd_vfs_remove_acl_xattrs(user_ns, path->dentry);
        /* Update posix acls */
        if (IS_ENABLED(CONFIG_FS_POSIX_ACL) && fattr.cf_dacls) {
                rc = set_posix_acl(user_ns, inode,
                                   ACL_TYPE_ACCESS, fattr.cf_acls);
-               if (S_ISDIR(inode->i_mode) && fattr.cf_dacls)
+               if (rc < 0)
+                       ksmbd_debug(SMB,
+                                   "Set posix acl(ACL_TYPE_ACCESS) failed, rc : %d\n",
+                                   rc);
+               if (S_ISDIR(inode->i_mode) && fattr.cf_dacls) {
                        rc = set_posix_acl(user_ns, inode,
                                           ACL_TYPE_DEFAULT, fattr.cf_dacls);
+                       if (rc)
+                               ksmbd_debug(SMB,
+                                           "Set posix acl(ACL_TYPE_DEFAULT) failed, rc : %d\n",
+                                           rc);
+               }
        }
 
+       inode_lock(inode);
+       rc = notify_change(user_ns, path->dentry, &newattrs, NULL);
+       inode_unlock(inode);
+       if (rc)
+               goto out;
+
        /* Check it only calling from SD BUFFER context */
        if (type_check && !(le16_to_cpu(pntsd->type) & DACL_PRESENT))
                goto out;