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/types.h>
27 #include <sys/param.h>
28 #include <sys/systm.h>
29 #include <sys/types.h>
30 #include <sys/malloc.h>
31 #include <sys/errno.h>
32 #include <sys/zfs_acl.h>
40 static const struct zfs2bsd perms
[] = {{ACE_READ_DATA
, ACL_READ_DATA
},
41 {ACE_WRITE_DATA
, ACL_WRITE_DATA
},
42 {ACE_EXECUTE
, ACL_EXECUTE
},
43 {ACE_APPEND_DATA
, ACL_APPEND_DATA
},
44 {ACE_DELETE_CHILD
, ACL_DELETE_CHILD
},
45 {ACE_DELETE
, ACL_DELETE
},
46 {ACE_READ_ATTRIBUTES
, ACL_READ_ATTRIBUTES
},
47 {ACE_WRITE_ATTRIBUTES
, ACL_WRITE_ATTRIBUTES
},
48 {ACE_READ_NAMED_ATTRS
, ACL_READ_NAMED_ATTRS
},
49 {ACE_WRITE_NAMED_ATTRS
, ACL_WRITE_NAMED_ATTRS
},
50 {ACE_READ_ACL
, ACL_READ_ACL
},
51 {ACE_WRITE_ACL
, ACL_WRITE_ACL
},
52 {ACE_WRITE_OWNER
, ACL_WRITE_OWNER
},
53 {ACE_SYNCHRONIZE
, ACL_SYNCHRONIZE
},
56 static const struct zfs2bsd flags
[] = {{ACE_FILE_INHERIT_ACE
,
57 ACL_ENTRY_FILE_INHERIT
},
58 {ACE_DIRECTORY_INHERIT_ACE
,
59 ACL_ENTRY_DIRECTORY_INHERIT
},
60 {ACE_NO_PROPAGATE_INHERIT_ACE
,
61 ACL_ENTRY_NO_PROPAGATE_INHERIT
},
62 {ACE_INHERIT_ONLY_ACE
,
63 ACL_ENTRY_INHERIT_ONLY
},
66 {ACE_SUCCESSFUL_ACCESS_ACE_FLAG
,
67 ACL_ENTRY_SUCCESSFUL_ACCESS
},
68 {ACE_FAILED_ACCESS_ACE_FLAG
,
69 ACL_ENTRY_FAILED_ACCESS
},
73 _bsd_from_zfs(uint32_t zfs
, const struct zfs2bsd
*table
)
75 const struct zfs2bsd
*tmp
;
78 for (tmp
= table
; tmp
->zb_zfs
!= 0; tmp
++) {
79 if (zfs
& tmp
->zb_zfs
)
87 _zfs_from_bsd(int bsd
, const struct zfs2bsd
*table
)
89 const struct zfs2bsd
*tmp
;
92 for (tmp
= table
; tmp
->zb_bsd
!= 0; tmp
++) {
93 if (bsd
& tmp
->zb_bsd
)
101 acl_from_aces(struct acl
*aclp
, const ace_t
*aces
, int nentries
)
104 struct acl_entry
*entry
;
108 printf("acl_from_aces: empty ZFS ACL; returning EINVAL.\n");
112 if (nentries
> ACL_MAX_ENTRIES
) {
114 * I believe it may happen only when moving a pool
115 * from SunOS to FreeBSD.
117 printf("acl_from_aces: ZFS ACL too big to fit "
118 "into 'struct acl'; returning EINVAL.\n");
122 memset(aclp
, 0, sizeof (*aclp
));
123 aclp
->acl_maxcnt
= ACL_MAX_ENTRIES
;
124 aclp
->acl_cnt
= nentries
;
126 for (i
= 0; i
< nentries
; i
++) {
127 entry
= &(aclp
->acl_entry
[i
]);
130 if (ace
->a_flags
& ACE_OWNER
)
131 entry
->ae_tag
= ACL_USER_OBJ
;
132 else if (ace
->a_flags
& ACE_GROUP
)
133 entry
->ae_tag
= ACL_GROUP_OBJ
;
134 else if (ace
->a_flags
& ACE_EVERYONE
)
135 entry
->ae_tag
= ACL_EVERYONE
;
136 else if (ace
->a_flags
& ACE_IDENTIFIER_GROUP
)
137 entry
->ae_tag
= ACL_GROUP
;
139 entry
->ae_tag
= ACL_USER
;
141 if (entry
->ae_tag
== ACL_USER
|| entry
->ae_tag
== ACL_GROUP
)
142 entry
->ae_id
= ace
->a_who
;
144 entry
->ae_id
= ACL_UNDEFINED_ID
;
146 entry
->ae_perm
= _bsd_from_zfs(ace
->a_access_mask
, perms
);
147 entry
->ae_flags
= _bsd_from_zfs(ace
->a_flags
, flags
);
149 switch (ace
->a_type
) {
150 case ACE_ACCESS_ALLOWED_ACE_TYPE
:
151 entry
->ae_entry_type
= ACL_ENTRY_TYPE_ALLOW
;
153 case ACE_ACCESS_DENIED_ACE_TYPE
:
154 entry
->ae_entry_type
= ACL_ENTRY_TYPE_DENY
;
156 case ACE_SYSTEM_AUDIT_ACE_TYPE
:
157 entry
->ae_entry_type
= ACL_ENTRY_TYPE_AUDIT
;
159 case ACE_SYSTEM_ALARM_ACE_TYPE
:
160 entry
->ae_entry_type
= ACL_ENTRY_TYPE_ALARM
;
163 panic("acl_from_aces: a_type is 0x%x", ace
->a_type
);
171 aces_from_acl(ace_t
*aces
, int *nentries
, const struct acl
*aclp
)
174 const struct acl_entry
*entry
;
177 memset(aces
, 0, sizeof (*aces
) * aclp
->acl_cnt
);
179 *nentries
= aclp
->acl_cnt
;
181 for (i
= 0; i
< aclp
->acl_cnt
; i
++) {
182 entry
= &(aclp
->acl_entry
[i
]);
185 ace
->a_who
= entry
->ae_id
;
187 if (entry
->ae_tag
== ACL_USER_OBJ
)
188 ace
->a_flags
= ACE_OWNER
;
189 else if (entry
->ae_tag
== ACL_GROUP_OBJ
)
190 ace
->a_flags
= (ACE_GROUP
| ACE_IDENTIFIER_GROUP
);
191 else if (entry
->ae_tag
== ACL_GROUP
)
192 ace
->a_flags
= ACE_IDENTIFIER_GROUP
;
193 else if (entry
->ae_tag
== ACL_EVERYONE
)
194 ace
->a_flags
= ACE_EVERYONE
;
198 ace
->a_access_mask
= _zfs_from_bsd(entry
->ae_perm
, perms
);
199 ace
->a_flags
|= _zfs_from_bsd(entry
->ae_flags
, flags
);
201 switch (entry
->ae_entry_type
) {
202 case ACL_ENTRY_TYPE_ALLOW
:
203 ace
->a_type
= ACE_ACCESS_ALLOWED_ACE_TYPE
;
205 case ACL_ENTRY_TYPE_DENY
:
206 ace
->a_type
= ACE_ACCESS_DENIED_ACE_TYPE
;
208 case ACL_ENTRY_TYPE_ALARM
:
209 ace
->a_type
= ACE_SYSTEM_ALARM_ACE_TYPE
;
211 case ACL_ENTRY_TYPE_AUDIT
:
212 ace
->a_type
= ACE_SYSTEM_AUDIT_ACE_TYPE
;
215 panic("aces_from_acl: ae_entry_type is 0x%x",
216 entry
->ae_entry_type
);