...
1 package devices
2
3 import (
4 "fmt"
5 "os"
6 "strconv"
7 )
8
9 const (
10 Wildcard = -1
11 )
12
13 type Device struct {
14 Rule
15
16
17 Path string `json:"path"`
18
19
20 FileMode os.FileMode `json:"file_mode"`
21
22
23 Uid uint32 `json:"uid"`
24
25
26 Gid uint32 `json:"gid"`
27 }
28
29
30
31
32 type Permissions string
33
34 const (
35 deviceRead uint = (1 << iota)
36 deviceWrite
37 deviceMknod
38 )
39
40 func (p Permissions) toSet() uint {
41 var set uint
42 for _, perm := range p {
43 switch perm {
44 case 'r':
45 set |= deviceRead
46 case 'w':
47 set |= deviceWrite
48 case 'm':
49 set |= deviceMknod
50 }
51 }
52 return set
53 }
54
55 func fromSet(set uint) Permissions {
56 var perm string
57 if set&deviceRead == deviceRead {
58 perm += "r"
59 }
60 if set&deviceWrite == deviceWrite {
61 perm += "w"
62 }
63 if set&deviceMknod == deviceMknod {
64 perm += "m"
65 }
66 return Permissions(perm)
67 }
68
69
70 func (p Permissions) Union(o Permissions) Permissions {
71 lhs := p.toSet()
72 rhs := o.toSet()
73 return fromSet(lhs | rhs)
74 }
75
76
77
78 func (p Permissions) Difference(o Permissions) Permissions {
79 lhs := p.toSet()
80 rhs := o.toSet()
81 return fromSet(lhs &^ rhs)
82 }
83
84
85 func (p Permissions) Intersection(o Permissions) Permissions {
86 lhs := p.toSet()
87 rhs := o.toSet()
88 return fromSet(lhs & rhs)
89 }
90
91
92
93 func (p Permissions) IsEmpty() bool {
94 return p == Permissions("")
95 }
96
97
98
99 func (p Permissions) IsValid() bool {
100 return p == fromSet(p.toSet())
101 }
102
103 type Type rune
104
105 const (
106 WildcardDevice Type = 'a'
107 BlockDevice Type = 'b'
108 CharDevice Type = 'c'
109 FifoDevice Type = 'p'
110 )
111
112 func (t Type) IsValid() bool {
113 switch t {
114 case WildcardDevice, BlockDevice, CharDevice, FifoDevice:
115 return true
116 default:
117 return false
118 }
119 }
120
121 func (t Type) CanMknod() bool {
122 switch t {
123 case BlockDevice, CharDevice, FifoDevice:
124 return true
125 default:
126 return false
127 }
128 }
129
130 func (t Type) CanCgroup() bool {
131 switch t {
132 case WildcardDevice, BlockDevice, CharDevice:
133 return true
134 default:
135 return false
136 }
137 }
138
139 type Rule struct {
140
141
142 Type Type `json:"type"`
143
144
145 Major int64 `json:"major"`
146
147
148 Minor int64 `json:"minor"`
149
150
151
152 Permissions Permissions `json:"permissions"`
153
154
155 Allow bool `json:"allow"`
156 }
157
158 func (d *Rule) CgroupString() string {
159 var (
160 major = strconv.FormatInt(d.Major, 10)
161 minor = strconv.FormatInt(d.Minor, 10)
162 )
163 if d.Major == Wildcard {
164 major = "*"
165 }
166 if d.Minor == Wildcard {
167 minor = "*"
168 }
169 return fmt.Sprintf("%c %s:%s %s", d.Type, major, minor, d.Permissions)
170 }
171
172 func (d *Rule) Mkdev() (uint64, error) {
173 return mkDev(d)
174 }
175
View as plain text