embox

Форк
0
117 строк · 2.1 Кб
1
/**
2
 * @file
3
 * @brief
4
 *
5
 * @author  Anton Kozlov
6
 * @date    14.02.2013
7
 */
8

9
#include <errno.h>
10
#include <unistd.h>
11
#include <stdlib.h>
12
#include <sys/stat.h>
13

14
#include <fs/vfs.h>
15
#include <fs/inode.h>
16
#include <fs/inode_operation.h>
17
#include <fs/hlpr_path.h>
18

19
#include <security/security.h>
20

21
int fs_perm_mask(struct inode *node) {
22
	int perm = node->i_mode & S_IRWXA;
23
	uid_t uid = getuid();
24

25
	if (uid == 0) {
26
		/* super user */
27
		return S_IRWXO;
28
	}
29

30
	if (node->i_owner_id == uid) {
31
		perm >>= 6;
32
	} else if (node->i_group_id == getgid()) {
33
		perm >>= 3;
34
	}
35
	perm &= S_IRWXO;
36

37
	return perm;
38
}
39

40
int fs_perm_check(struct inode *node, int fd_flags) {
41
	/* Here, we rely on the fact that fd_flags correspond to OTH perm bits. */
42
	return (fd_flags & ~fs_perm_mask(node)) ? -EACCES :
43
		security_node_permissions(node, fd_flags);
44
}
45

46
int fs_perm_lookup(const char *path, const char **pathlast,
47
		struct path *nodelast) {
48
	struct path node_path;
49
	struct path dir_path;
50
	size_t len = 0;
51
	int ret;
52

53
	if (!path) {
54
		return -EINVAL;
55
	}
56

57
	if (path[0] == '/') {
58
		vfs_get_root_path(&node_path);
59
	} else {
60
		vfs_get_leaf_path(&node_path);
61
	}
62

63
	do {
64
		struct inode *dnode;
65

66
		path = path_next(path + len, &len);
67

68
		*nodelast = node_path;
69

70
		if (pathlast != NULL) {
71
			*pathlast = path;
72
		}
73

74
		if (!path) {
75
			return 0;
76
		}
77

78
		if (0 != (ret = fs_perm_check(node_path.node, S_IXOTH))) {
79
			return ret;
80
		}
81

82
		dir_path = node_path;
83
		if_mounted_follow_down(&node_path);
84
		dnode = node_path.node;
85
		vfs_lookup_childn(&node_path, path, len, &node_path);
86

87
		if (NULL != node_path.node) {
88
			if (dnode && dnode->i_ops && dnode->i_ops->ino_lookup) {
89
				if (dnode->i_ops == dir_path.node->i_ops) {
90
					dnode->i_ops->ino_lookup(node_path.node, path, dir_path.node);
91
				} else {
92
					/* find mount inode */
93
					dnode->i_ops->ino_lookup(node_path.node, path, NULL);
94

95
				}
96
			}
97
		}
98

99
	} while (node_path.node);
100

101
	return -ENOENT;
102
}
103

104
int fs_perm_lookup_relative(const char *path, const char **pathlast,
105
		struct path *nodelast) {
106
	int ret = 0;
107

108
	if (0 != (ret = fs_perm_lookup(path, pathlast, nodelast))) {
109
		return ret;
110
	}
111

112
	if (!S_ISDIR(nodelast->node->i_mode)) {
113
		return 0;
114
	}
115

116
	return 0;
117
}
118

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.