5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /*
28 * ACL support for smbfs
29 */
30
31 #include <sys/systm.h> /* bcopy, ... */
32 #include <sys/errno.h>
33 #include <sys/cred.h>
34 #include <sys/cmn_err.h>
35 #include <sys/kmem.h>
36 #include <sys/sunddi.h>
37 #include <sys/acl.h>
38 #include <sys/vnode.h>
39 #include <sys/vfs.h>
40 #include <sys/byteorder.h>
41
42 #include <netsmb/mchain.h>
43 #include <netsmb/smb.h>
44 #include <netsmb/smb_conn.h>
52 #include <sys/fs/smbfs_ioctl.h>
53 #include <fs/fs_subr.h>
54 #include "smbfs_ntacl.h"
55
56 /* Sanity check SD sizes */
57 #define MAX_RAW_SD_SIZE 32768
58 #define SMALL_SD_SIZE 1024
59
60 /*
61 * smbfs_getsd() is a common function used by both
62 * smbfs_ioctl SMBFSIO_GETSD and VOP_GETSECATTR.
63 * Handles required rights, tmpopen/tmpclose.
64 *
65 * Note: smbfs_getsd allocates and returns an mblk chain,
66 * which the caller must free.
67 */
68 static int
69 smbfs_getsd(vnode_t *vp, uint32_t selector, mblk_t **mp, cred_t *cr)
70 {
71 struct smb_cred scred;
72 int error, cerror;
73 smbmntinfo_t *smi;
74 smbnode_t *np;
75 u_int16_t fid = SMB_FID_UNUSED;
76 uint32_t sdlen = SMALL_SD_SIZE;
77 uint32_t rights = STD_RIGHT_READ_CONTROL_ACCESS;
78
79 if (selector & SACL_SECURITY_INFORMATION)
80 rights |= SEC_RIGHT_SYSTEM_SECURITY;
81
82 np = VTOSMB(vp);
83 smi = VTOSMI(vp);
84
85 /* Shared lock for (possible) n_fid use. */
86 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp)))
87 return (EINTR);
88 smb_credinit(&scred, cr);
89
90 error = smbfs_smb_tmpopen(np, rights, &scred, &fid);
91 if (error)
92 goto out;
93
94 again:
95 /*
96 * This does the OTW Get
97 */
98 error = smbfs_smb_getsec_m(smi->smi_share, fid,
99 &scred, selector, mp, &sdlen);
100 /*
101 * Server may give us an error indicating that we
102 * need a larger data buffer to receive the SD,
103 * and the size we'll need. Use the given size,
104 * but only after a sanity check.
105 *
106 * Let's check for specific error values here.
107 * The NT error is: STATUS_BUFFER_TOO_SMALL,
108 * or with old error codes, one of these:
109 * ERRSRV/ERRnoroom, ERRDOS/122, ERRDOS/111
110 * Those are mapped to: EMOREDATA, which is
111 * later converted to E2BIG.
112 */
113 if (error == E2BIG &&
114 sdlen > SMALL_SD_SIZE &&
115 sdlen <= MAX_RAW_SD_SIZE)
116 goto again;
117
118 cerror = smbfs_smb_tmpclose(np, fid, &scred);
119 if (cerror)
120 SMBVDEBUG("error %d closing file %s\n",
121 cerror, np->n_rpath);
122
123 out:
124 smb_credrele(&scred);
125 smbfs_rw_exit(&np->r_lkserlock);
126
127 return (error);
128 }
129
130 /*
131 * smbfs_setsd() is a common function used by both
132 * smbfs_ioctl SMBFSIO_SETSD and VOP_SETSECATTR.
133 * Handles required rights, tmpopen/tmpclose.
134 *
135 * Note: smbfs_setsd _consumes_ the passed *mp and
136 * clears the pointer (so the caller won't free it)
137 */
138 static int
139 smbfs_setsd(vnode_t *vp, uint32_t selector, mblk_t **mp, cred_t *cr)
140 {
141 struct smb_cred scred;
142 int error, cerror;
143 smbmntinfo_t *smi;
144 smbnode_t *np;
145 uint32_t rights;
146 u_int16_t fid = SMB_FID_UNUSED;
147
148 np = VTOSMB(vp);
149 smi = VTOSMI(vp);
150
151 /*
152 * Which parts of the SD are we setting?
153 * What rights do we need for that?
154 */
155 if (selector == 0)
156 return (0);
157
158 rights = 0;
159 if (selector & (OWNER_SECURITY_INFORMATION |
160 GROUP_SECURITY_INFORMATION))
161 rights |= STD_RIGHT_WRITE_OWNER_ACCESS;
162 if (selector & DACL_SECURITY_INFORMATION)
163 rights |= STD_RIGHT_WRITE_DAC_ACCESS;
164 if (selector & SACL_SECURITY_INFORMATION)
165 rights |= SEC_RIGHT_SYSTEM_SECURITY;
166
167 /* Shared lock for (possible) n_fid use. */
168 if (smbfs_rw_enter_sig(&np->r_lkserlock, RW_READER, SMBINTR(vp)))
169 return (EINTR);
170 smb_credinit(&scred, cr);
171
172 error = smbfs_smb_tmpopen(np, rights, &scred, &fid);
173 if (error)
174 goto out;
175
176 /*
177 * We're setting the remote ACL now, so
178 * invalidate our cached ACL just in case
179 * the server doesn't do exactly as we ask.
180 */
181 mutex_enter(&np->r_statelock);
182 np->r_sectime = gethrtime();
183 mutex_exit(&np->r_statelock);
184
185 /*
186 * This does the OTW Set
187 */
188 error = smbfs_smb_setsec_m(smi->smi_share, fid,
189 &scred, selector, mp);
190
191 cerror = smbfs_smb_tmpclose(np, fid, &scred);
192 if (cerror)
193 SMBVDEBUG("error %d closing file %s\n",
194 cerror, np->n_rpath);
195
196 out:
197 smb_credrele(&scred);
198 smbfs_rw_exit(&np->r_lkserlock);
199
200 return (error);
201 }
202
203 /*
204 * Helper for VOP_IOCTL: SMBFSIO_GETSD
205 */
206 int
207 smbfs_acl_iocget(vnode_t *vp, intptr_t arg, int flag, cred_t *cr)
208 {
209 ioc_sdbuf_t iocb;
210 mdchain_t *mdp, md_store;
211 mblk_t *m;
212 void *ubuf;
213 int error;
214
215 /*
216 * Get the buffer information
217 */
218 if (ddi_copyin((void *)arg, &iocb, sizeof (iocb), flag))
|
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
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.
12 *
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]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 *
26 * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
27 */
28
29 /*
30 * ACL support for smbfs
31 */
32
33 #include <sys/systm.h> /* bcopy, ... */
34 #include <sys/errno.h>
35 #include <sys/cred.h>
36 #include <sys/cmn_err.h>
37 #include <sys/kmem.h>
38 #include <sys/sunddi.h>
39 #include <sys/acl.h>
40 #include <sys/vnode.h>
41 #include <sys/vfs.h>
42 #include <sys/byteorder.h>
43
44 #include <netsmb/mchain.h>
45 #include <netsmb/smb.h>
46 #include <netsmb/smb_conn.h>
54 #include <sys/fs/smbfs_ioctl.h>
55 #include <fs/fs_subr.h>
56 #include "smbfs_ntacl.h"
57
58 /* Sanity check SD sizes */
59 #define MAX_RAW_SD_SIZE 32768
60 #define SMALL_SD_SIZE 1024
61
62 /*
63 * smbfs_getsd() is a common function used by both
64 * smbfs_ioctl SMBFSIO_GETSD and VOP_GETSECATTR.
65 * Handles required rights, tmpopen/tmpclose.
66 *
67 * Note: smbfs_getsd allocates and returns an mblk chain,
68 * which the caller must free.
69 */
70 static int
71 smbfs_getsd(vnode_t *vp, uint32_t selector, mblk_t **mp, cred_t *cr)
72 {
73 struct smb_cred scred;
74 smbmntinfo_t *smi;
75 smbnode_t *np;
76 smb_fh_t *fid = NULL;
77 uint32_t sdlen = SMALL_SD_SIZE;
78 uint32_t rights = STD_RIGHT_READ_CONTROL_ACCESS;
79 int error;
80
81 if (selector & SACL_SECURITY_INFORMATION)
82 rights |= SEC_RIGHT_SYSTEM_SECURITY;
83
84 np = VTOSMB(vp);
85 smi = VTOSMI(vp);
86
87 smb_credinit(&scred, cr);
88
89 error = smbfs_smb_tmpopen(np, rights, &scred, &fid);
90 if (error)
91 goto out;
92
93 again:
94 /*
95 * This does the OTW Get
96 */
97 error = smbfs_smb_getsec(smi->smi_share, fid,
98 selector, mp, &sdlen, &scred);
99 /*
100 * Server may give us an error indicating that we
101 * need a larger data buffer to receive the SD,
102 * and the size we'll need. Use the given size,
103 * but only after a sanity check.
104 *
105 * Let's check for specific error values here.
106 * The NT error is: STATUS_BUFFER_TOO_SMALL,
107 * or with old error codes, one of these:
108 * ERRSRV/ERRnoroom, ERRDOS/122, ERRDOS/111
109 * Those are mapped to: EMOREDATA, which is
110 * later converted to E2BIG.
111 */
112 if (error == E2BIG &&
113 sdlen > SMALL_SD_SIZE &&
114 sdlen <= MAX_RAW_SD_SIZE)
115 goto again;
116
117 smbfs_smb_tmpclose(np, fid);
118
119 out:
120 smb_credrele(&scred);
121
122 return (error);
123 }
124
125 /*
126 * smbfs_setsd() is a common function used by both
127 * smbfs_ioctl SMBFSIO_SETSD and VOP_SETSECATTR.
128 * Handles required rights, tmpopen/tmpclose.
129 *
130 * Note: smbfs_setsd _consumes_ the passed *mp and
131 * clears the pointer (so the caller won't free it)
132 */
133 static int
134 smbfs_setsd(vnode_t *vp, uint32_t selector, mblk_t **mp, cred_t *cr)
135 {
136 struct smb_cred scred;
137 smbmntinfo_t *smi;
138 smbnode_t *np;
139 uint32_t rights;
140 smb_fh_t *fid = NULL;
141 int error;
142
143 np = VTOSMB(vp);
144 smi = VTOSMI(vp);
145
146 /*
147 * Which parts of the SD are we setting?
148 * What rights do we need for that?
149 */
150 if (selector == 0)
151 return (0);
152
153 rights = 0;
154 if (selector & (OWNER_SECURITY_INFORMATION |
155 GROUP_SECURITY_INFORMATION))
156 rights |= STD_RIGHT_WRITE_OWNER_ACCESS;
157 if (selector & DACL_SECURITY_INFORMATION)
158 rights |= STD_RIGHT_WRITE_DAC_ACCESS;
159 if (selector & SACL_SECURITY_INFORMATION)
160 rights |= SEC_RIGHT_SYSTEM_SECURITY;
161
162 smb_credinit(&scred, cr);
163
164 error = smbfs_smb_tmpopen(np, rights, &scred, &fid);
165 if (error)
166 goto out;
167
168 /*
169 * We're setting the remote ACL now, so
170 * invalidate our cached ACL just in case
171 * the server doesn't do exactly as we ask.
172 */
173 mutex_enter(&np->r_statelock);
174 np->r_sectime = gethrtime();
175 mutex_exit(&np->r_statelock);
176
177 /*
178 * This does the OTW Set
179 */
180 error = smbfs_smb_setsec(smi->smi_share, fid,
181 selector, mp, &scred);
182
183 smbfs_smb_tmpclose(np, fid);
184
185 out:
186 smb_credrele(&scred);
187
188 return (error);
189 }
190
191 /*
192 * Helper for VOP_IOCTL: SMBFSIO_GETSD
193 */
194 int
195 smbfs_acl_iocget(vnode_t *vp, intptr_t arg, int flag, cred_t *cr)
196 {
197 ioc_sdbuf_t iocb;
198 mdchain_t *mdp, md_store;
199 mblk_t *m;
200 void *ubuf;
201 int error;
202
203 /*
204 * Get the buffer information
205 */
206 if (ddi_copyin((void *)arg, &iocb, sizeof (iocb), flag))
|