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