4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
31 #include <sys/types.h>
32 #include <sys/errno.h>
34 #include <sys/cmn_err.h>
36 #include <sys/sunddi.h>
38 #include <sys/vnode.h>
40 #include <sys/byteorder.h>
50 #include <sys/fs/smbfs_ioctl.h>
52 #include <netsmb/smb.h>
53 #include <netsmb/smb_lib.h>
54 #include <netsmb/smbfs_acl.h>
56 #include "smbfs_ntacl.h"
59 /* Sanity check SD sizes */
60 #define MAX_RAW_SD_SIZE 32768
62 /* XXX: acl_common.h */
63 acl_t
*acl_alloc(enum acl_type
);
64 void acl_free(acl_t
*);
68 * Get/set a Windows security descriptor (SD)
69 * using the (private) smbfs ioctl mechanism.
70 * Note: Get allocates mbp->mb_top
75 smbfs_acl_iocget(int fd
, uint32_t selector
, mbdata_t
*mbp
)
81 error
= mb_init_sz(mbp
, MAX_RAW_SD_SIZE
);
86 iocb
.addr
= mtod(m
, uintptr_t);
87 iocb
.alloc
= m
->m_maxlen
;
89 iocb
.selector
= selector
;
92 * This does the OTW Get.
94 if (ioctl(fd
, SMBFSIO_GETSD
, &iocb
) < 0) {
109 smbfs_acl_iocset(int fd
, uint32_t selector
, mbdata_t
*mbp
)
115 /* Make the data contiguous. */
116 error
= m_lineup(mbp
->mb_top
, &m
);
120 if (mbp
->mb_top
!= m
)
123 iocb
.addr
= mtod(m
, uintptr_t);
124 iocb
.alloc
= m
->m_maxlen
;
125 iocb
.used
= m
->m_len
;
126 iocb
.selector
= selector
;
129 * This does the OTW Set.
131 if (ioctl(fd
, SMBFSIO_SETSD
, &iocb
) < 0)
138 * Get an NT SD from the open file via ioctl.
141 smbfs_acl_getsd(int fd
, uint32_t selector
, i_ntsd_t
**sdp
)
143 mbdata_t
*mbp
, mb_store
;
147 bzero(mbp
, sizeof (*mbp
));
150 * Get the raw Windows SD via ioctl.
151 * Returns allocated mbchain in mbp.
153 error
= smbfs_acl_iocget(fd
, selector
, mbp
);
156 * Import the raw SD into "internal" form.
157 * (like "absolute" form per. NT docs)
158 * Returns allocated data in sdp
160 error
= md_get_ntsd(mbp
, sdp
);
168 * Set an NT SD onto the open file via ioctl.
171 smbfs_acl_setsd(int fd
, uint32_t selector
, i_ntsd_t
*sd
)
173 mbdata_t
*mbp
, mb_store
;
177 error
= mb_init_sz(mbp
, MAX_RAW_SD_SIZE
);
182 * Export the "internal" SD into an mb chain.
183 * (a.k.a "self-relative" form per. NT docs)
184 * Returns allocated mbchain in mbp.
186 error
= mb_put_ntsd(mbp
, sd
);
189 * Set the raw Windows SD via ioctl.
191 error
= smbfs_acl_iocset(fd
, selector
, mbp
);
202 * Convenience function to Get security using a
203 * ZFS-style ACL (libsec acl, type=ACE_T)
204 * Intentionally similar to: facl_get(3SEC)
207 smbfs_acl_get(int fd
, acl_t
**aclp
, uid_t
*uidp
, gid_t
*gidp
)
215 * Which parts of the SD are being requested?
216 * XXX: Should we request the SACL too? If so,
217 * might that cause this access to be denied?
218 * Or maybe: if we get access denied, try the
219 * open/fetch again without the SACL bit.
223 selector
|= DACL_SECURITY_INFORMATION
;
225 selector
|= OWNER_SECURITY_INFORMATION
;
227 selector
|= GROUP_SECURITY_INFORMATION
;
233 * Get the Windows SD via ioctl, in
234 * "internal" (absolute) form.
236 error
= smbfs_acl_getsd(fd
, selector
, &sd
);
239 /* Note: sd now holds allocated data. */
242 * Convert the internal SD to a ZFS ACL.
243 * Get uid/gid too if pointers != NULL.
246 acl
= acl_alloc(ACE_T
);
252 error
= smbfs_acl_sd2zfs(sd
, acl
, uidp
, gidp
);
265 smbfs_acl_free_sd(sd
);
270 * Convenience function to Set security using a
271 * ZFS-style ACL (libsec acl, type=ACE_T)
272 * Intentionally similar to: facl_set(3SEC)
275 smbfs_acl_set(int fd
, acl_t
*acl
, uid_t uid
, gid_t gid
)
282 if (acl
&& acl
->acl_type
!= ACE_T
)
286 * Which parts of the SD are being modified?
287 * XXX: Ditto comments above re. SACL.
291 selector
|= DACL_SECURITY_INFORMATION
;
292 if (uid
!= (uid_t
)-1)
293 selector
|= OWNER_SECURITY_INFORMATION
;
294 if (gid
!= (gid_t
)-1)
295 selector
|= GROUP_SECURITY_INFORMATION
;
299 if (uid
== (uid_t
)-1 || gid
== (gid_t
)-1) {
301 * If not setting owner or group, we need the
302 * current owner and group for translating
303 * references via owner@ or group@ ACEs.
305 if (fstat(fd
, &st
) != 0)
307 if (uid
== (uid_t
)-1)
309 if (gid
== (gid_t
)-1)
314 * Convert the ZFS ACL to an internal SD.
315 * Returns allocated data in sd
317 error
= smbfs_acl_zfs2sd(acl
, uid
, gid
, selector
, &sd
);
319 error
= smbfs_acl_setsd(fd
, selector
, sd
);
321 smbfs_acl_free_sd(sd
);