Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/cddl/compat/opensolaris/kern/opensolaris_acl.c
48383 views
1
/*-
2
* Copyright (c) 2008, 2009 Edward Tomasz NapieraƂa <[email protected]>
3
*
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions
6
* are met:
7
* 1. Redistributions of source code must retain the above copyright
8
* notice, this list of conditions and the following disclaimer.
9
* 2. Redistributions in binary form must reproduce the above copyright
10
* notice, this list of conditions and the following disclaimer in the
11
* documentation and/or other materials provided with the distribution.
12
*
13
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23
* SUCH DAMAGE.
24
*/
25
26
#include <sys/param.h>
27
#include <sys/systm.h>
28
#include <sys/types.h>
29
#include <sys/malloc.h>
30
#include <sys/errno.h>
31
#include <sys/zfs_acl.h>
32
#include <sys/acl.h>
33
34
struct zfs2bsd {
35
uint32_t zb_zfs;
36
int zb_bsd;
37
};
38
39
struct zfs2bsd perms[] = {{ACE_READ_DATA, ACL_READ_DATA},
40
{ACE_WRITE_DATA, ACL_WRITE_DATA},
41
{ACE_EXECUTE, ACL_EXECUTE},
42
{ACE_APPEND_DATA, ACL_APPEND_DATA},
43
{ACE_DELETE_CHILD, ACL_DELETE_CHILD},
44
{ACE_DELETE, ACL_DELETE},
45
{ACE_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
46
{ACE_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
47
{ACE_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
48
{ACE_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
49
{ACE_READ_ACL, ACL_READ_ACL},
50
{ACE_WRITE_ACL, ACL_WRITE_ACL},
51
{ACE_WRITE_OWNER, ACL_WRITE_OWNER},
52
{ACE_SYNCHRONIZE, ACL_SYNCHRONIZE},
53
{0, 0}};
54
55
struct zfs2bsd flags[] = {{ACE_FILE_INHERIT_ACE,
56
ACL_ENTRY_FILE_INHERIT},
57
{ACE_DIRECTORY_INHERIT_ACE,
58
ACL_ENTRY_DIRECTORY_INHERIT},
59
{ACE_NO_PROPAGATE_INHERIT_ACE,
60
ACL_ENTRY_NO_PROPAGATE_INHERIT},
61
{ACE_INHERIT_ONLY_ACE,
62
ACL_ENTRY_INHERIT_ONLY},
63
{ACE_INHERITED_ACE,
64
ACL_ENTRY_INHERITED},
65
{ACE_SUCCESSFUL_ACCESS_ACE_FLAG,
66
ACL_ENTRY_SUCCESSFUL_ACCESS},
67
{ACE_FAILED_ACCESS_ACE_FLAG,
68
ACL_ENTRY_FAILED_ACCESS},
69
{0, 0}};
70
71
static int
72
_bsd_from_zfs(uint32_t zfs, const struct zfs2bsd *table)
73
{
74
const struct zfs2bsd *tmp;
75
int bsd = 0;
76
77
for (tmp = table; tmp->zb_zfs != 0; tmp++) {
78
if (zfs & tmp->zb_zfs)
79
bsd |= tmp->zb_bsd;
80
}
81
82
return (bsd);
83
}
84
85
static uint32_t
86
_zfs_from_bsd(int bsd, const struct zfs2bsd *table)
87
{
88
const struct zfs2bsd *tmp;
89
uint32_t zfs = 0;
90
91
for (tmp = table; tmp->zb_bsd != 0; tmp++) {
92
if (bsd & tmp->zb_bsd)
93
zfs |= tmp->zb_zfs;
94
}
95
96
return (zfs);
97
}
98
99
int
100
acl_from_aces(struct acl *aclp, const ace_t *aces, int nentries)
101
{
102
int i;
103
struct acl_entry *entry;
104
const ace_t *ace;
105
106
if (nentries < 1) {
107
printf("acl_from_aces: empty ZFS ACL; returning EINVAL.\n");
108
return (EINVAL);
109
}
110
111
if (nentries > ACL_MAX_ENTRIES) {
112
/*
113
* I believe it may happen only when moving a pool
114
* from SunOS to FreeBSD.
115
*/
116
printf("acl_from_aces: ZFS ACL too big to fit "
117
"into 'struct acl'; returning EINVAL.\n");
118
return (EINVAL);
119
}
120
121
bzero(aclp, sizeof(*aclp));
122
aclp->acl_maxcnt = ACL_MAX_ENTRIES;
123
aclp->acl_cnt = nentries;
124
125
for (i = 0; i < nentries; i++) {
126
entry = &(aclp->acl_entry[i]);
127
ace = &(aces[i]);
128
129
if (ace->a_flags & ACE_OWNER)
130
entry->ae_tag = ACL_USER_OBJ;
131
else if (ace->a_flags & ACE_GROUP)
132
entry->ae_tag = ACL_GROUP_OBJ;
133
else if (ace->a_flags & ACE_EVERYONE)
134
entry->ae_tag = ACL_EVERYONE;
135
else if (ace->a_flags & ACE_IDENTIFIER_GROUP)
136
entry->ae_tag = ACL_GROUP;
137
else
138
entry->ae_tag = ACL_USER;
139
140
if (entry->ae_tag == ACL_USER || entry->ae_tag == ACL_GROUP)
141
entry->ae_id = ace->a_who;
142
else
143
entry->ae_id = ACL_UNDEFINED_ID;
144
145
entry->ae_perm = _bsd_from_zfs(ace->a_access_mask, perms);
146
entry->ae_flags = _bsd_from_zfs(ace->a_flags, flags);
147
148
switch (ace->a_type) {
149
case ACE_ACCESS_ALLOWED_ACE_TYPE:
150
entry->ae_entry_type = ACL_ENTRY_TYPE_ALLOW;
151
break;
152
case ACE_ACCESS_DENIED_ACE_TYPE:
153
entry->ae_entry_type = ACL_ENTRY_TYPE_DENY;
154
break;
155
case ACE_SYSTEM_AUDIT_ACE_TYPE:
156
entry->ae_entry_type = ACL_ENTRY_TYPE_AUDIT;
157
break;
158
case ACE_SYSTEM_ALARM_ACE_TYPE:
159
entry->ae_entry_type = ACL_ENTRY_TYPE_ALARM;
160
break;
161
default:
162
panic("acl_from_aces: a_type is 0x%x", ace->a_type);
163
}
164
}
165
166
return (0);
167
}
168
169
void
170
aces_from_acl(ace_t *aces, int *nentries, const struct acl *aclp)
171
{
172
int i;
173
const struct acl_entry *entry;
174
ace_t *ace;
175
176
bzero(aces, sizeof(*aces) * aclp->acl_cnt);
177
178
*nentries = aclp->acl_cnt;
179
180
for (i = 0; i < aclp->acl_cnt; i++) {
181
entry = &(aclp->acl_entry[i]);
182
ace = &(aces[i]);
183
184
ace->a_who = entry->ae_id;
185
186
if (entry->ae_tag == ACL_USER_OBJ)
187
ace->a_flags = ACE_OWNER;
188
else if (entry->ae_tag == ACL_GROUP_OBJ)
189
ace->a_flags = (ACE_GROUP | ACE_IDENTIFIER_GROUP);
190
else if (entry->ae_tag == ACL_GROUP)
191
ace->a_flags = ACE_IDENTIFIER_GROUP;
192
else if (entry->ae_tag == ACL_EVERYONE)
193
ace->a_flags = ACE_EVERYONE;
194
else /* ACL_USER */
195
ace->a_flags = 0;
196
197
ace->a_access_mask = _zfs_from_bsd(entry->ae_perm, perms);
198
ace->a_flags |= _zfs_from_bsd(entry->ae_flags, flags);
199
200
switch (entry->ae_entry_type) {
201
case ACL_ENTRY_TYPE_ALLOW:
202
ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
203
break;
204
case ACL_ENTRY_TYPE_DENY:
205
ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
206
break;
207
case ACL_ENTRY_TYPE_ALARM:
208
ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE;
209
break;
210
case ACL_ENTRY_TYPE_AUDIT:
211
ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE;
212
break;
213
default:
214
panic("aces_from_acl: ae_entry_type is 0x%x", entry->ae_entry_type);
215
}
216
}
217
}
218
219