2 * Copyright (c) 2008, 2009 Edward Tomasz NapieraĆa <trasz@FreeBSD.org>
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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
26 #include <sys/cdefs.h>
27 __FBSDID("$FreeBSD$");
29 #include <sys/types.h>
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>
43 static const struct zfs2bsd perms
[] = {{ACE_READ_DATA
, ACL_READ_DATA
},
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
},
59 static const struct zfs2bsd flags
[] = {{ACE_FILE_INHERIT_ACE
,
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
},
69 {ACE_SUCCESSFUL_ACCESS_ACE_FLAG
,
70 ACL_ENTRY_SUCCESSFUL_ACCESS
},
71 {ACE_FAILED_ACCESS_ACE_FLAG
,
72 ACL_ENTRY_FAILED_ACCESS
},
76 _bsd_from_zfs(uint32_t zfs
, const struct zfs2bsd
*table
)
78 const struct zfs2bsd
*tmp
;
81 for (tmp
= table
; tmp
->zb_zfs
!= 0; tmp
++) {
82 if (zfs
& tmp
->zb_zfs
)
90 _zfs_from_bsd(int bsd
, const struct zfs2bsd
*table
)
92 const struct zfs2bsd
*tmp
;
95 for (tmp
= table
; tmp
->zb_bsd
!= 0; tmp
++) {
96 if (bsd
& tmp
->zb_bsd
)
104 acl_from_aces(struct acl
*aclp
, const ace_t
*aces
, int nentries
)
107 struct acl_entry
*entry
;
111 printf("acl_from_aces: empty ZFS ACL; returning EINVAL.\n");
115 if (nentries
> ACL_MAX_ENTRIES
) {
117 * I believe it may happen only when moving a pool
118 * from SunOS to FreeBSD.
120 printf("acl_from_aces: ZFS ACL too big to fit "
121 "into 'struct acl'; returning EINVAL.\n");
125 memset(aclp
, 0, sizeof (*aclp
));
126 aclp
->acl_maxcnt
= ACL_MAX_ENTRIES
;
127 aclp
->acl_cnt
= nentries
;
129 for (i
= 0; i
< nentries
; i
++) {
130 entry
= &(aclp
->acl_entry
[i
]);
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
;
142 entry
->ae_tag
= ACL_USER
;
144 if (entry
->ae_tag
== ACL_USER
|| entry
->ae_tag
== ACL_GROUP
)
145 entry
->ae_id
= ace
->a_who
;
147 entry
->ae_id
= ACL_UNDEFINED_ID
;
149 entry
->ae_perm
= _bsd_from_zfs(ace
->a_access_mask
, perms
);
150 entry
->ae_flags
= _bsd_from_zfs(ace
->a_flags
, flags
);
152 switch (ace
->a_type
) {
153 case ACE_ACCESS_ALLOWED_ACE_TYPE
:
154 entry
->ae_entry_type
= ACL_ENTRY_TYPE_ALLOW
;
156 case ACE_ACCESS_DENIED_ACE_TYPE
:
157 entry
->ae_entry_type
= ACL_ENTRY_TYPE_DENY
;
159 case ACE_SYSTEM_AUDIT_ACE_TYPE
:
160 entry
->ae_entry_type
= ACL_ENTRY_TYPE_AUDIT
;
162 case ACE_SYSTEM_ALARM_ACE_TYPE
:
163 entry
->ae_entry_type
= ACL_ENTRY_TYPE_ALARM
;
166 panic("acl_from_aces: a_type is 0x%x", ace
->a_type
);
174 aces_from_acl(ace_t
*aces
, int *nentries
, const struct acl
*aclp
)
177 const struct acl_entry
*entry
;
180 memset(aces
, 0, sizeof (*aces
) * aclp
->acl_cnt
);
182 *nentries
= aclp
->acl_cnt
;
184 for (i
= 0; i
< aclp
->acl_cnt
; i
++) {
185 entry
= &(aclp
->acl_entry
[i
]);
188 ace
->a_who
= entry
->ae_id
;
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
;
201 ace
->a_access_mask
= _zfs_from_bsd(entry
->ae_perm
, perms
);
202 ace
->a_flags
|= _zfs_from_bsd(entry
->ae_flags
, flags
);
204 switch (entry
->ae_entry_type
) {
205 case ACL_ENTRY_TYPE_ALLOW
:
206 ace
->a_type
= ACE_ACCESS_ALLOWED_ACE_TYPE
;
208 case ACL_ENTRY_TYPE_DENY
:
209 ace
->a_type
= ACE_ACCESS_DENIED_ACE_TYPE
;
211 case ACL_ENTRY_TYPE_ALARM
:
212 ace
->a_type
= ACE_SYSTEM_ALARM_ACE_TYPE
;
214 case ACL_ENTRY_TYPE_AUDIT
:
215 ace
->a_type
= ACE_SYSTEM_AUDIT_ACE_TYPE
;
218 panic("aces_from_acl: ae_entry_type is 0x%x",
219 entry
->ae_entry_type
);