14bff34e3Sthurlow /*
24bff34e3Sthurlow * Copyright (c) 2000-2001 Boris Popov
34bff34e3Sthurlow * All rights reserved.
44bff34e3Sthurlow *
54bff34e3Sthurlow * Redistribution and use in source and binary forms, with or without
64bff34e3Sthurlow * modification, are permitted provided that the following conditions
74bff34e3Sthurlow * are met:
84bff34e3Sthurlow * 1. Redistributions of source code must retain the above copyright
94bff34e3Sthurlow * notice, this list of conditions and the following disclaimer.
104bff34e3Sthurlow * 2. Redistributions in binary form must reproduce the above copyright
114bff34e3Sthurlow * notice, this list of conditions and the following disclaimer in the
124bff34e3Sthurlow * documentation and/or other materials provided with the distribution.
134bff34e3Sthurlow * 3. All advertising materials mentioning features or use of this software
144bff34e3Sthurlow * must display the following acknowledgement:
154bff34e3Sthurlow * This product includes software developed by Boris Popov.
164bff34e3Sthurlow * 4. Neither the name of the author nor the names of any co-contributors
174bff34e3Sthurlow * may be used to endorse or promote products derived from this software
184bff34e3Sthurlow * without specific prior written permission.
194bff34e3Sthurlow *
204bff34e3Sthurlow * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
214bff34e3Sthurlow * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
224bff34e3Sthurlow * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
234bff34e3Sthurlow * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
244bff34e3Sthurlow * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
254bff34e3Sthurlow * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
264bff34e3Sthurlow * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
274bff34e3Sthurlow * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
284bff34e3Sthurlow * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
294bff34e3Sthurlow * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
304bff34e3Sthurlow * SUCH DAMAGE.
314bff34e3Sthurlow */
324bff34e3Sthurlow
334bff34e3Sthurlow /*
34613a2f6bSGordon Ross * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
354bff34e3Sthurlow * Use is subject to license terms.
368329232eSGordon Ross *
37*168091e5SGordon Ross * Copyright 2021 Tintri by DDN, Inc. All rights reserved.
384bff34e3Sthurlow */
394bff34e3Sthurlow
404bff34e3Sthurlow #include <sys/param.h>
414bff34e3Sthurlow #include <sys/systm.h>
428329232eSGordon Ross #include <sys/inttypes.h>
434bff34e3Sthurlow #include <sys/time.h>
444bff34e3Sthurlow #include <sys/vnode.h>
45613a2f6bSGordon Ross #include <sys/sunddi.h>
464bff34e3Sthurlow #include <sys/cmn_err.h>
474bff34e3Sthurlow
484bff34e3Sthurlow #include <netsmb/smb_osdep.h>
494bff34e3Sthurlow
504bff34e3Sthurlow #include <netsmb/smb.h>
51adee6784SGordon Ross #include <netsmb/smb2.h>
524bff34e3Sthurlow #include <netsmb/smb_conn.h>
534bff34e3Sthurlow #include <netsmb/smb_subr.h>
544bff34e3Sthurlow #include <netsmb/smb_rq.h>
554bff34e3Sthurlow
564bff34e3Sthurlow #include <smbfs/smbfs.h>
574bff34e3Sthurlow #include <smbfs/smbfs_node.h>
584bff34e3Sthurlow #include <smbfs/smbfs_subr.h>
594bff34e3Sthurlow
6002d09e03SGordon Ross /*
6102d09e03SGordon Ross * Jan 1 1980 as 64 bit NT time.
6202d09e03SGordon Ross * (tenths of microseconds since 1601)
6302d09e03SGordon Ross */
6402d09e03SGordon Ross const uint64_t NT1980 = 11960035200ULL*10000000ULL;
6502d09e03SGordon Ross
664bff34e3Sthurlow
674bff34e3Sthurlow /*
68adee6784SGordon Ross * Helper for smbfs_getattr_otw
69adee6784SGordon Ross * used when we have an open FID
704bff34e3Sthurlow */
714bff34e3Sthurlow int
smbfs_smb_getfattr(struct smbnode * np,smb_fh_t * fhp,struct smbfattr * fap,struct smb_cred * scrp)724bff34e3Sthurlow smbfs_smb_getfattr(
734bff34e3Sthurlow struct smbnode *np,
74adee6784SGordon Ross smb_fh_t *fhp,
754bff34e3Sthurlow struct smbfattr *fap,
764bff34e3Sthurlow struct smb_cred *scrp)
774bff34e3Sthurlow {
78adee6784SGordon Ross struct smb_share *ssp = np->n_mount->smi_share;
794bff34e3Sthurlow int error;
804bff34e3Sthurlow
81adee6784SGordon Ross if (SSTOVC(ssp)->vc_flags & SMBV_SMB2) {
82adee6784SGordon Ross error = smbfs_smb2_qfileinfo(ssp, &fhp->fh_fid2, fap, scrp);
83adee6784SGordon Ross } else {
84adee6784SGordon Ross error = smbfs_smb1_trans2_query(np, fhp->fh_fid1, fap, scrp);
8591d632c8Sgwr }
8691d632c8Sgwr
874bff34e3Sthurlow return (error);
884bff34e3Sthurlow }
894bff34e3Sthurlow
904bff34e3Sthurlow /*
91adee6784SGordon Ross * Helper for smbfs_getattr_otw
92adee6784SGordon Ross * used when we don't have an open FID
93adee6784SGordon Ross *
94adee6784SGordon Ross * For SMB1 we can just use the path form of trans2 query.
95adee6784SGordon Ross * For SMB2 we need to do an attribute-only open.
96adee6784SGordon Ross * See smbfs_smb2_getpattr()
974bff34e3Sthurlow */
984bff34e3Sthurlow int
smbfs_smb_getpattr(struct smbnode * np,struct smbfattr * fap,struct smb_cred * scrp)99adee6784SGordon Ross smbfs_smb_getpattr(
100adee6784SGordon Ross struct smbnode *np,
101adee6784SGordon Ross struct smbfattr *fap,
102adee6784SGordon Ross struct smb_cred *scrp)
1034bff34e3Sthurlow {
1044bff34e3Sthurlow struct smb_share *ssp = np->n_mount->smi_share;
105adee6784SGordon Ross int error;
10602d09e03SGordon Ross
107adee6784SGordon Ross if (SSTOVC(ssp)->vc_flags & SMBV_SMB2) {
108adee6784SGordon Ross error = smbfs_smb2_getpattr(np, fap, scrp);
109adee6784SGordon Ross } else {
110adee6784SGordon Ross uint16_t fid = SMB_FID_UNUSED;
111adee6784SGordon Ross error = smbfs_smb1_trans2_query(np, fid, fap, scrp);
1124bff34e3Sthurlow }
11302d09e03SGordon Ross
1144bff34e3Sthurlow return (error);
1154bff34e3Sthurlow }
1164bff34e3Sthurlow
1174bff34e3Sthurlow /*
118adee6784SGordon Ross * Get and parse FileFsAttributeInformation
1194bff34e3Sthurlow */
1204bff34e3Sthurlow int
smbfs_smb_qfsattr(struct smb_share * ssp,struct smb_fs_attr_info * fsa,struct smb_cred * scrp)121613a2f6bSGordon Ross smbfs_smb_qfsattr(struct smb_share *ssp, struct smb_fs_attr_info *fsa,
122613a2f6bSGordon Ross struct smb_cred *scrp)
1234bff34e3Sthurlow {
1244bff34e3Sthurlow int error;
125613a2f6bSGordon Ross
126adee6784SGordon Ross if (SSTOVC(ssp)->vc_flags & SMBV_SMB2) {
127adee6784SGordon Ross error = smbfs_smb2_qfsattr(ssp, fsa, scrp);
128613a2f6bSGordon Ross } else {
129adee6784SGordon Ross error = smbfs_smb1_qfsattr(ssp, fsa, scrp);
1304bff34e3Sthurlow }
131613a2f6bSGordon Ross
13202d09e03SGordon Ross /*
13302d09e03SGordon Ross * If fs_name starts with FAT, we can't set dates before 1980
13402d09e03SGordon Ross */
13502d09e03SGordon Ross if (0 == strncmp(fsa->fsa_tname, "FAT", 3)) {
13602d09e03SGordon Ross SMB_SS_LOCK(ssp);
13702d09e03SGordon Ross ssp->ss_flags |= SMBS_FST_FAT;
13802d09e03SGordon Ross SMB_SS_UNLOCK(ssp);
13902d09e03SGordon Ross }
14002d09e03SGordon Ross
141adee6784SGordon Ross return (error);
1424bff34e3Sthurlow }
1434bff34e3Sthurlow
1444bff34e3Sthurlow int
smbfs_smb_statfs(struct smb_share * ssp,statvfs64_t * sbp,struct smb_cred * scp)1454bff34e3Sthurlow smbfs_smb_statfs(struct smb_share *ssp, statvfs64_t *sbp,
1464bff34e3Sthurlow struct smb_cred *scp)
1474bff34e3Sthurlow {
148adee6784SGordon Ross struct smb_fs_size_info info;
149adee6784SGordon Ross struct smb_vc *vcp = SSTOVC(ssp);
150adee6784SGordon Ross uint32_t bps, spu;
1514bff34e3Sthurlow int error;
1524bff34e3Sthurlow
153adee6784SGordon Ross if (vcp->vc_flags & SMBV_SMB2) {
154adee6784SGordon Ross error = smbfs_smb2_statfs(ssp, &info, scp);
155adee6784SGordon Ross } else {
156adee6784SGordon Ross error = smbfs_smb1_statfs(ssp, &info, scp);
157adee6784SGordon Ross }
158adee6784SGordon Ross if (error)
159adee6784SGordon Ross return (error);
160adee6784SGordon Ross
161adee6784SGordon Ross /* A bit of paranoia. */
162adee6784SGordon Ross bps = info.bytes_per_sect;
163adee6784SGordon Ross if (bps < DEV_BSIZE)
164adee6784SGordon Ross bps = DEV_BSIZE;
165adee6784SGordon Ross spu = info.sect_per_unit;
166adee6784SGordon Ross if (spu == 0)
167adee6784SGordon Ross spu = 1;
168adee6784SGordon Ross
169adee6784SGordon Ross /* preferred file system block size */
170adee6784SGordon Ross sbp->f_bsize = bps * spu;
171adee6784SGordon Ross
172adee6784SGordon Ross /* file system block size ("fragment size") */
173adee6784SGordon Ross sbp->f_frsize = bps;
174adee6784SGordon Ross
175adee6784SGordon Ross /* total blocks of f_frsize */
176adee6784SGordon Ross sbp->f_blocks = info.total_units * spu;
177adee6784SGordon Ross
178adee6784SGordon Ross /* free blocks of f_frsize */
179adee6784SGordon Ross sbp->f_bfree = info.actual_avail * spu;
180adee6784SGordon Ross
181adee6784SGordon Ross /* free blocks avail to non-superuser */
182adee6784SGordon Ross sbp->f_bavail = info.caller_avail * spu;
183adee6784SGordon Ross
184adee6784SGordon Ross sbp->f_files = (-1); /* total file nodes in file system */
185adee6784SGordon Ross sbp->f_ffree = (-1); /* free file nodes in fs */
1864bff34e3Sthurlow
1874bff34e3Sthurlow return (error);
1884bff34e3Sthurlow }
1894bff34e3Sthurlow
1904bff34e3Sthurlow int
smbfs_smb_setdisp(struct smb_share * ssp,smb_fh_t * fhp,uint8_t disp,struct smb_cred * scrp)191adee6784SGordon Ross smbfs_smb_setdisp(struct smb_share *ssp, smb_fh_t *fhp,
192adee6784SGordon Ross uint8_t disp, struct smb_cred *scrp)
1934bff34e3Sthurlow {
194adee6784SGordon Ross int err;
19502d09e03SGordon Ross
196adee6784SGordon Ross if (SSTOVC(ssp)->vc_flags & SMBV_SMB2) {
197adee6784SGordon Ross err = smbfs_smb2_setdisp(ssp, &fhp->fh_fid2, disp, scrp);
198adee6784SGordon Ross } else {
199adee6784SGordon Ross err = smbfs_smb1_setdisp(ssp, fhp->fh_fid1, disp, scrp);
2004bff34e3Sthurlow }
20102d09e03SGordon Ross
202adee6784SGordon Ross return (err);
2034bff34e3Sthurlow }
2044bff34e3Sthurlow
2054bff34e3Sthurlow int
smbfs_smb_setfsize(struct smb_share * ssp,smb_fh_t * fhp,uint64_t size,struct smb_cred * scrp)206adee6784SGordon Ross smbfs_smb_setfsize(struct smb_share *ssp, smb_fh_t *fhp,
207adee6784SGordon Ross uint64_t size, struct smb_cred *scrp)
2084bff34e3Sthurlow {
2094bff34e3Sthurlow int error;
2104bff34e3Sthurlow
211adee6784SGordon Ross if (SSTOVC(ssp)->vc_flags & SMBV_SMB2) {
212adee6784SGordon Ross error = smbfs_smb2_seteof(ssp, &fhp->fh_fid2, size, scrp);
213adee6784SGordon Ross } else {
214adee6784SGordon Ross error = smbfs_smb1_seteof(ssp, fhp->fh_fid1, size, scrp);
2154bff34e3Sthurlow }
21602d09e03SGordon Ross
217adee6784SGordon Ross return (error);
2184bff34e3Sthurlow }
2194bff34e3Sthurlow
220adee6784SGordon Ross
221adee6784SGordon Ross /*
222adee6784SGordon Ross * Set file attributes (optionally: DOS attr, atime, mtime)
223adee6784SGordon Ross * Always have an open FID with set attr rights.
224adee6784SGordon Ross */
2254bff34e3Sthurlow int
smbfs_smb_setfattr(struct smb_share * ssp,smb_fh_t * fhp,uint32_t attr,struct timespec * mtime,struct timespec * atime,struct smb_cred * scrp)226adee6784SGordon Ross smbfs_smb_setfattr(
227adee6784SGordon Ross struct smb_share *ssp,
228adee6784SGordon Ross smb_fh_t *fhp,
229adee6784SGordon Ross uint32_t attr,
230adee6784SGordon Ross struct timespec *mtime,
231adee6784SGordon Ross struct timespec *atime,
232adee6784SGordon Ross struct smb_cred *scrp)
2334bff34e3Sthurlow {
234adee6784SGordon Ross struct mbchain mb_info;
235adee6784SGordon Ross struct mbchain *mbp = &mb_info;
236adee6784SGordon Ross uint64_t tm;
2374bff34e3Sthurlow int error;
2384bff34e3Sthurlow
239adee6784SGordon Ross /*
240adee6784SGordon Ross * Build a struct FILE_BASIC_INFORMATION in mbp
241adee6784SGordon Ross * LARGE_INTEGER CreationTime;
242adee6784SGordon Ross * LARGE_INTEGER LastAccessTime;
243adee6784SGordon Ross * LARGE_INTEGER LastWriteTime;
244adee6784SGordon Ross * LARGE_INTEGER ChangeTime;
245adee6784SGordon Ross * ULONG FileAttributes;
246adee6784SGordon Ross * Zero in times means "no change".
247adee6784SGordon Ross */
2484bff34e3Sthurlow mb_init(mbp);
249adee6784SGordon Ross mb_put_uint64le(mbp, 0); /* creation time */
250adee6784SGordon Ross if (atime) {
251adee6784SGordon Ross smb_time_local2NT(atime, &tm);
252adee6784SGordon Ross if (tm != 0 && (ssp->ss_flags & SMBS_FST_FAT) &&
253adee6784SGordon Ross tm < NT1980)
254adee6784SGordon Ross tm = NT1980;
255adee6784SGordon Ross } else
256adee6784SGordon Ross tm = 0;
257adee6784SGordon Ross mb_put_uint64le(mbp, tm); /* last access time */
258adee6784SGordon Ross if (mtime) {
259adee6784SGordon Ross smb_time_local2NT(mtime, &tm);
260adee6784SGordon Ross if (tm != 0 && (ssp->ss_flags & SMBS_FST_FAT) &&
261adee6784SGordon Ross tm < NT1980)
262adee6784SGordon Ross tm = NT1980;
263adee6784SGordon Ross } else
264adee6784SGordon Ross tm = 0;
265adee6784SGordon Ross mb_put_uint64le(mbp, tm); /* last write time */
266adee6784SGordon Ross mb_put_uint64le(mbp, 0); /* change time */
267adee6784SGordon Ross mb_put_uint32le(mbp, attr);
2688a2c2d71SGordon Ross mb_put_uint32le(mbp, 0); /* reserved */
269adee6784SGordon Ross
270adee6784SGordon Ross if (SSTOVC(ssp)->vc_flags & SMBV_SMB2) {
271adee6784SGordon Ross error = smbfs_smb2_setfattr(ssp, &fhp->fh_fid2, mbp, scrp);
272adee6784SGordon Ross } else {
273adee6784SGordon Ross error = smbfs_smb1_setfattr(ssp, fhp->fh_fid1, mbp, scrp);
274adee6784SGordon Ross }
275adee6784SGordon Ross
2764bff34e3Sthurlow return (error);
2774bff34e3Sthurlow }
2784bff34e3Sthurlow
2794bff34e3Sthurlow int
smbfs_smb_flush(struct smb_share * ssp,smb_fh_t * fhp,struct smb_cred * scrp)280adee6784SGordon Ross smbfs_smb_flush(struct smb_share *ssp, smb_fh_t *fhp,
2818329232eSGordon Ross struct smb_cred *scrp)
2824bff34e3Sthurlow {
283ff1e230cSjilinxpd int error;
2844bff34e3Sthurlow
285adee6784SGordon Ross if (SSTOVC(ssp)->vc_flags & SMBV_SMB2) {
286adee6784SGordon Ross error = smbfs_smb2_flush(ssp, &fhp->fh_fid2, scrp);
287adee6784SGordon Ross } else {
288adee6784SGordon Ross error = smbfs_smb1_flush(ssp, fhp->fh_fid1, scrp);
289adee6784SGordon Ross }
290ff1e230cSjilinxpd return (error);
291ff1e230cSjilinxpd }
2924bff34e3Sthurlow
293ff1e230cSjilinxpd /*
294adee6784SGordon Ross * Modern create/open of file or directory.
295adee6784SGordon Ross * On success, fills in fhp->fh_fid* and fhp->fh_rights
296ff1e230cSjilinxpd */
297ff1e230cSjilinxpd int
smbfs_smb_ntcreatex(struct smbnode * np,const char * name,int nmlen,int xattr,uint32_t req_acc,uint32_t efa,uint32_t share_acc,uint32_t disp,uint32_t createopt,struct smb_cred * scrp,smb_fh_t * fhp,uint32_t * cr_act_p,struct smbfattr * fap)298adee6784SGordon Ross smbfs_smb_ntcreatex(
299adee6784SGordon Ross struct smbnode *np,
300adee6784SGordon Ross const char *name,
301adee6784SGordon Ross int nmlen,
302adee6784SGordon Ross int xattr, /* is named stream? */
303adee6784SGordon Ross uint32_t req_acc, /* requested access */
304adee6784SGordon Ross uint32_t efa, /* ext. file attrs (DOS attr +) */
305adee6784SGordon Ross uint32_t share_acc,
306adee6784SGordon Ross uint32_t disp, /* open disposition */
307adee6784SGordon Ross uint32_t createopt, /* NTCREATEX_OPTIONS_ */
308adee6784SGordon Ross struct smb_cred *scrp,
309adee6784SGordon Ross smb_fh_t *fhp, /* pre-made file handle to fill in */
310adee6784SGordon Ross uint32_t *cr_act_p, /* optional returned create action */
311adee6784SGordon Ross struct smbfattr *fap) /* optional returned attributes */
312ff1e230cSjilinxpd {
313adee6784SGordon Ross struct mbchain name_mb;
314ff1e230cSjilinxpd struct smb_share *ssp = np->n_mount->smi_share;
315adee6784SGordon Ross int err;
316ff1e230cSjilinxpd
317adee6784SGordon Ross mb_init(&name_mb);
318ff1e230cSjilinxpd
319adee6784SGordon Ross if (name == NULL)
320adee6784SGordon Ross nmlen = 0;
321adee6784SGordon Ross err = smbfs_fullpath(&name_mb, SSTOVC(ssp),
322adee6784SGordon Ross np, name, nmlen, xattr ? ':' : '\\');
323adee6784SGordon Ross if (err)
324ff1e230cSjilinxpd goto out;
3254bff34e3Sthurlow
326adee6784SGordon Ross err = smb_smb_ntcreate(ssp, &name_mb,
327adee6784SGordon Ross 0, /* NTCREATEX_FLAGS... */
328adee6784SGordon Ross req_acc, efa, share_acc, disp, createopt,
329adee6784SGordon Ross NTCREATEX_IMPERSONATION_IMPERSONATION,
330adee6784SGordon Ross scrp, fhp, cr_act_p, fap);
3314bff34e3Sthurlow
332adee6784SGordon Ross out:
333adee6784SGordon Ross mb_done(&name_mb);
334613a2f6bSGordon Ross
335adee6784SGordon Ross return (err);
3364bff34e3Sthurlow }
3374bff34e3Sthurlow
338adee6784SGordon Ross /*
339adee6784SGordon Ross * Get a file handle with (at least) the specified rights.
340adee6784SGordon Ross *
341adee6784SGordon Ross * We'll try to borrow the node ->n_fid if we can. When we
342adee6784SGordon Ross * borrow n_fid, just take a hold on the smb_fh_t, and don't
343adee6784SGordon Ross * bump n_fidrefs as that tracks VFS-level opens. Similarly
344adee6784SGordon Ross * in _tmpclose we just release the smb_fh_t, not n_fidrefs.
345adee6784SGordon Ross */
3464bff34e3Sthurlow int
smbfs_smb_tmpopen(struct smbnode * np,uint32_t rights,struct smb_cred * scrp,smb_fh_t ** fhpp)347adee6784SGordon Ross smbfs_smb_tmpopen(struct smbnode *np, uint32_t rights, struct smb_cred *scrp,
348adee6784SGordon Ross smb_fh_t **fhpp)
3494bff34e3Sthurlow {
3504bff34e3Sthurlow struct smb_share *ssp = np->n_mount->smi_share;
351adee6784SGordon Ross smb_fh_t *fhp = NULL;
3524bff34e3Sthurlow int error;
3534bff34e3Sthurlow
354613a2f6bSGordon Ross /* Can we re-use n_fid? or must we open anew? */
355adee6784SGordon Ross mutex_enter(&np->r_statelock);
356adee6784SGordon Ross if (np->n_fidrefs > 0 &&
357adee6784SGordon Ross (fhp = np->n_fid) != NULL &&
358adee6784SGordon Ross fhp->fh_vcgenid == ssp->ss_vcgenid &&
359adee6784SGordon Ross (fhp->fh_rights & rights) == rights) {
360adee6784SGordon Ross smb_fh_hold(fhp);
361adee6784SGordon Ross *fhpp = fhp;
362adee6784SGordon Ross mutex_exit(&np->r_statelock);
3634bff34e3Sthurlow return (0);
36402d09e03SGordon Ross }
365adee6784SGordon Ross mutex_exit(&np->r_statelock);
366adee6784SGordon Ross
367adee6784SGordon Ross error = smb_fh_create(ssp, &fhp);
368adee6784SGordon Ross if (error != 0)
369adee6784SGordon Ross goto out;
370adee6784SGordon Ross
371adee6784SGordon Ross /* re-open an existing file. */
372adee6784SGordon Ross error = smbfs_smb_ntcreatex(np,
373adee6784SGordon Ross NULL, 0, 0, /* name nmlen xattr */
374adee6784SGordon Ross rights, SMB_EFA_NORMAL,
375adee6784SGordon Ross NTCREATEX_SHARE_ACCESS_ALL,
376adee6784SGordon Ross NTCREATEX_DISP_OPEN,
377adee6784SGordon Ross 0, /* create options */
378adee6784SGordon Ross scrp, fhp,
379adee6784SGordon Ross NULL, NULL); /* cr_act_p fa_p */
380adee6784SGordon Ross if (error != 0)
381adee6784SGordon Ross goto out;
382adee6784SGordon Ross
383adee6784SGordon Ross fhp->fh_rights = rights;
384adee6784SGordon Ross smb_fh_opened(fhp);
385adee6784SGordon Ross *fhpp = fhp;
386adee6784SGordon Ross fhp = NULL;
387adee6784SGordon Ross
388adee6784SGordon Ross out:
389adee6784SGordon Ross if (fhp != NULL)
390adee6784SGordon Ross smb_fh_rele(fhp);
39102d09e03SGordon Ross
39202d09e03SGordon Ross return (error);
3934bff34e3Sthurlow }
3944bff34e3Sthurlow
395adee6784SGordon Ross /* ARGSUSED */
396adee6784SGordon Ross void
smbfs_smb_tmpclose(struct smbnode * np,smb_fh_t * fhp)397adee6784SGordon Ross smbfs_smb_tmpclose(struct smbnode *np, smb_fh_t *fhp)
398adee6784SGordon Ross {
399adee6784SGordon Ross smb_fh_rele(fhp);
400adee6784SGordon Ross }
401adee6784SGordon Ross
4024bff34e3Sthurlow int
smbfs_smb_open(struct smbnode * np,const char * name,int nmlen,int xattr,uint32_t rights,struct smb_cred * scrp,smb_fh_t ** fhpp,smbfattr_t * fap)403adee6784SGordon Ross smbfs_smb_open(
404adee6784SGordon Ross struct smbnode *np,
405adee6784SGordon Ross const char *name,
406adee6784SGordon Ross int nmlen,
407adee6784SGordon Ross int xattr,
408adee6784SGordon Ross uint32_t rights,
409adee6784SGordon Ross struct smb_cred *scrp,
410adee6784SGordon Ross smb_fh_t **fhpp,
411adee6784SGordon Ross smbfattr_t *fap)
4124bff34e3Sthurlow {
4134bff34e3Sthurlow struct smb_share *ssp = np->n_mount->smi_share;
414adee6784SGordon Ross // struct smb_vc *vcp = SSTOVC(ssp);
415adee6784SGordon Ross smb_fh_t *fhp = NULL;
4164bff34e3Sthurlow int error;
4174bff34e3Sthurlow
418adee6784SGordon Ross error = smb_fh_create(ssp, &fhp);
419adee6784SGordon Ross if (error != 0)
420adee6784SGordon Ross goto out;
4214bff34e3Sthurlow
422adee6784SGordon Ross /* open an existing file */
423adee6784SGordon Ross error = smbfs_smb_ntcreatex(np,
424adee6784SGordon Ross name, nmlen, xattr,
425adee6784SGordon Ross rights, SMB_EFA_NORMAL,
426adee6784SGordon Ross NTCREATEX_SHARE_ACCESS_ALL,
427adee6784SGordon Ross NTCREATEX_DISP_OPEN,
428adee6784SGordon Ross 0, /* create options */
429adee6784SGordon Ross scrp, fhp, NULL, fap);
430adee6784SGordon Ross if (error != 0)
431adee6784SGordon Ross goto out;
4324bff34e3Sthurlow
433adee6784SGordon Ross fhp->fh_rights = rights;
434adee6784SGordon Ross smb_fh_opened(fhp);
435adee6784SGordon Ross *fhpp = fhp;
436adee6784SGordon Ross fhp = NULL;
4374bff34e3Sthurlow
438adee6784SGordon Ross out:
439adee6784SGordon Ross if (fhp != NULL)
440adee6784SGordon Ross smb_fh_rele(fhp);
44191d632c8Sgwr
442*168091e5SGordon Ross return (error);
4434bff34e3Sthurlow }
4444bff34e3Sthurlow
445adee6784SGordon Ross void
smbfs_smb_close(smb_fh_t * fhp)446adee6784SGordon Ross smbfs_smb_close(smb_fh_t *fhp)
4474bff34e3Sthurlow {
4484bff34e3Sthurlow
449adee6784SGordon Ross smb_fh_close(fhp);
450adee6784SGordon Ross smb_fh_rele(fhp);
4514bff34e3Sthurlow }
4524bff34e3Sthurlow
453adee6784SGordon Ross int
smbfs_smb_create(struct smbnode * dnp,const char * name,int nmlen,int xattr,uint32_t disp,struct smb_cred * scrp,smb_fh_t ** fhpp)454adee6784SGordon Ross smbfs_smb_create(
455adee6784SGordon Ross struct smbnode *dnp,
456adee6784SGordon Ross const char *name,
457adee6784SGordon Ross int nmlen,
458adee6784SGordon Ross int xattr,
459adee6784SGordon Ross uint32_t disp,
460adee6784SGordon Ross struct smb_cred *scrp,
461adee6784SGordon Ross smb_fh_t **fhpp)
4624bff34e3Sthurlow {
463adee6784SGordon Ross struct smb_share *ssp = dnp->n_mount->smi_share;
464adee6784SGordon Ross // struct smb_vc *vcp = SSTOVC(ssp);
465adee6784SGordon Ross smb_fh_t *fhp = NULL;
466adee6784SGordon Ross uint32_t efa, rights;
467430b4c46SGordon Ross int error;
4684bff34e3Sthurlow
469adee6784SGordon Ross error = smb_fh_create(ssp, &fhp);
4705ecede33SGordon Ross if (error != 0)
471adee6784SGordon Ross goto out;
4725ecede33SGordon Ross
4734bff34e3Sthurlow /*
474adee6784SGordon Ross * At present the only access we might need is to WRITE data,
475adee6784SGordon Ross * and that only if we are creating a "symlink". When/if the
476adee6784SGordon Ross * access needed gets more complex it should made a parameter
477adee6784SGordon Ross * and be set upstream.
4784bff34e3Sthurlow */
479adee6784SGordon Ross rights = SA_RIGHT_FILE_WRITE_DATA;
480adee6784SGordon Ross efa = SMB_EFA_NORMAL;
481adee6784SGordon Ross if (!xattr && name && *name == '.')
482adee6784SGordon Ross efa = SMB_EFA_HIDDEN;
483adee6784SGordon Ross error = smbfs_smb_ntcreatex(dnp,
484adee6784SGordon Ross name, nmlen, xattr, rights, efa,
485adee6784SGordon Ross NTCREATEX_SHARE_ACCESS_ALL,
486adee6784SGordon Ross disp, /* != NTCREATEX_DISP_OPEN */
487adee6784SGordon Ross NTCREATEX_OPTIONS_NON_DIRECTORY_FILE,
488adee6784SGordon Ross scrp, fhp, NULL, NULL);
489adee6784SGordon Ross if (error != 0)
490adee6784SGordon Ross goto out;
4915ecede33SGordon Ross
492adee6784SGordon Ross fhp->fh_rights = rights;
493adee6784SGordon Ross smb_fh_opened(fhp);
494adee6784SGordon Ross *fhpp = fhp;
495adee6784SGordon Ross fhp = NULL;
4964bff34e3Sthurlow
497adee6784SGordon Ross out:
498adee6784SGordon Ross if (fhp != NULL)
499adee6784SGordon Ross smb_fh_rele(fhp);
5004bff34e3Sthurlow
5014bff34e3Sthurlow return (error);
5024bff34e3Sthurlow }
5034bff34e3Sthurlow
504adee6784SGordon Ross int
smbfs_smb_rename(struct smbnode * sdnp,struct smbnode * np,struct smbnode * tdnp,const char * tname,int tnlen,smb_fh_t * fhp,struct smb_cred * scrp)505adee6784SGordon Ross smbfs_smb_rename(struct smbnode *sdnp, struct smbnode *np,
506adee6784SGordon Ross struct smbnode *tdnp, const char *tname, int tnlen,
507adee6784SGordon Ross smb_fh_t *fhp, struct smb_cred *scrp)
5084bff34e3Sthurlow {
509adee6784SGordon Ross struct smb_share *ssp = np->n_mount->smi_share;
510adee6784SGordon Ross struct smb_vc *vcp = SSTOVC(ssp);
511adee6784SGordon Ross int err;
512613a2f6bSGordon Ross
513adee6784SGordon Ross if (vcp->vc_flags & SMBV_SMB2) {
514adee6784SGordon Ross err = smbfs_smb2_rename(np, tdnp, tname, tnlen, 0,
515adee6784SGordon Ross &fhp->fh_fid2, scrp);
516adee6784SGordon Ross return (err);
5174bff34e3Sthurlow }
5184bff34e3Sthurlow
5194bff34e3Sthurlow /*
520adee6784SGordon Ross * SMB1 -- Want to use _t2rename if we can
521adee6784SGordon Ross * (rename in same dir and cap pass-through)
522adee6784SGordon Ross * Most SMB1 servers have cap pass-through.
5234bff34e3Sthurlow */
524adee6784SGordon Ross if (sdnp == tdnp &&
525adee6784SGordon Ross (vcp->vc_sopt.sv_caps & SMB_CAP_INFOLEVEL_PASSTHRU) != 0) {
526adee6784SGordon Ross err = smbfs_smb1_t2rename(np, tname, tnlen, fhp->fh_fid1, scrp);
527adee6784SGordon Ross } else {
528adee6784SGordon Ross err = smbfs_smb1_oldrename(np, tdnp, tname, tnlen, scrp);
5294bff34e3Sthurlow }
53091d632c8Sgwr
531adee6784SGordon Ross return (err);
532adee6784SGordon Ross }
533adee6784SGordon Ross
534adee6784SGordon Ross int
smbfs_smb_mkdir(struct smbnode * dnp,const char * name,int nmlen,struct smb_cred * scrp)535adee6784SGordon Ross smbfs_smb_mkdir(struct smbnode *dnp, const char *name, int nmlen,
536adee6784SGordon Ross struct smb_cred *scrp)
537adee6784SGordon Ross {
538adee6784SGordon Ross smb_fh_t tmp_fh;
539adee6784SGordon Ross struct smb_share *ssp = dnp->n_mount->smi_share;
540adee6784SGordon Ross uint32_t efa, rights;
541adee6784SGordon Ross int error;
5425ecede33SGordon Ross
5435ecede33SGordon Ross /*
544adee6784SGordon Ross * Using a faked-up handle here to avoid the work of
545adee6784SGordon Ross * creating and destroying a real "conn obj".
5465ecede33SGordon Ross */
547adee6784SGordon Ross bzero(&tmp_fh, sizeof (tmp_fh));
5484bff34e3Sthurlow
54902d09e03SGordon Ross /*
550adee6784SGordon Ross * We ask for SA_RIGHT_FILE_READ_DATA not because we need it, but
551adee6784SGordon Ross * just to be asking for something. The rights==0 case could
552adee6784SGordon Ross * easily be broken on some old or unusual servers.
55302d09e03SGordon Ross */
554adee6784SGordon Ross rights = SA_RIGHT_FILE_READ_DATA;
555adee6784SGordon Ross efa = SMB_EFA_NORMAL;
556adee6784SGordon Ross if (name && *name == '.')
557adee6784SGordon Ross efa |= SMB_EFA_HIDDEN;
558adee6784SGordon Ross error = smbfs_smb_ntcreatex(dnp,
559adee6784SGordon Ross name, nmlen, 0, /* xattr */
560adee6784SGordon Ross rights, SMB_EFA_DIRECTORY,
561adee6784SGordon Ross NTCREATEX_SHARE_ACCESS_ALL,
562adee6784SGordon Ross NTCREATEX_DISP_CREATE,
563adee6784SGordon Ross NTCREATEX_OPTIONS_DIRECTORY,
564adee6784SGordon Ross scrp, &tmp_fh, NULL, NULL);
565adee6784SGordon Ross if (error == 0) {
566adee6784SGordon Ross (void) smb_smb_close(ssp, &tmp_fh, scrp);
567adee6784SGordon Ross }
568adee6784SGordon Ross
5697568150aSgwr return (error);
5704bff34e3Sthurlow }
5714bff34e3Sthurlow
572adee6784SGordon Ross /*
573adee6784SGordon Ross * Protocol-level directory open
574adee6784SGordon Ross */
5754bff34e3Sthurlow int
smbfs_smb_findopen(struct smbnode * dnp,const char * wild,int wlen,int attr,struct smb_cred * scrp,struct smbfs_fctx ** ctxpp)57691d632c8Sgwr smbfs_smb_findopen(struct smbnode *dnp, const char *wild, int wlen,
5774bff34e3Sthurlow int attr, struct smb_cred *scrp,
5784bff34e3Sthurlow struct smbfs_fctx **ctxpp)
5794bff34e3Sthurlow {
580adee6784SGordon Ross struct smb_share *ssp = dnp->n_mount->smi_share;
581adee6784SGordon Ross struct smb_vc *vcp = SSTOVC(ssp);
5824bff34e3Sthurlow struct smbfs_fctx *ctx;
5834bff34e3Sthurlow int error;
5844bff34e3Sthurlow
585613a2f6bSGordon Ross ctx = kmem_zalloc(sizeof (*ctx), KM_SLEEP);
58691d632c8Sgwr
5874bff34e3Sthurlow ctx->f_flags = SMBFS_RDD_FINDFIRST;
58891d632c8Sgwr ctx->f_dnp = dnp;
5894bff34e3Sthurlow ctx->f_scred = scrp;
590adee6784SGordon Ross ctx->f_ssp = ssp;
59191d632c8Sgwr
59291d632c8Sgwr if (dnp->n_flag & N_XATTR) {
59391d632c8Sgwr error = smbfs_xa_findopen(ctx, dnp, wild, wlen);
59491d632c8Sgwr goto out;
59591d632c8Sgwr }
59691d632c8Sgwr
597adee6784SGordon Ross if (vcp->vc_flags & SMBV_SMB2) {
598adee6784SGordon Ross error = smbfs_smb2_findopen(ctx, dnp, wild, wlen, attr);
59991d632c8Sgwr } else {
60091d632c8Sgwr error = smbfs_smb_findopenLM2(ctx, dnp, wild, wlen, attr);
60191d632c8Sgwr }
60291d632c8Sgwr
60391d632c8Sgwr out:
604adee6784SGordon Ross ctx->f_scred = NULL;
605adee6784SGordon Ross if (error) {
606adee6784SGordon Ross kmem_free(ctx, sizeof (*ctx));
607adee6784SGordon Ross } else {
6084bff34e3Sthurlow *ctxpp = ctx;
609adee6784SGordon Ross }
610adee6784SGordon Ross
6114bff34e3Sthurlow return (error);
6124bff34e3Sthurlow }
6134bff34e3Sthurlow
6144bff34e3Sthurlow int
smbfs_smb_findnext(struct smbfs_fctx * ctx,int limit,struct smb_cred * scrp)6154bff34e3Sthurlow smbfs_smb_findnext(struct smbfs_fctx *ctx, int limit, struct smb_cred *scrp)
6164bff34e3Sthurlow {
617adee6784SGordon Ross int error = 0;
618adee6784SGordon Ross uint16_t lim;
6194bff34e3Sthurlow
6204bff34e3Sthurlow /*
6214bff34e3Sthurlow * Note: "limit" (maxcount) needs to fit in a short!
6224bff34e3Sthurlow */
6235ecede33SGordon Ross if (limit > 0xffff)
6245ecede33SGordon Ross limit = 0xffff;
625adee6784SGordon Ross lim = (uint16_t)limit;
6264bff34e3Sthurlow
6274bff34e3Sthurlow ctx->f_scred = scrp;
6284bff34e3Sthurlow for (;;) {
62991d632c8Sgwr bzero(&ctx->f_attr, sizeof (ctx->f_attr));
63091d632c8Sgwr switch (ctx->f_type) {
631adee6784SGordon Ross
632adee6784SGordon Ross case ft_SMB2:
633adee6784SGordon Ross error = smbfs_smb2_findnext(ctx, lim);
63491d632c8Sgwr break;
63591d632c8Sgwr case ft_LM2:
636adee6784SGordon Ross error = smbfs_smb_findnextLM2(ctx, lim);
63791d632c8Sgwr break;
63891d632c8Sgwr case ft_XA:
639adee6784SGordon Ross error = smbfs_xa_findnext(ctx, lim);
64091d632c8Sgwr break;
64191d632c8Sgwr default:
64291d632c8Sgwr ASSERT(0);
64391d632c8Sgwr error = EINVAL;
64491d632c8Sgwr break;
64591d632c8Sgwr }
6464bff34e3Sthurlow if (error)
647adee6784SGordon Ross break;
64891d632c8Sgwr /*
64991d632c8Sgwr * Skip "." or ".." - easy now that ctx->f_name
65091d632c8Sgwr * has already been converted to utf-8 format.
65191d632c8Sgwr */
65291d632c8Sgwr if ((ctx->f_nmlen == 1 && ctx->f_name[0] == '.') ||
65391d632c8Sgwr (ctx->f_nmlen == 2 && ctx->f_name[0] == '.' &&
65491d632c8Sgwr ctx->f_name[1] == '.'))
65591d632c8Sgwr continue;
6564bff34e3Sthurlow break;
6574bff34e3Sthurlow }
658adee6784SGordon Ross ctx->f_scred = NULL;
659adee6784SGordon Ross if (error != 0)
660adee6784SGordon Ross return (error);
66191d632c8Sgwr
662adee6784SGordon Ross ctx->f_inum = smbfs_getino(ctx->f_dnp,
663adee6784SGordon Ross ctx->f_name, ctx->f_nmlen);
66491d632c8Sgwr
665adee6784SGordon Ross #ifdef DEBUG
666adee6784SGordon Ross SMBVDEBUG("findnext: (%s)\n", ctx->f_name);
667adee6784SGordon Ross #endif
668adee6784SGordon Ross
669adee6784SGordon Ross return (error);
6704bff34e3Sthurlow }
6714bff34e3Sthurlow
6724bff34e3Sthurlow
6734bff34e3Sthurlow int
smbfs_smb_findclose(struct smbfs_fctx * ctx,struct smb_cred * scrp)6744bff34e3Sthurlow smbfs_smb_findclose(struct smbfs_fctx *ctx, struct smb_cred *scrp)
6754bff34e3Sthurlow {
6767568150aSgwr int error;
67791d632c8Sgwr
6784bff34e3Sthurlow ctx->f_scred = scrp;
67991d632c8Sgwr switch (ctx->f_type) {
680adee6784SGordon Ross case ft_SMB2:
681adee6784SGordon Ross error = smbfs_smb2_findclose(ctx);
68291d632c8Sgwr break;
68391d632c8Sgwr case ft_LM2:
6847568150aSgwr error = smbfs_smb_findcloseLM2(ctx);
68591d632c8Sgwr break;
68691d632c8Sgwr case ft_XA:
68791d632c8Sgwr error = smbfs_xa_findclose(ctx);
68891d632c8Sgwr break;
6898329232eSGordon Ross default:
6908329232eSGordon Ross error = ENOSYS;
6918329232eSGordon Ross break;
69291d632c8Sgwr }
693adee6784SGordon Ross ctx->f_scred = NULL;
6944bff34e3Sthurlow if (ctx->f_rname)
6954bff34e3Sthurlow kmem_free(ctx->f_rname, ctx->f_rnamelen);
6964bff34e3Sthurlow if (ctx->f_firstnm)
6974bff34e3Sthurlow kmem_free(ctx->f_firstnm, ctx->f_firstnmlen);
6984bff34e3Sthurlow kmem_free(ctx, sizeof (*ctx));
6997568150aSgwr return (error);
7004bff34e3Sthurlow }
7014bff34e3Sthurlow
7024bff34e3Sthurlow
7034bff34e3Sthurlow int
smbfs_smb_lookup(struct smbnode * dnp,const char ** namep,int * nmlenp,struct smbfattr * fap,struct smb_cred * scrp)7044bff34e3Sthurlow smbfs_smb_lookup(struct smbnode *dnp, const char **namep, int *nmlenp,
7054bff34e3Sthurlow struct smbfattr *fap, struct smb_cred *scrp)
7064bff34e3Sthurlow {
7074bff34e3Sthurlow struct smbfs_fctx *ctx;
7084bff34e3Sthurlow int error, intr;
7094bff34e3Sthurlow const char *name = (namep ? *namep : NULL);
7104bff34e3Sthurlow int nmlen = (nmlenp ? *nmlenp : 0);
7114bff34e3Sthurlow
7124bff34e3Sthurlow /* This is no longer called with a null dnp */
7134bff34e3Sthurlow ASSERT(dnp);
7144bff34e3Sthurlow
7154bff34e3Sthurlow /*
7164bff34e3Sthurlow * Should not get here with "" anymore.
7174bff34e3Sthurlow */
7184bff34e3Sthurlow if (!name || !nmlen) {
7194bff34e3Sthurlow DEBUG_ENTER("smbfs_smb_lookup: name is NULL");
7204bff34e3Sthurlow return (EINVAL);
7214bff34e3Sthurlow }
7224bff34e3Sthurlow
7234bff34e3Sthurlow /*
7244bff34e3Sthurlow * Should not get here with "." or ".." anymore.
7254bff34e3Sthurlow */
7264bff34e3Sthurlow if ((nmlen == 1 && name[0] == '.') ||
7274bff34e3Sthurlow (nmlen == 2 && name[0] == '.' && name[1] == '.')) {
7284bff34e3Sthurlow DEBUG_ENTER("smbfs_smb_lookup: name is '.' or '..'");
7294bff34e3Sthurlow return (EINVAL);
7304bff34e3Sthurlow }
7314bff34e3Sthurlow
7324bff34e3Sthurlow /*
7334bff34e3Sthurlow * Shared lock for n_fid use (smb_flush).
7344bff34e3Sthurlow */
7354bff34e3Sthurlow intr = dnp->n_mount->smi_flags & SMI_INT;
7364bff34e3Sthurlow if (smbfs_rw_enter_sig(&dnp->r_lkserlock, RW_READER, intr))
7374bff34e3Sthurlow return (EINTR);
7384bff34e3Sthurlow
7394bff34e3Sthurlow error = smbfs_smb_findopen(dnp, name, nmlen,
7404bff34e3Sthurlow SMB_FA_SYSTEM | SMB_FA_HIDDEN | SMB_FA_DIR, scrp, &ctx);
7414bff34e3Sthurlow if (error)
7424bff34e3Sthurlow goto out;
7434bff34e3Sthurlow ctx->f_flags |= SMBFS_RDD_FINDSINGLE;
7444bff34e3Sthurlow error = smbfs_smb_findnext(ctx, 1, scrp);
7454bff34e3Sthurlow if (error == 0) {
7464bff34e3Sthurlow *fap = ctx->f_attr;
74702d09e03SGordon Ross /*
74802d09e03SGordon Ross * Solaris smbfattr doesn't have fa_ino,
74902d09e03SGordon Ross * and we don't allow name==NULL in this
75002d09e03SGordon Ross * function anymore.
75102d09e03SGordon Ross */
7524bff34e3Sthurlow if (namep)
7534bff34e3Sthurlow *namep = (const char *)smbfs_name_alloc(
7544bff34e3Sthurlow ctx->f_name, ctx->f_nmlen);
7554bff34e3Sthurlow if (nmlenp)
7564bff34e3Sthurlow *nmlenp = ctx->f_nmlen;
7574bff34e3Sthurlow }
7587568150aSgwr (void) smbfs_smb_findclose(ctx, scrp);
7594bff34e3Sthurlow
7604bff34e3Sthurlow out:
7614bff34e3Sthurlow smbfs_rw_exit(&dnp->r_lkserlock);
7624bff34e3Sthurlow return (error);
7634bff34e3Sthurlow }
7644bff34e3Sthurlow
7654bff34e3Sthurlow /*
7667568150aSgwr * OTW function to Get a security descriptor (SD).
7677568150aSgwr *
7687568150aSgwr * Note: On success, this fills in mdp->md_top,
7697568150aSgwr * which the caller should free.
7704bff34e3Sthurlow */
7714bff34e3Sthurlow int
smbfs_smb_getsec(struct smb_share * ssp,smb_fh_t * fhp,uint32_t selector,mblk_t ** res,uint32_t * reslen,struct smb_cred * scrp)772adee6784SGordon Ross smbfs_smb_getsec(struct smb_share *ssp, smb_fh_t *fhp,
773adee6784SGordon Ross uint32_t selector, mblk_t **res, uint32_t *reslen,
774adee6784SGordon Ross struct smb_cred *scrp)
7754bff34e3Sthurlow {
776adee6784SGordon Ross struct smb_vc *vcp = SSTOVC(ssp);
7774bff34e3Sthurlow int error, len;
7784bff34e3Sthurlow
7794bff34e3Sthurlow *res = NULL;
7807568150aSgwr
781adee6784SGordon Ross if (vcp->vc_flags & SMBV_SMB2) {
782adee6784SGordon Ross error = smbfs_smb2_getsec(ssp, &fhp->fh_fid2,
783adee6784SGordon Ross selector, res, reslen, scrp);
784adee6784SGordon Ross } else {
785adee6784SGordon Ross error = smbfs_smb1_getsec(ssp, fhp->fh_fid1,
786adee6784SGordon Ross selector, res, reslen, scrp);
787adee6784SGordon Ross }
7884bff34e3Sthurlow
7897568150aSgwr /*
7907568150aSgwr * get the data part.
7917568150aSgwr */
792adee6784SGordon Ross if (*res == NULL) {
7937568150aSgwr error = EBADRPC;
7947568150aSgwr goto done;
7957568150aSgwr }
7967568150aSgwr
7977568150aSgwr /*
798adee6784SGordon Ross * If message length is < returned SD_length,
799adee6784SGordon Ross * correct *reslen (reduce it). It greater,
800adee6784SGordon Ross * just ignore the extra data.
8017568150aSgwr */
802adee6784SGordon Ross len = m_fixhdr(*res);
8037568150aSgwr if (len < *reslen)
8047568150aSgwr *reslen = len;
8057568150aSgwr
8064bff34e3Sthurlow done:
8077568150aSgwr if (error == 0 && *res == NULL) {
8087568150aSgwr ASSERT(*res);
8097568150aSgwr error = EBADRPC;
8107568150aSgwr }
8117568150aSgwr
8124bff34e3Sthurlow return (error);
8134bff34e3Sthurlow }
8144bff34e3Sthurlow
8157568150aSgwr /*
8167568150aSgwr * OTW function to Set a security descriptor (SD).
8177568150aSgwr * Caller data are carried in an mbchain_t.
8187568150aSgwr *
8197568150aSgwr * Note: This normally consumes mbp->mb_top, and clears
8207568150aSgwr * that pointer when it does.
8217568150aSgwr */
8227568150aSgwr int
smbfs_smb_setsec(struct smb_share * ssp,smb_fh_t * fhp,uint32_t selector,mblk_t ** mp,struct smb_cred * scrp)823adee6784SGordon Ross smbfs_smb_setsec(struct smb_share *ssp, smb_fh_t *fhp,
824adee6784SGordon Ross uint32_t selector, mblk_t **mp,
825adee6784SGordon Ross struct smb_cred *scrp)
8267568150aSgwr {
827adee6784SGordon Ross struct smb_vc *vcp = SSTOVC(ssp);
828adee6784SGordon Ross int error;
8297568150aSgwr
830adee6784SGordon Ross if (vcp->vc_flags & SMBV_SMB2) {
831adee6784SGordon Ross error = smbfs_smb2_setsec(ssp, &fhp->fh_fid2,
832adee6784SGordon Ross selector, mp, scrp);
833adee6784SGordon Ross } else {
834adee6784SGordon Ross error = smbfs_smb1_setsec(ssp, fhp->fh_fid1,
835adee6784SGordon Ross selector, mp, scrp);
8364bff34e3Sthurlow }
8377568150aSgwr
8384bff34e3Sthurlow return (error);
8394bff34e3Sthurlow }
840