1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * fs/sharefs/authentication.c 4 * 5 * Copyright (c) 2023 Huawei Device Co., Ltd. 6 */ 7#include "authentication.h" 8 9static inline __u16 perm_get_next_level(__u16 perm) 10{ 11 __u16 level = (perm & SHAREFS_PERM_MASK) + 1; 12 13 if (level <= SHAREFS_PERM_OTHER) 14 return level; 15 else 16 return SHAREFS_PERM_OTHER; 17} 18 19void fixup_perm_from_level(struct inode *dir, struct dentry *dentry) 20{ 21 struct sharefs_inode_info *hii = SHAREFS_I(dir); 22 struct inode *dinode = d_inode(dentry); 23 struct sharefs_inode_info *dinfo = SHAREFS_I(dinode); 24 const unsigned char* cur_name = dentry->d_name.name; 25 __u16 level = perm_get_next_level(hii->perm); 26 __u16 perm = 0; 27 int bid = 0; 28 29 if (IS_ERR_OR_NULL(dinode)) 30 return; 31 dinode->i_uid = dir->i_uid; 32 dinode->i_gid = dir->i_gid; 33 switch (level) { 34 case SHAREFS_PERM_MNT: 35 bid = get_bundle_uid(SHAREFS_SB(dentry->d_sb), 36 dentry->d_name.name); 37 perm = level; 38 if (bid != 0) { 39 dinode->i_uid = KUIDT_INIT(bid); 40 dinode->i_gid = KGIDT_INIT(bid); 41 } else { 42 dinode->i_uid = ROOT_UID; 43 dinode->i_gid = ROOT_GID; 44 } 45 dinode->i_mode = (dinode->i_mode & S_IFMT) | SHAREFS_PERM_READONLY_DIR; 46 break; 47 case SHAREFS_PERM_DFS: 48 if (!strcmp(cur_name, SHAREFS_READ_DIR)) { 49 perm = SHAREFS_DIR_TYPE_READONLY | level; 50 sharefs_set_read_perm(dinode); 51 } else if (!strcmp(cur_name, SHAREFS_READWRITE_DIR)) { 52 perm = SHAREFS_DIR_TYPE_READWRITE | level; 53 sharefs_set_read_write_perm(dinode); 54 } 55 break; 56 case SHAREFS_PERM_OTHER: 57 if (is_read_only_auth(hii->perm)) { 58 perm = SHAREFS_DIR_TYPE_READONLY | SHAREFS_PERM_DFS; 59 sharefs_set_read_perm(dinode); 60 } else if (is_read_write_auth(hii->perm)) { 61 perm = SHAREFS_DIR_TYPE_READWRITE | SHAREFS_PERM_DFS; 62 sharefs_set_read_write_perm(dinode); 63 } 64 break; 65 default: 66 sharefs_err("sharedfs perm incorrect got default case, level:%u", level); 67 break; 68 } 69 dinfo->perm = perm; 70} 71 72void sharefs_root_inode_perm_init(struct inode *root_inode) 73{ 74 struct sharefs_inode_info *hii = SHAREFS_I(root_inode); 75 hii->perm = SHAREFS_PERM_FIX; 76} 77 78#ifdef CONFIG_SHAREFS_SUPPORT_OVERRIDE 79const struct cred *sharefs_override_file_fsids(struct inode *dir, __u16 *_perm) 80{ 81 struct cred *cred = NULL; 82 cred = prepare_creds(); 83 if (!cred) 84 return NULL; 85 86 cred->fsuid = dir->i_uid; 87 cred->fsgid = dir->i_gid; 88 return override_creds(cred); 89} 90 91void sharefs_revert_fsids(const struct cred *old_cred) 92{ 93 const struct cred *cur_cred; 94 cur_cred = current->cred; 95 revert_creds(old_cred); 96 put_cred(cur_cred); 97} 98#endif