]> git.proxmox.com Git - mirror_zfs.git/blame - module/os/freebsd/spl/spl_acl.c
Remove bcopy(), bzero(), bcmp()
[mirror_zfs.git] / module / os / freebsd / spl / spl_acl.c
CommitLineData
9f0a21e6
MM
1/*
2 * Copyright (c) 2008, 2009 Edward Tomasz Napierała <trasz@FreeBSD.org>
9f0a21e6
MM
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/cdefs.h>
27__FBSDID("$FreeBSD$");
28
e64cc495 29#include <sys/types.h>
9f0a21e6
MM
30#include <sys/param.h>
31#include <sys/systm.h>
32#include <sys/types.h>
33#include <sys/malloc.h>
34#include <sys/errno.h>
35#include <sys/zfs_acl.h>
36#include <sys/acl.h>
37
38struct zfs2bsd {
39 uint32_t zb_zfs;
40 int zb_bsd;
41};
42
861166b0 43static const struct zfs2bsd perms[] = {{ACE_READ_DATA, ACL_READ_DATA},
9f0a21e6
MM
44 {ACE_WRITE_DATA, ACL_WRITE_DATA},
45 {ACE_EXECUTE, ACL_EXECUTE},
46 {ACE_APPEND_DATA, ACL_APPEND_DATA},
47 {ACE_DELETE_CHILD, ACL_DELETE_CHILD},
48 {ACE_DELETE, ACL_DELETE},
49 {ACE_READ_ATTRIBUTES, ACL_READ_ATTRIBUTES},
50 {ACE_WRITE_ATTRIBUTES, ACL_WRITE_ATTRIBUTES},
51 {ACE_READ_NAMED_ATTRS, ACL_READ_NAMED_ATTRS},
52 {ACE_WRITE_NAMED_ATTRS, ACL_WRITE_NAMED_ATTRS},
53 {ACE_READ_ACL, ACL_READ_ACL},
54 {ACE_WRITE_ACL, ACL_WRITE_ACL},
55 {ACE_WRITE_OWNER, ACL_WRITE_OWNER},
56 {ACE_SYNCHRONIZE, ACL_SYNCHRONIZE},
57 {0, 0}};
58
861166b0 59static const struct zfs2bsd flags[] = {{ACE_FILE_INHERIT_ACE,
9f0a21e6
MM
60 ACL_ENTRY_FILE_INHERIT},
61 {ACE_DIRECTORY_INHERIT_ACE,
62 ACL_ENTRY_DIRECTORY_INHERIT},
63 {ACE_NO_PROPAGATE_INHERIT_ACE,
64 ACL_ENTRY_NO_PROPAGATE_INHERIT},
65 {ACE_INHERIT_ONLY_ACE,
66 ACL_ENTRY_INHERIT_ONLY},
67 {ACE_INHERITED_ACE,
68 ACL_ENTRY_INHERITED},
69 {ACE_SUCCESSFUL_ACCESS_ACE_FLAG,
70 ACL_ENTRY_SUCCESSFUL_ACCESS},
71 {ACE_FAILED_ACCESS_ACE_FLAG,
72 ACL_ENTRY_FAILED_ACCESS},
73 {0, 0}};
74
75static int
76_bsd_from_zfs(uint32_t zfs, const struct zfs2bsd *table)
77{
78 const struct zfs2bsd *tmp;
79 int bsd = 0;
80
81 for (tmp = table; tmp->zb_zfs != 0; tmp++) {
82 if (zfs & tmp->zb_zfs)
83 bsd |= tmp->zb_bsd;
84 }
85
86 return (bsd);
87}
88
89static uint32_t
90_zfs_from_bsd(int bsd, const struct zfs2bsd *table)
91{
92 const struct zfs2bsd *tmp;
93 uint32_t zfs = 0;
94
95 for (tmp = table; tmp->zb_bsd != 0; tmp++) {
96 if (bsd & tmp->zb_bsd)
97 zfs |= tmp->zb_zfs;
98 }
99
100 return (zfs);
101}
102
103int
104acl_from_aces(struct acl *aclp, const ace_t *aces, int nentries)
105{
106 int i;
107 struct acl_entry *entry;
108 const ace_t *ace;
109
110 if (nentries < 1) {
111 printf("acl_from_aces: empty ZFS ACL; returning EINVAL.\n");
112 return (EINVAL);
113 }
114
115 if (nentries > ACL_MAX_ENTRIES) {
116 /*
117 * I believe it may happen only when moving a pool
118 * from SunOS to FreeBSD.
119 */
120 printf("acl_from_aces: ZFS ACL too big to fit "
121 "into 'struct acl'; returning EINVAL.\n");
122 return (EINVAL);
123 }
124
861166b0 125 memset(aclp, 0, sizeof (*aclp));
9f0a21e6
MM
126 aclp->acl_maxcnt = ACL_MAX_ENTRIES;
127 aclp->acl_cnt = nentries;
128
129 for (i = 0; i < nentries; i++) {
130 entry = &(aclp->acl_entry[i]);
131 ace = &(aces[i]);
132
133 if (ace->a_flags & ACE_OWNER)
134 entry->ae_tag = ACL_USER_OBJ;
135 else if (ace->a_flags & ACE_GROUP)
136 entry->ae_tag = ACL_GROUP_OBJ;
137 else if (ace->a_flags & ACE_EVERYONE)
138 entry->ae_tag = ACL_EVERYONE;
139 else if (ace->a_flags & ACE_IDENTIFIER_GROUP)
140 entry->ae_tag = ACL_GROUP;
141 else
142 entry->ae_tag = ACL_USER;
143
144 if (entry->ae_tag == ACL_USER || entry->ae_tag == ACL_GROUP)
145 entry->ae_id = ace->a_who;
146 else
147 entry->ae_id = ACL_UNDEFINED_ID;
148
149 entry->ae_perm = _bsd_from_zfs(ace->a_access_mask, perms);
150 entry->ae_flags = _bsd_from_zfs(ace->a_flags, flags);
151
152 switch (ace->a_type) {
153 case ACE_ACCESS_ALLOWED_ACE_TYPE:
154 entry->ae_entry_type = ACL_ENTRY_TYPE_ALLOW;
155 break;
156 case ACE_ACCESS_DENIED_ACE_TYPE:
157 entry->ae_entry_type = ACL_ENTRY_TYPE_DENY;
158 break;
159 case ACE_SYSTEM_AUDIT_ACE_TYPE:
160 entry->ae_entry_type = ACL_ENTRY_TYPE_AUDIT;
161 break;
162 case ACE_SYSTEM_ALARM_ACE_TYPE:
163 entry->ae_entry_type = ACL_ENTRY_TYPE_ALARM;
164 break;
165 default:
166 panic("acl_from_aces: a_type is 0x%x", ace->a_type);
167 }
168 }
169
170 return (0);
171}
172
173void
174aces_from_acl(ace_t *aces, int *nentries, const struct acl *aclp)
175{
176 int i;
177 const struct acl_entry *entry;
178 ace_t *ace;
179
861166b0 180 memset(aces, 0, sizeof (*aces) * aclp->acl_cnt);
9f0a21e6
MM
181
182 *nentries = aclp->acl_cnt;
183
184 for (i = 0; i < aclp->acl_cnt; i++) {
185 entry = &(aclp->acl_entry[i]);
186 ace = &(aces[i]);
187
188 ace->a_who = entry->ae_id;
189
190 if (entry->ae_tag == ACL_USER_OBJ)
191 ace->a_flags = ACE_OWNER;
192 else if (entry->ae_tag == ACL_GROUP_OBJ)
193 ace->a_flags = (ACE_GROUP | ACE_IDENTIFIER_GROUP);
194 else if (entry->ae_tag == ACL_GROUP)
195 ace->a_flags = ACE_IDENTIFIER_GROUP;
196 else if (entry->ae_tag == ACL_EVERYONE)
197 ace->a_flags = ACE_EVERYONE;
198 else /* ACL_USER */
199 ace->a_flags = 0;
200
201 ace->a_access_mask = _zfs_from_bsd(entry->ae_perm, perms);
202 ace->a_flags |= _zfs_from_bsd(entry->ae_flags, flags);
203
204 switch (entry->ae_entry_type) {
205 case ACL_ENTRY_TYPE_ALLOW:
206 ace->a_type = ACE_ACCESS_ALLOWED_ACE_TYPE;
207 break;
208 case ACL_ENTRY_TYPE_DENY:
209 ace->a_type = ACE_ACCESS_DENIED_ACE_TYPE;
210 break;
211 case ACL_ENTRY_TYPE_ALARM:
212 ace->a_type = ACE_SYSTEM_ALARM_ACE_TYPE;
213 break;
214 case ACL_ENTRY_TYPE_AUDIT:
215 ace->a_type = ACE_SYSTEM_AUDIT_ACE_TYPE;
216 break;
217 default:
218 panic("aces_from_acl: ae_entry_type is 0x%x",
219 entry->ae_entry_type);
220 }
221 }
222}