xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_query_fileinfo.c (revision a90cf9f29973990687fa61de9f1f6ea22e924e40)
1e3f2c991SKeyur Desai /*
2e3f2c991SKeyur Desai  * CDDL HEADER START
3e3f2c991SKeyur Desai  *
4e3f2c991SKeyur Desai  * The contents of this file are subject to the terms of the
5e3f2c991SKeyur Desai  * Common Development and Distribution License (the "License").
6e3f2c991SKeyur Desai  * You may not use this file except in compliance with the License.
7e3f2c991SKeyur Desai  *
8e3f2c991SKeyur Desai  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9e3f2c991SKeyur Desai  * or http://www.opensolaris.org/os/licensing.
10e3f2c991SKeyur Desai  * See the License for the specific language governing permissions
11e3f2c991SKeyur Desai  * and limitations under the License.
12e3f2c991SKeyur Desai  *
13e3f2c991SKeyur Desai  * When distributing Covered Code, include this CDDL HEADER in each
14e3f2c991SKeyur Desai  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15e3f2c991SKeyur Desai  * If applicable, add the following below this CDDL HEADER, with the
16e3f2c991SKeyur Desai  * fields enclosed by brackets "[]" replaced with your own identifying
17e3f2c991SKeyur Desai  * information: Portions Copyright [yyyy] [name of copyright owner]
18e3f2c991SKeyur Desai  *
19e3f2c991SKeyur Desai  * CDDL HEADER END
20e3f2c991SKeyur Desai  */
21148c5f43SAlan Wright 
22e3f2c991SKeyur Desai /*
23c5866007SKeyur Desai  * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
245fd03bc0SGordon Ross  * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
25e3f2c991SKeyur Desai  */
26e3f2c991SKeyur Desai 
27bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h>
28e3f2c991SKeyur Desai #include <smbsrv/smb_vops.h>
29e3f2c991SKeyur Desai #include <smbsrv/smb_fsops.h>
30e3f2c991SKeyur Desai 
31e3f2c991SKeyur Desai /*
32e3f2c991SKeyur Desai  * Trans2 Query File/Path Information Levels:
33e3f2c991SKeyur Desai  *
34e3f2c991SKeyur Desai  * SMB_INFO_STANDARD
35e3f2c991SKeyur Desai  * SMB_INFO_QUERY_EA_SIZE
36e3f2c991SKeyur Desai  * SMB_INFO_QUERY_EAS_FROM_LIST
37e3f2c991SKeyur Desai  * SMB_INFO_QUERY_ALL_EAS - not valid for pipes
38e3f2c991SKeyur Desai  * SMB_INFO_IS_NAME_VALID - only valid when query is by path
39e3f2c991SKeyur Desai  *
40e3f2c991SKeyur Desai  * SMB_QUERY_FILE_BASIC_INFO
41e3f2c991SKeyur Desai  * SMB_QUERY_FILE_STANDARD_INFO
42e3f2c991SKeyur Desai  * SMB_QUERY_FILE_EA_INFO
43e3f2c991SKeyur Desai  * SMB_QUERY_FILE_NAME_INFO
44e3f2c991SKeyur Desai  * SMB_QUERY_FILE_ALL_INFO
45e3f2c991SKeyur Desai  * SMB_QUERY_FILE_ALT_NAME_INFO - not valid for pipes
46e3f2c991SKeyur Desai  * SMB_QUERY_FILE_STREAM_INFO - not valid for pipes
47e3f2c991SKeyur Desai  * SMB_QUERY_FILE_COMPRESSION_INFO - not valid for pipes
48e3f2c991SKeyur Desai  *
49e3f2c991SKeyur Desai  * Supported Passthrough levels:
50e3f2c991SKeyur Desai  * SMB_FILE_BASIC_INFORMATION
51e3f2c991SKeyur Desai  * SMB_FILE_STANDARD_INFORMATION
52e3f2c991SKeyur Desai  * SMB_FILE_INTERNAL_INFORMATION
53e3f2c991SKeyur Desai  * SMB_FILE_EA_INFORMATION
54cb174861Sjoyce mcintosh  * SMB_FILE_ACCESS_INFORMATION - not yet supported when query by path
55e3f2c991SKeyur Desai  * SMB_FILE_NAME_INFORMATION
56e3f2c991SKeyur Desai  * SMB_FILE_ALL_INFORMATION
57e3f2c991SKeyur Desai  * SMB_FILE_ALT_NAME_INFORMATION - not valid for pipes
58e3f2c991SKeyur Desai  * SMB_FILE_STREAM_INFORMATION - not valid for pipes
59e3f2c991SKeyur Desai  * SMB_FILE_COMPRESSION_INFORMATION - not valid for pipes
609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * SMB_FILE_NETWORK_OPEN_INFORMATION - not valid for pipes
61e3f2c991SKeyur Desai  * SMB_FILE_ATTR_TAG_INFORMATION - not valid for pipes
62e3f2c991SKeyur Desai  *
63e3f2c991SKeyur Desai  * Internal levels representing non trans2 requests
64e3f2c991SKeyur Desai  * SMB_QUERY_INFORMATION
65e3f2c991SKeyur Desai  * SMB_QUERY_INFORMATION2
66e3f2c991SKeyur Desai  */
67e3f2c991SKeyur Desai 
68cb174861Sjoyce mcintosh /*
69cb174861Sjoyce mcintosh  * SMB_STREAM_ENCODE_FIXED_SIZE:
70cb174861Sjoyce mcintosh  * 2 dwords + 2 quadwords => 4 + 4 + 8 + 8 => 24
71cb174861Sjoyce mcintosh  */
72cb174861Sjoyce mcintosh #define	SMB_STREAM_ENCODE_FIXED_SZ	24
73cb174861Sjoyce mcintosh 
74*a90cf9f2SGordon Ross /* See smb_queryinfo_t in smb_ktypes.h */
75e3f2c991SKeyur Desai #define	qi_mtime	qi_attr.sa_vattr.va_mtime
76e3f2c991SKeyur Desai #define	qi_ctime	qi_attr.sa_vattr.va_ctime
77e3f2c991SKeyur Desai #define	qi_atime	qi_attr.sa_vattr.va_atime
78e3f2c991SKeyur Desai #define	qi_crtime	qi_attr.sa_crtime
79e3f2c991SKeyur Desai 
80e3f2c991SKeyur Desai static int smb_query_by_fid(smb_request_t *, smb_xa_t *, uint16_t);
819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States static int smb_query_by_path(smb_request_t *, smb_xa_t *, uint16_t);
82e3f2c991SKeyur Desai 
83e3f2c991SKeyur Desai static int smb_query_fileinfo(smb_request_t *, smb_node_t *,
84e3f2c991SKeyur Desai     uint16_t, smb_queryinfo_t *);
85e3f2c991SKeyur Desai static int smb_query_pipeinfo(smb_request_t *, smb_opipe_t *,
86e3f2c991SKeyur Desai     uint16_t, smb_queryinfo_t *);
87e3f2c991SKeyur Desai static boolean_t smb_query_pipe_valid_infolev(smb_request_t *, uint16_t);
88e3f2c991SKeyur Desai 
89e3f2c991SKeyur Desai static int smb_query_encode_response(smb_request_t *, smb_xa_t *,
90e3f2c991SKeyur Desai     uint16_t, smb_queryinfo_t *);
91*a90cf9f2SGordon Ross static boolean_t smb_stream_fits(smb_request_t *, mbuf_chain_t *,
92*a90cf9f2SGordon Ross     char *, uint32_t);
93148c5f43SAlan Wright static int smb_query_pathname(smb_request_t *, smb_node_t *, boolean_t,
94148c5f43SAlan Wright     smb_queryinfo_t *);
95e3f2c991SKeyur Desai 
969fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int smb_query_passthru;
97e3f2c991SKeyur Desai 
98e3f2c991SKeyur Desai /*
99e3f2c991SKeyur Desai  * smb_com_trans2_query_file_information
100e3f2c991SKeyur Desai  */
101e3f2c991SKeyur Desai smb_sdrc_t
102e3f2c991SKeyur Desai smb_com_trans2_query_file_information(struct smb_request *sr, struct smb_xa *xa)
103e3f2c991SKeyur Desai {
104e3f2c991SKeyur Desai 	uint16_t infolev;
105e3f2c991SKeyur Desai 
106e3f2c991SKeyur Desai 	if (smb_mbc_decodef(&xa->req_param_mb, "ww",
107e3f2c991SKeyur Desai 	    &sr->smb_fid, &infolev) != 0)
108e3f2c991SKeyur Desai 		return (SDRC_ERROR);
109e3f2c991SKeyur Desai 
110e3f2c991SKeyur Desai 	if (smb_query_by_fid(sr, xa, infolev) != 0)
111e3f2c991SKeyur Desai 		return (SDRC_ERROR);
112e3f2c991SKeyur Desai 
113e3f2c991SKeyur Desai 	return (SDRC_SUCCESS);
114e3f2c991SKeyur Desai }
115e3f2c991SKeyur Desai 
116e3f2c991SKeyur Desai /*
117e3f2c991SKeyur Desai  * smb_com_trans2_query_path_information
118e3f2c991SKeyur Desai  */
119e3f2c991SKeyur Desai smb_sdrc_t
120e3f2c991SKeyur Desai smb_com_trans2_query_path_information(smb_request_t *sr, smb_xa_t *xa)
121e3f2c991SKeyur Desai {
122e3f2c991SKeyur Desai 	uint16_t	infolev;
1239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_fqi_t	*fqi = &sr->arg.dirop.fqi;
124e3f2c991SKeyur Desai 
125f96bd5c8SAlan Wright 	if (STYPE_ISIPC(sr->tid_tree->t_res_type)) {
126e3f2c991SKeyur Desai 		smbsr_error(sr, NT_STATUS_INVALID_DEVICE_REQUEST,
127e3f2c991SKeyur Desai 		    ERRDOS, ERROR_INVALID_FUNCTION);
128e3f2c991SKeyur Desai 		return (SDRC_ERROR);
129e3f2c991SKeyur Desai 	}
130e3f2c991SKeyur Desai 
131e3f2c991SKeyur Desai 	if (smb_mbc_decodef(&xa->req_param_mb, "%w4.u",
1329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    sr, &infolev, &fqi->fq_path.pn_path) != 0)
133e3f2c991SKeyur Desai 		return (SDRC_ERROR);
134e3f2c991SKeyur Desai 
1359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_query_by_path(sr, xa, infolev) != 0)
136e3f2c991SKeyur Desai 		return (SDRC_ERROR);
137e3f2c991SKeyur Desai 
138e3f2c991SKeyur Desai 	return (SDRC_SUCCESS);
139e3f2c991SKeyur Desai }
140e3f2c991SKeyur Desai 
141e3f2c991SKeyur Desai /*
142e3f2c991SKeyur Desai  * smb_com_query_information (aka getattr)
143e3f2c991SKeyur Desai  */
144e3f2c991SKeyur Desai smb_sdrc_t
145e3f2c991SKeyur Desai smb_pre_query_information(smb_request_t *sr)
146e3f2c991SKeyur Desai {
147e3f2c991SKeyur Desai 	int rc;
148e3f2c991SKeyur Desai 	smb_fqi_t *fqi = &sr->arg.dirop.fqi;
149e3f2c991SKeyur Desai 
150e3f2c991SKeyur Desai 	rc = smbsr_decode_data(sr, "%S", sr, &fqi->fq_path.pn_path);
151e3f2c991SKeyur Desai 
152e3f2c991SKeyur Desai 	DTRACE_SMB_2(op__QueryInformation__start, smb_request_t *, sr,
153e3f2c991SKeyur Desai 	    smb_fqi_t *, fqi);
154e3f2c991SKeyur Desai 
155e3f2c991SKeyur Desai 	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
156e3f2c991SKeyur Desai }
157e3f2c991SKeyur Desai 
158e3f2c991SKeyur Desai void
159e3f2c991SKeyur Desai smb_post_query_information(smb_request_t *sr)
160e3f2c991SKeyur Desai {
161e3f2c991SKeyur Desai 	DTRACE_SMB_1(op__QueryInformation__done, smb_request_t *, sr);
162e3f2c991SKeyur Desai }
163e3f2c991SKeyur Desai 
164e3f2c991SKeyur Desai smb_sdrc_t
165e3f2c991SKeyur Desai smb_com_query_information(smb_request_t *sr)
166e3f2c991SKeyur Desai {
167e3f2c991SKeyur Desai 	uint16_t infolev = SMB_QUERY_INFORMATION;
168e3f2c991SKeyur Desai 
169f96bd5c8SAlan Wright 	if (STYPE_ISIPC(sr->tid_tree->t_res_type)) {
170e3f2c991SKeyur Desai 		smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
171e3f2c991SKeyur Desai 		    ERRDOS, ERROR_ACCESS_DENIED);
172e3f2c991SKeyur Desai 		return (SDRC_ERROR);
173e3f2c991SKeyur Desai 	}
174e3f2c991SKeyur Desai 
1759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (smb_query_by_path(sr, NULL, infolev) != 0)
176e3f2c991SKeyur Desai 		return (SDRC_ERROR);
177e3f2c991SKeyur Desai 
178e3f2c991SKeyur Desai 	return (SDRC_SUCCESS);
179e3f2c991SKeyur Desai }
180e3f2c991SKeyur Desai 
181e3f2c991SKeyur Desai /*
182e3f2c991SKeyur Desai  * smb_com_query_information2 (aka getattre)
183e3f2c991SKeyur Desai  */
184e3f2c991SKeyur Desai smb_sdrc_t
185e3f2c991SKeyur Desai smb_pre_query_information2(smb_request_t *sr)
186e3f2c991SKeyur Desai {
187e3f2c991SKeyur Desai 	int rc;
188e3f2c991SKeyur Desai 	rc = smbsr_decode_vwv(sr, "w", &sr->smb_fid);
189e3f2c991SKeyur Desai 
190e3f2c991SKeyur Desai 	DTRACE_SMB_1(op__QueryInformation2__start, smb_request_t *, sr);
191e3f2c991SKeyur Desai 
192e3f2c991SKeyur Desai 	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
193e3f2c991SKeyur Desai }
194e3f2c991SKeyur Desai 
195e3f2c991SKeyur Desai void
196e3f2c991SKeyur Desai smb_post_query_information2(smb_request_t *sr)
197e3f2c991SKeyur Desai {
198e3f2c991SKeyur Desai 	DTRACE_SMB_1(op__QueryInformation2__done, smb_request_t *, sr);
199e3f2c991SKeyur Desai }
200e3f2c991SKeyur Desai 
201e3f2c991SKeyur Desai smb_sdrc_t
202e3f2c991SKeyur Desai smb_com_query_information2(smb_request_t *sr)
203e3f2c991SKeyur Desai {
204e3f2c991SKeyur Desai 	uint16_t infolev = SMB_QUERY_INFORMATION2;
205e3f2c991SKeyur Desai 
206e3f2c991SKeyur Desai 	if (smb_query_by_fid(sr, NULL, infolev) != 0)
207e3f2c991SKeyur Desai 		return (SDRC_ERROR);
208e3f2c991SKeyur Desai 
209e3f2c991SKeyur Desai 	return (SDRC_SUCCESS);
210e3f2c991SKeyur Desai }
211e3f2c991SKeyur Desai 
212e3f2c991SKeyur Desai /*
213e3f2c991SKeyur Desai  * smb_query_by_fid
214e3f2c991SKeyur Desai  *
215e3f2c991SKeyur Desai  * Common code for querying file information by open file (or pipe) id.
216e3f2c991SKeyur Desai  * Use the id to identify the node / pipe object and request the
217e3f2c991SKeyur Desai  * smb_queryinfo_t data for that object.
218e3f2c991SKeyur Desai  */
219e3f2c991SKeyur Desai static int
220e3f2c991SKeyur Desai smb_query_by_fid(smb_request_t *sr, smb_xa_t *xa, uint16_t infolev)
221e3f2c991SKeyur Desai {
222e3f2c991SKeyur Desai 	int		rc;
223e3f2c991SKeyur Desai 	smb_queryinfo_t	*qinfo;
224e3f2c991SKeyur Desai 	smb_node_t	*node;
225e3f2c991SKeyur Desai 	smb_opipe_t	*opipe;
226e3f2c991SKeyur Desai 
227e3f2c991SKeyur Desai 	smbsr_lookup_file(sr);
228e3f2c991SKeyur Desai 
229e3f2c991SKeyur Desai 	if (sr->fid_ofile == NULL) {
230e3f2c991SKeyur Desai 		smbsr_error(sr, NT_STATUS_INVALID_HANDLE, ERRDOS, ERRbadfid);
231e3f2c991SKeyur Desai 		return (-1);
232e3f2c991SKeyur Desai 	}
233e3f2c991SKeyur Desai 
234e3f2c991SKeyur Desai 	if (infolev == SMB_INFO_IS_NAME_VALID) {
235148c5f43SAlan Wright 		smbsr_error(sr, 0, ERRDOS, ERROR_INVALID_LEVEL);
236e3f2c991SKeyur Desai 		smbsr_release_file(sr);
237e3f2c991SKeyur Desai 		return (-1);
238e3f2c991SKeyur Desai 	}
239e3f2c991SKeyur Desai 
240e3f2c991SKeyur Desai 	if ((sr->fid_ofile->f_ftype == SMB_FTYPE_MESG_PIPE) &&
241e3f2c991SKeyur Desai 	    (!smb_query_pipe_valid_infolev(sr, infolev))) {
242e3f2c991SKeyur Desai 		smbsr_release_file(sr);
243e3f2c991SKeyur Desai 		return (-1);
244e3f2c991SKeyur Desai 	}
245e3f2c991SKeyur Desai 
2465fd03bc0SGordon Ross 	sr->user_cr = smb_ofile_getcred(sr->fid_ofile);
247e3f2c991SKeyur Desai 	qinfo = kmem_alloc(sizeof (smb_queryinfo_t), KM_SLEEP);
248e3f2c991SKeyur Desai 
249e3f2c991SKeyur Desai 	switch (sr->fid_ofile->f_ftype) {
250e3f2c991SKeyur Desai 	case SMB_FTYPE_DISK:
251e3f2c991SKeyur Desai 		node = sr->fid_ofile->f_node;
252e3f2c991SKeyur Desai 		rc = smb_query_fileinfo(sr, node, infolev, qinfo);
253e3f2c991SKeyur Desai 		break;
254e3f2c991SKeyur Desai 	case SMB_FTYPE_MESG_PIPE:
255e3f2c991SKeyur Desai 		opipe = sr->fid_ofile->f_pipe;
256e3f2c991SKeyur Desai 		rc = smb_query_pipeinfo(sr, opipe, infolev, qinfo);
257e3f2c991SKeyur Desai 		break;
258e3f2c991SKeyur Desai 	default:
259e3f2c991SKeyur Desai 		smbsr_error(sr, 0, ERRDOS, ERRbadfile);
260e3f2c991SKeyur Desai 		rc = -1;
261e3f2c991SKeyur Desai 		break;
262e3f2c991SKeyur Desai 	}
263e3f2c991SKeyur Desai 
264e3f2c991SKeyur Desai 	if (rc == 0)
265e3f2c991SKeyur Desai 		rc = smb_query_encode_response(sr, xa, infolev, qinfo);
266e3f2c991SKeyur Desai 
267e3f2c991SKeyur Desai 	kmem_free(qinfo, sizeof (smb_queryinfo_t));
268e3f2c991SKeyur Desai 	smbsr_release_file(sr);
269e3f2c991SKeyur Desai 	return (rc);
270e3f2c991SKeyur Desai }
271e3f2c991SKeyur Desai 
272e3f2c991SKeyur Desai /*
273e3f2c991SKeyur Desai  * smb_query_by_path
274e3f2c991SKeyur Desai  *
275e3f2c991SKeyur Desai  * Common code for querying file information by file name.
276e3f2c991SKeyur Desai  * Use the file name to identify the node object and request the
277e3f2c991SKeyur Desai  * smb_queryinfo_t data for that node.
278e3f2c991SKeyur Desai  *
2799fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * Path should be set in sr->arg.dirop.fqi.fq_path prior to
2809fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * calling smb_query_by_path.
2819fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  *
282e3f2c991SKeyur Desai  * Querying attributes on a named pipe by name is an error and
283e3f2c991SKeyur Desai  * is handled in the calling functions so that they can return
284e3f2c991SKeyur Desai  * the appropriate error status code (which differs by caller).
285e3f2c991SKeyur Desai  */
286e3f2c991SKeyur Desai static int
2879fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_query_by_path(smb_request_t *sr, smb_xa_t *xa, uint16_t infolev)
288e3f2c991SKeyur Desai {
289e3f2c991SKeyur Desai 	smb_queryinfo_t	*qinfo;
290e3f2c991SKeyur Desai 	smb_node_t	*node, *dnode;
2919fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_pathname_t	*pn;
292e3f2c991SKeyur Desai 	int		rc;
293e3f2c991SKeyur Desai 
2945fd03bc0SGordon Ross 	/*
2955fd03bc0SGordon Ross 	 * The function smb_query_fileinfo is used here and in
2965fd03bc0SGordon Ross 	 * smb_query_by_fid.  That common function needs this
2975fd03bc0SGordon Ross 	 * one to call it with a NULL fid_ofile, so check here.
2985fd03bc0SGordon Ross 	 * Note: smb_query_by_fid enforces the opposite.
2995fd03bc0SGordon Ross 	 *
3005fd03bc0SGordon Ross 	 * In theory we could ASSERT this, but whether we have
3015fd03bc0SGordon Ross 	 * fid_ofile set here depends on what sequence of SMB
3025fd03bc0SGordon Ross 	 * commands the client has sent in this message, so
3035fd03bc0SGordon Ross 	 * let's be cautious and handle it as an error.
3045fd03bc0SGordon Ross 	 */
3055fd03bc0SGordon Ross 	if (sr->fid_ofile != NULL)
3065fd03bc0SGordon Ross 		return (-1);
3075fd03bc0SGordon Ross 
3085fd03bc0SGordon Ross 
309e3f2c991SKeyur Desai 	/* VALID, but not yet supported */
310e3f2c991SKeyur Desai 	if (infolev == SMB_FILE_ACCESS_INFORMATION) {
311148c5f43SAlan Wright 		smbsr_error(sr, 0, ERRDOS, ERROR_INVALID_LEVEL);
312e3f2c991SKeyur Desai 		return (-1);
313e3f2c991SKeyur Desai 	}
314e3f2c991SKeyur Desai 
3159fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	pn = &sr->arg.dirop.fqi.fq_path;
3169fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_pathname_init(sr, pn, pn->pn_path);
3179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_pathname_validate(sr, pn))
3189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
319e3f2c991SKeyur Desai 
320e3f2c991SKeyur Desai 	qinfo = kmem_alloc(sizeof (smb_queryinfo_t), KM_SLEEP);
321e3f2c991SKeyur Desai 
3229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rc = smb_pathname_reduce(sr, sr->user_cr, pn->pn_path,
3239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    sr->tid_tree->t_snode, sr->tid_tree->t_snode, &dnode,
3249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	    qinfo->qi_name);
3259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
326e3f2c991SKeyur Desai 	if (rc == 0) {
327e3f2c991SKeyur Desai 		rc = smb_fsop_lookup_name(sr, sr->user_cr, SMB_FOLLOW_LINKS,
328e3f2c991SKeyur Desai 		    sr->tid_tree->t_snode, dnode, qinfo->qi_name, &node);
329e3f2c991SKeyur Desai 		smb_node_release(dnode);
330e3f2c991SKeyur Desai 	}
331e3f2c991SKeyur Desai 
332e3f2c991SKeyur Desai 	if (rc != 0) {
333e3f2c991SKeyur Desai 		if (rc == ENOENT)
334e3f2c991SKeyur Desai 			smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND,
335e3f2c991SKeyur Desai 			    ERRDOS, ERROR_FILE_NOT_FOUND);
336e3f2c991SKeyur Desai 		else
337e3f2c991SKeyur Desai 			smbsr_errno(sr, rc);
338e3f2c991SKeyur Desai 
339e3f2c991SKeyur Desai 		kmem_free(qinfo, sizeof (smb_queryinfo_t));
340e3f2c991SKeyur Desai 		return (-1);
341e3f2c991SKeyur Desai 	}
342e3f2c991SKeyur Desai 
3439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((sr->smb_flg2 & SMB_FLAGS2_DFS) && smb_node_is_dfslink(node)) {
3449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smbsr_error(sr, NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
3459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		kmem_free(qinfo, sizeof (smb_queryinfo_t));
3469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_node_release(node);
3479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (-1);
3489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
3499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
350e3f2c991SKeyur Desai 	rc = smb_query_fileinfo(sr, node, infolev, qinfo);
351e3f2c991SKeyur Desai 	if (rc != 0) {
352e3f2c991SKeyur Desai 		kmem_free(qinfo, sizeof (smb_queryinfo_t));
353e3f2c991SKeyur Desai 		smb_node_release(node);
354e3f2c991SKeyur Desai 		return (rc);
355e3f2c991SKeyur Desai 	}
356e3f2c991SKeyur Desai 
357e3f2c991SKeyur Desai 	/* If delete_on_close - NT_STATUS_DELETE_PENDING */
358e3f2c991SKeyur Desai 	if (qinfo->qi_delete_on_close) {
359e3f2c991SKeyur Desai 		smbsr_error(sr, NT_STATUS_DELETE_PENDING,
360e3f2c991SKeyur Desai 		    ERRDOS, ERROR_ACCESS_DENIED);
361e3f2c991SKeyur Desai 		kmem_free(qinfo, sizeof (smb_queryinfo_t));
362e3f2c991SKeyur Desai 		smb_node_release(node);
363e3f2c991SKeyur Desai 		return (-1);
364e3f2c991SKeyur Desai 	}
365e3f2c991SKeyur Desai 
366e3f2c991SKeyur Desai 	rc = smb_query_encode_response(sr, xa, infolev, qinfo);
367e3f2c991SKeyur Desai 	kmem_free(qinfo, sizeof (smb_queryinfo_t));
368e3f2c991SKeyur Desai 	smb_node_release(node);
369e3f2c991SKeyur Desai 	return (rc);
370e3f2c991SKeyur Desai }
371e3f2c991SKeyur Desai 
372e3f2c991SKeyur Desai /*
373e3f2c991SKeyur Desai  * smb_size32
374e3f2c991SKeyur Desai  * Some responses only support 32 bit file sizes. If the file size
375e3f2c991SKeyur Desai  * exceeds UINT_MAX (32 bit) we return UINT_MAX in the response.
376e3f2c991SKeyur Desai  */
377e3f2c991SKeyur Desai static uint32_t
378e3f2c991SKeyur Desai smb_size32(u_offset_t size)
379e3f2c991SKeyur Desai {
380e3f2c991SKeyur Desai 	return ((size > UINT_MAX) ? UINT_MAX : (uint32_t)size);
381e3f2c991SKeyur Desai }
382e3f2c991SKeyur Desai 
383e3f2c991SKeyur Desai /*
384e3f2c991SKeyur Desai  * smb_query_encode_response
385e3f2c991SKeyur Desai  *
386e3f2c991SKeyur Desai  * Encode the data from smb_queryinfo_t into client response
387e3f2c991SKeyur Desai  */
388e3f2c991SKeyur Desai int
389e3f2c991SKeyur Desai smb_query_encode_response(smb_request_t *sr, smb_xa_t *xa,
390e3f2c991SKeyur Desai     uint16_t infolev, smb_queryinfo_t *qinfo)
391e3f2c991SKeyur Desai {
392e3f2c991SKeyur Desai 	uint16_t dattr;
393e3f2c991SKeyur Desai 	u_offset_t datasz, allocsz;
394*a90cf9f2SGordon Ross 	uint32_t status;
395e3f2c991SKeyur Desai 
396e3f2c991SKeyur Desai 	dattr = qinfo->qi_attr.sa_dosattr & FILE_ATTRIBUTE_MASK;
397e3f2c991SKeyur Desai 	datasz = qinfo->qi_attr.sa_vattr.va_size;
398e3f2c991SKeyur Desai 	allocsz = qinfo->qi_attr.sa_allocsz;
399e3f2c991SKeyur Desai 
400e3f2c991SKeyur Desai 	switch (infolev) {
401e3f2c991SKeyur Desai 	case SMB_QUERY_INFORMATION:
402e3f2c991SKeyur Desai 		(void) smbsr_encode_result(sr, 10, 0, "bwll10.w",
403e3f2c991SKeyur Desai 		    10,
404e3f2c991SKeyur Desai 		    dattr,
405e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, qinfo->qi_mtime.tv_sec),
406e3f2c991SKeyur Desai 		    smb_size32(datasz),
407e3f2c991SKeyur Desai 		    0);
408e3f2c991SKeyur Desai 		break;
409e3f2c991SKeyur Desai 
410e3f2c991SKeyur Desai 	case SMB_QUERY_INFORMATION2:
411e3f2c991SKeyur Desai 		(void) smbsr_encode_result(sr, 11, 0, "byyyllww",
412e3f2c991SKeyur Desai 		    11,
413e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, qinfo->qi_crtime.tv_sec),
414e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, qinfo->qi_atime.tv_sec),
415e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, qinfo->qi_mtime.tv_sec),
416e3f2c991SKeyur Desai 		    smb_size32(datasz), smb_size32(allocsz), dattr, 0);
417e3f2c991SKeyur Desai 	break;
418e3f2c991SKeyur Desai 
419e3f2c991SKeyur Desai 	case SMB_FILE_ACCESS_INFORMATION:
420e3f2c991SKeyur Desai 		ASSERT(sr->fid_ofile);
421e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_data_mb, "l",
422e3f2c991SKeyur Desai 		    sr->fid_ofile->f_granted_access);
423e3f2c991SKeyur Desai 		break;
424e3f2c991SKeyur Desai 
425e3f2c991SKeyur Desai 	case SMB_INFO_STANDARD:
426e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0);
427e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_data_mb,
428e3f2c991SKeyur Desai 		    ((sr->session->native_os == NATIVE_OS_WIN95) ?
429e3f2c991SKeyur Desai 		    "YYYllw" : "yyyllw"),
430e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, qinfo->qi_crtime.tv_sec),
431e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, qinfo->qi_atime.tv_sec),
432e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, qinfo->qi_mtime.tv_sec),
433e3f2c991SKeyur Desai 		    smb_size32(datasz), smb_size32(allocsz), dattr);
434e3f2c991SKeyur Desai 		break;
435e3f2c991SKeyur Desai 
436e3f2c991SKeyur Desai 	case SMB_INFO_QUERY_EA_SIZE:
437e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0);
438e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_data_mb,
439e3f2c991SKeyur Desai 		    ((sr->session->native_os == NATIVE_OS_WIN95) ?
440e3f2c991SKeyur Desai 		    "YYYllwl" : "yyyllwl"),
441e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, qinfo->qi_crtime.tv_sec),
442e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, qinfo->qi_atime.tv_sec),
443e3f2c991SKeyur Desai 		    smb_time_gmt_to_local(sr, qinfo->qi_mtime.tv_sec),
444e3f2c991SKeyur Desai 		    smb_size32(datasz), smb_size32(allocsz), dattr, 0);
445e3f2c991SKeyur Desai 		break;
446e3f2c991SKeyur Desai 
447e3f2c991SKeyur Desai 	case SMB_INFO_QUERY_ALL_EAS:
448e3f2c991SKeyur Desai 	case SMB_INFO_QUERY_EAS_FROM_LIST:
449e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0);
450e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_data_mb, "l", 0);
451e3f2c991SKeyur Desai 		break;
452e3f2c991SKeyur Desai 
453e3f2c991SKeyur Desai 	case SMB_INFO_IS_NAME_VALID:
454e3f2c991SKeyur Desai 		break;
455e3f2c991SKeyur Desai 
456e3f2c991SKeyur Desai 	case SMB_QUERY_FILE_BASIC_INFO:
457e3f2c991SKeyur Desai 	case SMB_FILE_BASIC_INFORMATION:
458e3f2c991SKeyur Desai 		/*
459e3f2c991SKeyur Desai 		 * NT includes 6 bytes (spec says 4) at the end of this
460e3f2c991SKeyur Desai 		 * response, which are required by NetBench 5.01.
461e3f2c991SKeyur Desai 		 */
462e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0);
463e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_data_mb, "TTTTw6.",
464e3f2c991SKeyur Desai 		    &qinfo->qi_crtime,
465e3f2c991SKeyur Desai 		    &qinfo->qi_atime,
466e3f2c991SKeyur Desai 		    &qinfo->qi_mtime,
467e3f2c991SKeyur Desai 		    &qinfo->qi_ctime,
468e3f2c991SKeyur Desai 		    dattr);
469e3f2c991SKeyur Desai 		break;
470e3f2c991SKeyur Desai 
471e3f2c991SKeyur Desai 	case SMB_QUERY_FILE_STANDARD_INFO:
472e3f2c991SKeyur Desai 	case SMB_FILE_STANDARD_INFORMATION:
473e3f2c991SKeyur Desai 		/* 2-byte pad at end */
474e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0);
475e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_data_mb, "qqlbb2.",
476e3f2c991SKeyur Desai 		    (uint64_t)allocsz,
477e3f2c991SKeyur Desai 		    (uint64_t)datasz,
478e3f2c991SKeyur Desai 		    qinfo->qi_attr.sa_vattr.va_nlink,
479e3f2c991SKeyur Desai 		    qinfo->qi_delete_on_close,
480*a90cf9f2SGordon Ross 		    qinfo->qi_isdir);
481e3f2c991SKeyur Desai 		break;
482e3f2c991SKeyur Desai 
483e3f2c991SKeyur Desai 	case SMB_QUERY_FILE_EA_INFO:
484e3f2c991SKeyur Desai 	case SMB_FILE_EA_INFORMATION:
485e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0);
486e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_data_mb, "l", 0);
487e3f2c991SKeyur Desai 		break;
488e3f2c991SKeyur Desai 
489e3f2c991SKeyur Desai 	case SMB_QUERY_FILE_NAME_INFO:
490e3f2c991SKeyur Desai 	case SMB_FILE_NAME_INFORMATION:
491e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0);
492e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_data_mb, "%lu", sr,
493e3f2c991SKeyur Desai 		    qinfo->qi_namelen, qinfo->qi_name);
494e3f2c991SKeyur Desai 		break;
495e3f2c991SKeyur Desai 
496e3f2c991SKeyur Desai 	case SMB_QUERY_FILE_ALL_INFO:
497e3f2c991SKeyur Desai 	case SMB_FILE_ALL_INFORMATION:
498e3f2c991SKeyur Desai 		/*
499e3f2c991SKeyur Desai 		 * There is a 6-byte pad between Attributes and AllocationSize,
500e3f2c991SKeyur Desai 		 * and a 2-byte pad after the Directory field.
501e3f2c991SKeyur Desai 		 */
502e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0);
503e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_data_mb, "TTTTw6.qqlbb2.l",
504e3f2c991SKeyur Desai 		    &qinfo->qi_crtime,
505e3f2c991SKeyur Desai 		    &qinfo->qi_atime,
506e3f2c991SKeyur Desai 		    &qinfo->qi_mtime,
507e3f2c991SKeyur Desai 		    &qinfo->qi_ctime,
508e3f2c991SKeyur Desai 		    dattr,
509e3f2c991SKeyur Desai 		    (uint64_t)allocsz,
510e3f2c991SKeyur Desai 		    (uint64_t)datasz,
511e3f2c991SKeyur Desai 		    qinfo->qi_attr.sa_vattr.va_nlink,
512e3f2c991SKeyur Desai 		    qinfo->qi_delete_on_close,
513*a90cf9f2SGordon Ross 		    qinfo->qi_isdir,
514e3f2c991SKeyur Desai 		    0);
515e3f2c991SKeyur Desai 
516e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_data_mb, "%lu",
517e3f2c991SKeyur Desai 		    sr, qinfo->qi_namelen, qinfo->qi_name);
518e3f2c991SKeyur Desai 		break;
519e3f2c991SKeyur Desai 
520e3f2c991SKeyur Desai 	case SMB_QUERY_FILE_ALT_NAME_INFO:
521e3f2c991SKeyur Desai 	case SMB_FILE_ALT_NAME_INFORMATION:
522e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0);
523e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_data_mb, "%lU", sr,
524bbf6f00cSJordan Brown 		    smb_wcequiv_strlen(qinfo->qi_shortname),
525e3f2c991SKeyur Desai 		    qinfo->qi_shortname);
526e3f2c991SKeyur Desai 		break;
527e3f2c991SKeyur Desai 
528e3f2c991SKeyur Desai 	case SMB_QUERY_FILE_STREAM_INFO:
529e3f2c991SKeyur Desai 	case SMB_FILE_STREAM_INFORMATION:
530e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0);
531*a90cf9f2SGordon Ross 		status = smb_query_stream_info(sr, &xa->rep_data_mb, qinfo);
532*a90cf9f2SGordon Ross 		if (status)
533*a90cf9f2SGordon Ross 			smbsr_status(sr, status, 0, 0);
534e3f2c991SKeyur Desai 		break;
535e3f2c991SKeyur Desai 
536e3f2c991SKeyur Desai 	case SMB_QUERY_FILE_COMPRESSION_INFO:
537e3f2c991SKeyur Desai 	case SMB_FILE_COMPRESSION_INFORMATION:
538e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0);
539e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_data_mb, "qwbbb3.",
540e3f2c991SKeyur Desai 		    datasz, 0, 0, 0, 0);
541e3f2c991SKeyur Desai 		break;
542e3f2c991SKeyur Desai 
543e3f2c991SKeyur Desai 	case SMB_FILE_INTERNAL_INFORMATION:
544e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0);
545e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_data_mb, "q",
546e3f2c991SKeyur Desai 		    qinfo->qi_attr.sa_vattr.va_nodeid);
547e3f2c991SKeyur Desai 		break;
548e3f2c991SKeyur Desai 
5499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_FILE_NETWORK_OPEN_INFORMATION:
5509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0);
5519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		(void) smb_mbc_encodef(&xa->rep_data_mb, "TTTTqql4.",
5529fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    &qinfo->qi_crtime,
5539fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    &qinfo->qi_atime,
5549fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    &qinfo->qi_mtime,
5559fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    &qinfo->qi_ctime,
5569fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    (uint64_t)allocsz,
5579fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    (uint64_t)datasz,
5589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    (uint32_t)dattr);
5599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		break;
5609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
561e3f2c991SKeyur Desai 	case SMB_FILE_ATTR_TAG_INFORMATION:
562e3f2c991SKeyur Desai 		/*
563e3f2c991SKeyur Desai 		 * If dattr includes FILE_ATTRIBUTE_REPARSE_POINT, the
564e3f2c991SKeyur Desai 		 * second dword should be the reparse tag.  Otherwise
565e3f2c991SKeyur Desai 		 * the tag value should be set to zero.
566e3f2c991SKeyur Desai 		 * We don't support reparse points, so we set the tag
567e3f2c991SKeyur Desai 		 * to zero.
568e3f2c991SKeyur Desai 		 */
569e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_param_mb, "w", 0);
570e3f2c991SKeyur Desai 		(void) smb_mbc_encodef(&xa->rep_data_mb, "ll",
571e3f2c991SKeyur Desai 		    (uint32_t)dattr, 0);
572e3f2c991SKeyur Desai 		break;
573e3f2c991SKeyur Desai 
574e3f2c991SKeyur Desai 	default:
5759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		if ((infolev > 1000) && smb_query_passthru)
5769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			smbsr_error(sr, NT_STATUS_NOT_SUPPORTED,
5779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 			    ERRDOS, ERROR_NOT_SUPPORTED);
5789fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		else
579148c5f43SAlan Wright 			smbsr_error(sr, 0, ERRDOS, ERROR_INVALID_LEVEL);
580e3f2c991SKeyur Desai 		return (-1);
581e3f2c991SKeyur Desai 	}
582e3f2c991SKeyur Desai 
583e3f2c991SKeyur Desai 	return (0);
584e3f2c991SKeyur Desai }
585e3f2c991SKeyur Desai 
586e3f2c991SKeyur Desai /*
587e3f2c991SKeyur Desai  * smb_encode_stream_info
588e3f2c991SKeyur Desai  *
589e3f2c991SKeyur Desai  * This function encodes the streams information.
590e3f2c991SKeyur Desai  * The following rules about how have been derived from observed NT
591e3f2c991SKeyur Desai  * behaviour.
592e3f2c991SKeyur Desai  *
593e3f2c991SKeyur Desai  * If the target is a file:
594e3f2c991SKeyur Desai  * 1. If there are no named streams, the response should still contain
595e3f2c991SKeyur Desai  *    an entry for the unnamed stream.
596e3f2c991SKeyur Desai  * 2. If there are named streams, the response should contain an entry
597e3f2c991SKeyur Desai  *    for the unnamed stream followed by the entries for the named
598e3f2c991SKeyur Desai  *    streams.
599e3f2c991SKeyur Desai  *
600e3f2c991SKeyur Desai  * If the target is a directory:
601e3f2c991SKeyur Desai  * 1. If there are no streams, the response is complete. Directories
602e3f2c991SKeyur Desai  *    do not report the unnamed stream.
603e3f2c991SKeyur Desai  * 2. If there are streams, the response should contain entries for
604e3f2c991SKeyur Desai  *    those streams but there should not be an entry for the unnamed
605e3f2c991SKeyur Desai  *    stream.
606e3f2c991SKeyur Desai  *
607e3f2c991SKeyur Desai  * Note that the stream name lengths exclude the null terminator but
608e3f2c991SKeyur Desai  * the field lengths (i.e. next offset calculations) need to include
609e3f2c991SKeyur Desai  * the null terminator and be padded to a multiple of 8 bytes. The
610e3f2c991SKeyur Desai  * last entry does not seem to need any padding.
611e3f2c991SKeyur Desai  *
612e3f2c991SKeyur Desai  * If an error is encountered when trying to read the stream entries
613e3f2c991SKeyur Desai  * (smb_odir_read_streaminfo) it is treated as if there are no [more]
614e3f2c991SKeyur Desai  * entries. The entries that have been read so far are returned and
615e3f2c991SKeyur Desai  * no error is reported.
616e3f2c991SKeyur Desai  *
617cb174861Sjoyce mcintosh  * If the response buffer is not large enough to return all of the
618cb174861Sjoyce mcintosh  * named stream entries, the entries that do fit are returned and
619cb174861Sjoyce mcintosh  * a warning code is set (NT_STATUS_BUFFER_OVERFLOW). The next_offset
620cb174861Sjoyce mcintosh  * value in the last returned entry must be 0.
621e3f2c991SKeyur Desai  */
622*a90cf9f2SGordon Ross uint32_t
623*a90cf9f2SGordon Ross smb_query_stream_info(smb_request_t *sr, mbuf_chain_t *mbc,
624*a90cf9f2SGordon Ross 	smb_queryinfo_t *qinfo)
625e3f2c991SKeyur Desai {
626e3f2c991SKeyur Desai 	char *stream_name;
627e3f2c991SKeyur Desai 	uint32_t next_offset;
628e3f2c991SKeyur Desai 	uint32_t stream_nlen;
629e3f2c991SKeyur Desai 	uint32_t pad;
630e3f2c991SKeyur Desai 	u_offset_t datasz, allocsz;
631e3f2c991SKeyur Desai 	smb_streaminfo_t *sinfo, *sinfo_next;
632e3f2c991SKeyur Desai 	int rc = 0;
633e3f2c991SKeyur Desai 	boolean_t done = B_FALSE;
634e3f2c991SKeyur Desai 	boolean_t eos = B_FALSE;
635e3f2c991SKeyur Desai 	smb_odir_t *od = NULL;
636*a90cf9f2SGordon Ross 	uint32_t status = 0;
637e3f2c991SKeyur Desai 
638e3f2c991SKeyur Desai 	smb_node_t *fnode = qinfo->qi_node;
639e3f2c991SKeyur Desai 	smb_attr_t *attr = &qinfo->qi_attr;
640e3f2c991SKeyur Desai 
641e3f2c991SKeyur Desai 	ASSERT(fnode);
642e3f2c991SKeyur Desai 	if (SMB_IS_STREAM(fnode)) {
643e3f2c991SKeyur Desai 		fnode = fnode->n_unode;
644e3f2c991SKeyur Desai 		ASSERT(fnode);
645e3f2c991SKeyur Desai 	}
646e3f2c991SKeyur Desai 	ASSERT(fnode->n_magic == SMB_NODE_MAGIC);
647e3f2c991SKeyur Desai 	ASSERT(fnode->n_state != SMB_NODE_STATE_DESTROYING);
648e3f2c991SKeyur Desai 
649e3f2c991SKeyur Desai 	sinfo = kmem_alloc(sizeof (smb_streaminfo_t), KM_SLEEP);
650e3f2c991SKeyur Desai 	sinfo_next = kmem_alloc(sizeof (smb_streaminfo_t), KM_SLEEP);
651e3f2c991SKeyur Desai 	datasz = attr->sa_vattr.va_size;
652e3f2c991SKeyur Desai 	allocsz = attr->sa_allocsz;
653e3f2c991SKeyur Desai 
654*a90cf9f2SGordon Ross 	status = smb_odir_openat(sr, fnode, &od);
655*a90cf9f2SGordon Ross 	switch (status) {
656*a90cf9f2SGordon Ross 	case 0:
657*a90cf9f2SGordon Ross 		break;
658*a90cf9f2SGordon Ross 	case NT_STATUS_NO_SUCH_FILE:
659*a90cf9f2SGordon Ross 	case NT_STATUS_NOT_SUPPORTED:
660*a90cf9f2SGordon Ross 		/* No streams. */
661e3f2c991SKeyur Desai 		done = B_TRUE;
662*a90cf9f2SGordon Ross 		break;
663*a90cf9f2SGordon Ross 	default:
664*a90cf9f2SGordon Ross 		return (status);
665*a90cf9f2SGordon Ross 	}
666*a90cf9f2SGordon Ross 
667*a90cf9f2SGordon Ross 	if (!done) {
668*a90cf9f2SGordon Ross 		rc = smb_odir_read_streaminfo(sr, od, sinfo, &eos);
669*a90cf9f2SGordon Ross 		if ((rc != 0) || (eos))
670*a90cf9f2SGordon Ross 			done = B_TRUE;
671*a90cf9f2SGordon Ross 	}
672e3f2c991SKeyur Desai 
673e3f2c991SKeyur Desai 	/* If not a directory, encode an entry for the unnamed stream. */
674*a90cf9f2SGordon Ross 	if (qinfo->qi_isdir == 0) {
675e3f2c991SKeyur Desai 		stream_name = "::$DATA";
676e3f2c991SKeyur Desai 		stream_nlen = smb_ascii_or_unicode_strlen(sr, stream_name);
677cb174861Sjoyce mcintosh 		next_offset = SMB_STREAM_ENCODE_FIXED_SZ + stream_nlen +
678cb174861Sjoyce mcintosh 		    smb_ascii_or_unicode_null_len(sr);
679cb174861Sjoyce mcintosh 
680cb174861Sjoyce mcintosh 		/* Can unnamed stream fit in response buffer? */
681*a90cf9f2SGordon Ross 		if (MBC_ROOM_FOR(mbc, next_offset) == 0) {
682cb174861Sjoyce mcintosh 			done = B_TRUE;
683*a90cf9f2SGordon Ross 			status = NT_STATUS_BUFFER_OVERFLOW;
684cb174861Sjoyce mcintosh 		} else {
685cb174861Sjoyce mcintosh 			/* Can first named stream fit in rsp buffer? */
686*a90cf9f2SGordon Ross 			if (!done && !smb_stream_fits(sr, mbc, sinfo->si_name,
687cb174861Sjoyce mcintosh 			    next_offset)) {
688cb174861Sjoyce mcintosh 				done = B_TRUE;
689*a90cf9f2SGordon Ross 				status = NT_STATUS_BUFFER_OVERFLOW;
690cb174861Sjoyce mcintosh 			}
691e3f2c991SKeyur Desai 
692e3f2c991SKeyur Desai 			if (done)
693e3f2c991SKeyur Desai 				next_offset = 0;
694e3f2c991SKeyur Desai 
695*a90cf9f2SGordon Ross 			(void) smb_mbc_encodef(mbc, "%llqqu", sr,
696cb174861Sjoyce mcintosh 			    next_offset, stream_nlen, datasz, allocsz,
697cb174861Sjoyce mcintosh 			    stream_name);
698cb174861Sjoyce mcintosh 		}
699e3f2c991SKeyur Desai 	}
700e3f2c991SKeyur Desai 
701e3f2c991SKeyur Desai 	/*
702cb174861Sjoyce mcintosh 	 * If there is no next entry, or there is not enough space in
703cb174861Sjoyce mcintosh 	 * the response buffer for the next entry, the next_offset and
704cb174861Sjoyce mcintosh 	 * padding are 0.
705e3f2c991SKeyur Desai 	 */
706e3f2c991SKeyur Desai 	while (!done) {
707e3f2c991SKeyur Desai 		stream_nlen = smb_ascii_or_unicode_strlen(sr, sinfo->si_name);
708e3f2c991SKeyur Desai 		sinfo_next->si_name[0] = 0;
709e3f2c991SKeyur Desai 
710e3f2c991SKeyur Desai 		rc = smb_odir_read_streaminfo(sr, od, sinfo_next, &eos);
711e3f2c991SKeyur Desai 		if ((rc != 0) || (eos)) {
712e3f2c991SKeyur Desai 			done = B_TRUE;
713e3f2c991SKeyur Desai 		} else {
714cb174861Sjoyce mcintosh 			next_offset = SMB_STREAM_ENCODE_FIXED_SZ +
715cb174861Sjoyce mcintosh 			    stream_nlen +
716e3f2c991SKeyur Desai 			    smb_ascii_or_unicode_null_len(sr);
717e3f2c991SKeyur Desai 			pad = smb_pad_align(next_offset, 8);
718e3f2c991SKeyur Desai 			next_offset += pad;
719cb174861Sjoyce mcintosh 
720cb174861Sjoyce mcintosh 			/* Can next named stream fit in response buffer? */
721*a90cf9f2SGordon Ross 			if (!smb_stream_fits(sr, mbc, sinfo_next->si_name,
722cb174861Sjoyce mcintosh 			    next_offset)) {
723cb174861Sjoyce mcintosh 				done = B_TRUE;
724*a90cf9f2SGordon Ross 				status = NT_STATUS_BUFFER_OVERFLOW;
725e3f2c991SKeyur Desai 			}
726cb174861Sjoyce mcintosh 		}
727cb174861Sjoyce mcintosh 
728cb174861Sjoyce mcintosh 		if (done) {
729cb174861Sjoyce mcintosh 			next_offset = 0;
730cb174861Sjoyce mcintosh 			pad = 0;
731cb174861Sjoyce mcintosh 		}
732cb174861Sjoyce mcintosh 
733*a90cf9f2SGordon Ross 		(void) smb_mbc_encodef(mbc, "%llqqu#.",
734e3f2c991SKeyur Desai 		    sr, next_offset, stream_nlen,
735e3f2c991SKeyur Desai 		    sinfo->si_size, sinfo->si_alloc_size,
736e3f2c991SKeyur Desai 		    sinfo->si_name, pad);
737e3f2c991SKeyur Desai 
738e3f2c991SKeyur Desai 		(void) memcpy(sinfo, sinfo_next, sizeof (smb_streaminfo_t));
739e3f2c991SKeyur Desai 	}
740e3f2c991SKeyur Desai 
741e3f2c991SKeyur Desai 	kmem_free(sinfo, sizeof (smb_streaminfo_t));
742e3f2c991SKeyur Desai 	kmem_free(sinfo_next, sizeof (smb_streaminfo_t));
743e3f2c991SKeyur Desai 	if (od) {
744e3f2c991SKeyur Desai 		smb_odir_close(od);
745e3f2c991SKeyur Desai 		smb_odir_release(od);
746e3f2c991SKeyur Desai 	}
747*a90cf9f2SGordon Ross 
748*a90cf9f2SGordon Ross 	return (status);
749e3f2c991SKeyur Desai }
750e3f2c991SKeyur Desai 
751e3f2c991SKeyur Desai /*
752cb174861Sjoyce mcintosh  * smb_stream_fits
753cb174861Sjoyce mcintosh  *
754cb174861Sjoyce mcintosh  * Check if the named stream entry can fit in the response buffer.
755cb174861Sjoyce mcintosh  *
756cb174861Sjoyce mcintosh  * Required space =
757cb174861Sjoyce mcintosh  *	offset (size of current entry)
758cb174861Sjoyce mcintosh  *	+ SMB_STREAM_ENCODE_FIXED_SIZE
759cb174861Sjoyce mcintosh  *      + length of encoded stream name
760cb174861Sjoyce mcintosh  *	+ length of null terminator
761cb174861Sjoyce mcintosh  *	+ alignment padding
762cb174861Sjoyce mcintosh  */
763cb174861Sjoyce mcintosh static boolean_t
764*a90cf9f2SGordon Ross smb_stream_fits(smb_request_t *sr, mbuf_chain_t *mbc,
765*a90cf9f2SGordon Ross 	char *name, uint32_t offset)
766cb174861Sjoyce mcintosh {
767cb174861Sjoyce mcintosh 	uint32_t len, pad;
768cb174861Sjoyce mcintosh 
769cb174861Sjoyce mcintosh 	len = SMB_STREAM_ENCODE_FIXED_SZ +
770cb174861Sjoyce mcintosh 	    smb_ascii_or_unicode_strlen(sr, name) +
771cb174861Sjoyce mcintosh 	    smb_ascii_or_unicode_null_len(sr);
772cb174861Sjoyce mcintosh 	pad = smb_pad_align(len, 8);
773cb174861Sjoyce mcintosh 	len += pad;
774cb174861Sjoyce mcintosh 
775*a90cf9f2SGordon Ross 	return (MBC_ROOM_FOR(mbc, offset + len) != 0);
776cb174861Sjoyce mcintosh }
777cb174861Sjoyce mcintosh 
778cb174861Sjoyce mcintosh /*
779e3f2c991SKeyur Desai  * smb_query_fileinfo
780e3f2c991SKeyur Desai  *
781e3f2c991SKeyur Desai  * Populate smb_queryinfo_t structure for SMB_FTYPE_DISK
782e3f2c991SKeyur Desai  * (This should become an smb_ofile / smb_node function.)
783e3f2c991SKeyur Desai  */
784e3f2c991SKeyur Desai int
785e3f2c991SKeyur Desai smb_query_fileinfo(smb_request_t *sr, smb_node_t *node, uint16_t infolev,
786e3f2c991SKeyur Desai     smb_queryinfo_t *qinfo)
787e3f2c991SKeyur Desai {
788148c5f43SAlan Wright 	int rc = 0;
789e3f2c991SKeyur Desai 
790cb174861Sjoyce mcintosh 	/* If shortname required but not supported -> OBJECT_NAME_NOT_FOUND */
791cb174861Sjoyce mcintosh 	if ((infolev == SMB_QUERY_FILE_ALT_NAME_INFO) ||
792cb174861Sjoyce mcintosh 	    (infolev == SMB_FILE_ALT_NAME_INFORMATION)) {
793cb174861Sjoyce mcintosh 		if (!smb_tree_has_feature(sr->tid_tree, SMB_TREE_SHORTNAMES)) {
794cb174861Sjoyce mcintosh 			smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND,
795cb174861Sjoyce mcintosh 			    ERRDOS, ERROR_FILE_NOT_FOUND);
796cb174861Sjoyce mcintosh 			return (-1);
797cb174861Sjoyce mcintosh 		}
798cb174861Sjoyce mcintosh 	}
799cb174861Sjoyce mcintosh 
800e3f2c991SKeyur Desai 	(void) bzero(qinfo, sizeof (smb_queryinfo_t));
801e3f2c991SKeyur Desai 
8025fd03bc0SGordon Ross 	/* See: smb_query_encode_response */
8035fd03bc0SGordon Ross 	qinfo->qi_attr.sa_mask = SMB_AT_ALL;
8045fd03bc0SGordon Ross 	rc = smb_node_getattr(sr, node, sr->user_cr, sr->fid_ofile,
8055fd03bc0SGordon Ross 	    &qinfo->qi_attr);
8065fd03bc0SGordon Ross 	if (rc != 0) {
807e3f2c991SKeyur Desai 		smbsr_error(sr, NT_STATUS_INTERNAL_ERROR,
808e3f2c991SKeyur Desai 		    ERRDOS, ERROR_INTERNAL_ERROR);
809e3f2c991SKeyur Desai 		return (-1);
810e3f2c991SKeyur Desai 	}
811e3f2c991SKeyur Desai 
812e3f2c991SKeyur Desai 	qinfo->qi_node = node;
813e3f2c991SKeyur Desai 	qinfo->qi_delete_on_close =
814e3f2c991SKeyur Desai 	    (node->flags & NODE_FLAGS_DELETE_ON_CLOSE) != 0;
815*a90cf9f2SGordon Ross 	qinfo->qi_isdir = smb_node_is_dir(node);
816e3f2c991SKeyur Desai 
817e3f2c991SKeyur Desai 	/*
818e3f2c991SKeyur Desai 	 * The number of links reported should be the number of
819e3f2c991SKeyur Desai 	 * non-deleted links. Thus if delete_on_close is set,
820e3f2c991SKeyur Desai 	 * decrement the link count.
821e3f2c991SKeyur Desai 	 */
822e3f2c991SKeyur Desai 	if (qinfo->qi_delete_on_close &&
823e3f2c991SKeyur Desai 	    qinfo->qi_attr.sa_vattr.va_nlink > 0) {
824e3f2c991SKeyur Desai 		--(qinfo->qi_attr.sa_vattr.va_nlink);
825e3f2c991SKeyur Desai 	}
826e3f2c991SKeyur Desai 
827148c5f43SAlan Wright 	/*
828148c5f43SAlan Wright 	 * populate name, namelen and shortname ONLY for the information
829148c5f43SAlan Wright 	 * levels that require these fields
830148c5f43SAlan Wright 	 */
831148c5f43SAlan Wright 	switch (infolev) {
832148c5f43SAlan Wright 	case SMB_QUERY_FILE_ALL_INFO:
833148c5f43SAlan Wright 	case SMB_FILE_ALL_INFORMATION:
834148c5f43SAlan Wright 		rc = smb_query_pathname(sr, node, B_TRUE, qinfo);
835148c5f43SAlan Wright 		break;
836148c5f43SAlan Wright 	case SMB_QUERY_FILE_NAME_INFO:
837148c5f43SAlan Wright 	case SMB_FILE_NAME_INFORMATION:
838148c5f43SAlan Wright 		rc = smb_query_pathname(sr, node, B_FALSE, qinfo);
839148c5f43SAlan Wright 		break;
840148c5f43SAlan Wright 	case SMB_QUERY_FILE_ALT_NAME_INFO:
841148c5f43SAlan Wright 	case SMB_FILE_ALT_NAME_INFORMATION:
842148c5f43SAlan Wright 		smb_query_shortname(node, qinfo);
843148c5f43SAlan Wright 		break;
844148c5f43SAlan Wright 	default:
845148c5f43SAlan Wright 		break;
846bbf6f00cSJordan Brown 	}
847bbf6f00cSJordan Brown 
848e3f2c991SKeyur Desai 	if (rc != 0) {
849e3f2c991SKeyur Desai 		smbsr_errno(sr, rc);
850e3f2c991SKeyur Desai 		return (-1);
851e3f2c991SKeyur Desai 	}
852148c5f43SAlan Wright 	return (0);
853148c5f43SAlan Wright }
854e3f2c991SKeyur Desai 
855e3f2c991SKeyur Desai /*
856148c5f43SAlan Wright  * smb_query_pathname
857148c5f43SAlan Wright  *
858148c5f43SAlan Wright  * Determine the absolute pathname of 'node' within the share.
859148c5f43SAlan Wright  * For some levels (e.g. ALL_INFO) the pathname should include the
860148c5f43SAlan Wright  * sharename for others (e.g. NAME_INFO) the pathname should be
861148c5f43SAlan Wright  * relative to the share.
862148c5f43SAlan Wright  * For example if the node represents file "test1.txt" in directory
863148c5f43SAlan Wright  * "dir1" on share "share1"
864148c5f43SAlan Wright  * - if include_share is TRUE the pathname would be: \share1\dir1\test1.txt
865148c5f43SAlan Wright  * - if include_share is FALSE the pathname would be: \dir1\test1.txt
866148c5f43SAlan Wright  *
867e3f2c991SKeyur Desai  * For some reason NT will not show the security tab in the root
868148c5f43SAlan Wright  * directory of a mapped drive unless the filename length is greater
869148c5f43SAlan Wright  * than one. So if the length is 1 we set it to 2 to persuade NT to
870148c5f43SAlan Wright  * show the tab. It should be safe because of the null terminator.
871e3f2c991SKeyur Desai  */
872148c5f43SAlan Wright static int
873148c5f43SAlan Wright smb_query_pathname(smb_request_t *sr, smb_node_t *node, boolean_t include_share,
874148c5f43SAlan Wright     smb_queryinfo_t *qinfo)
875148c5f43SAlan Wright {
876148c5f43SAlan Wright 	smb_tree_t *tree = sr->tid_tree;
877148c5f43SAlan Wright 	char *buf = qinfo->qi_name;
878148c5f43SAlan Wright 	size_t buflen = MAXPATHLEN;
879148c5f43SAlan Wright 	size_t len;
880148c5f43SAlan Wright 	int rc;
881148c5f43SAlan Wright 
882148c5f43SAlan Wright 	if (include_share) {
883148c5f43SAlan Wright 		len = snprintf(buf, buflen, "\\%s", tree->t_sharename);
884148c5f43SAlan Wright 		if (len == (buflen - 1))
885148c5f43SAlan Wright 			return (ENAMETOOLONG);
886148c5f43SAlan Wright 
887148c5f43SAlan Wright 		buf += len;
888148c5f43SAlan Wright 		buflen -= len;
889148c5f43SAlan Wright 	}
890148c5f43SAlan Wright 
891148c5f43SAlan Wright 	if (node == tree->t_snode) {
892148c5f43SAlan Wright 		if (!include_share)
893148c5f43SAlan Wright 			(void) strlcpy(buf, "\\", buflen);
894148c5f43SAlan Wright 		return (0);
895148c5f43SAlan Wright 	}
896148c5f43SAlan Wright 
897148c5f43SAlan Wright 	rc =  smb_node_getshrpath(node, tree, buf, buflen);
898148c5f43SAlan Wright 	if (rc == 0) {
899148c5f43SAlan Wright 		qinfo->qi_namelen =
900148c5f43SAlan Wright 		    smb_ascii_or_unicode_strlen(sr, qinfo->qi_name);
901e3f2c991SKeyur Desai 		if (qinfo->qi_namelen == 1)
902e3f2c991SKeyur Desai 			qinfo->qi_namelen = 2;
903148c5f43SAlan Wright 	}
904148c5f43SAlan Wright 	return (rc);
905148c5f43SAlan Wright }
906e3f2c991SKeyur Desai 
907e3f2c991SKeyur Desai /*
908148c5f43SAlan Wright  * smb_query_shortname
909148c5f43SAlan Wright  *
910148c5f43SAlan Wright  * If the node is a named stream, use its associated
9119fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States  * unnamed stream name to determine the shortname.
912148c5f43SAlan Wright  * If a shortname is required (smb_needs_mangle()), generate it
913148c5f43SAlan Wright  * using smb_mangle(), otherwise, convert the original name to
914148c5f43SAlan Wright  * upper-case and return it as the alternative name.
915e3f2c991SKeyur Desai  */
916*a90cf9f2SGordon Ross void
917148c5f43SAlan Wright smb_query_shortname(smb_node_t *node, smb_queryinfo_t *qinfo)
918148c5f43SAlan Wright {
919148c5f43SAlan Wright 	char *namep;
920148c5f43SAlan Wright 
9219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (SMB_IS_STREAM(node))
9229fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		namep = node->n_unode->od_name;
9239fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	else
9249fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		namep = node->od_name;
9259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
926148c5f43SAlan Wright 	if (smb_needs_mangled(namep)) {
927148c5f43SAlan Wright 		smb_mangle(namep, qinfo->qi_attr.sa_vattr.va_nodeid,
928148c5f43SAlan Wright 		    qinfo->qi_shortname, SMB_SHORTNAMELEN);
929148c5f43SAlan Wright 	} else {
930cb174861Sjoyce mcintosh 		(void) strlcpy(qinfo->qi_shortname, namep, SMB_SHORTNAMELEN);
931bbf6f00cSJordan Brown 		(void) smb_strupr(qinfo->qi_shortname);
932e3f2c991SKeyur Desai 	}
933e3f2c991SKeyur Desai }
934e3f2c991SKeyur Desai 
935e3f2c991SKeyur Desai /*
936e3f2c991SKeyur Desai  * smb_query_pipeinfo
937e3f2c991SKeyur Desai  *
938e3f2c991SKeyur Desai  * Populate smb_queryinfo_t structure for SMB_FTYPE_MESG_PIPE
939e3f2c991SKeyur Desai  * (This should become an smb_opipe function.)
940e3f2c991SKeyur Desai  */
941e3f2c991SKeyur Desai static int
942e3f2c991SKeyur Desai smb_query_pipeinfo(smb_request_t *sr, smb_opipe_t *opipe, uint16_t infolev,
943e3f2c991SKeyur Desai     smb_queryinfo_t *qinfo)
944e3f2c991SKeyur Desai {
945e3f2c991SKeyur Desai 	char *namep = opipe->p_name;
946e3f2c991SKeyur Desai 
947e3f2c991SKeyur Desai 	(void) bzero(qinfo, sizeof (smb_queryinfo_t));
948e3f2c991SKeyur Desai 	qinfo->qi_node = NULL;
949e3f2c991SKeyur Desai 	qinfo->qi_attr.sa_vattr.va_nlink = 1;
950e3f2c991SKeyur Desai 	qinfo->qi_delete_on_close = 1;
951*a90cf9f2SGordon Ross 	qinfo->qi_isdir = 0;
952e3f2c991SKeyur Desai 
953e3f2c991SKeyur Desai 	if ((infolev == SMB_INFO_STANDARD) ||
954e3f2c991SKeyur Desai 	    (infolev == SMB_INFO_QUERY_EA_SIZE) ||
955e3f2c991SKeyur Desai 	    (infolev == SMB_QUERY_INFORMATION2)) {
956e3f2c991SKeyur Desai 		qinfo->qi_attr.sa_dosattr = 0;
957e3f2c991SKeyur Desai 	} else {
958e3f2c991SKeyur Desai 		qinfo->qi_attr.sa_dosattr = FILE_ATTRIBUTE_NORMAL;
959e3f2c991SKeyur Desai 	}
960e3f2c991SKeyur Desai 
961e3f2c991SKeyur Desai 	/* If the leading \ is missing from the pipe name, add it. */
962e3f2c991SKeyur Desai 	if (*namep != '\\')
963e3f2c991SKeyur Desai 		(void) snprintf(qinfo->qi_name, MAXNAMELEN, "\\%s", namep);
964e3f2c991SKeyur Desai 	else
965e3f2c991SKeyur Desai 		(void) strlcpy(qinfo->qi_name, namep, MAXNAMELEN);
966e3f2c991SKeyur Desai 
967e3f2c991SKeyur Desai 	qinfo->qi_namelen=
968e3f2c991SKeyur Desai 	    smb_ascii_or_unicode_strlen(sr, qinfo->qi_name);
969e3f2c991SKeyur Desai 
970e3f2c991SKeyur Desai 	return (0);
971e3f2c991SKeyur Desai }
972e3f2c991SKeyur Desai 
973e3f2c991SKeyur Desai /*
974e3f2c991SKeyur Desai  * smb_query_pipe_valid_infolev
975e3f2c991SKeyur Desai  *
976e3f2c991SKeyur Desai  * If the infolev is not valid for a message pipe, the error
977e3f2c991SKeyur Desai  * information is set in sr and B_FALSE is returned.
978e3f2c991SKeyur Desai  * Otherwise, returns B_TRUE.
979e3f2c991SKeyur Desai  */
980e3f2c991SKeyur Desai static boolean_t
981e3f2c991SKeyur Desai smb_query_pipe_valid_infolev(smb_request_t *sr, uint16_t infolev)
982e3f2c991SKeyur Desai {
983e3f2c991SKeyur Desai 	switch (infolev) {
984e3f2c991SKeyur Desai 	case SMB_INFO_QUERY_ALL_EAS:
985e3f2c991SKeyur Desai 		smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
986e3f2c991SKeyur Desai 		    ERRDOS, ERROR_ACCESS_DENIED);
987e3f2c991SKeyur Desai 		return (B_FALSE);
988e3f2c991SKeyur Desai 
989e3f2c991SKeyur Desai 	case SMB_QUERY_FILE_ALT_NAME_INFO:
990e3f2c991SKeyur Desai 	case SMB_FILE_ALT_NAME_INFORMATION:
991e3f2c991SKeyur Desai 	case SMB_QUERY_FILE_STREAM_INFO:
992e3f2c991SKeyur Desai 	case SMB_FILE_STREAM_INFORMATION:
993e3f2c991SKeyur Desai 	case SMB_QUERY_FILE_COMPRESSION_INFO:
994e3f2c991SKeyur Desai 	case SMB_FILE_COMPRESSION_INFORMATION:
9959fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	case SMB_FILE_NETWORK_OPEN_INFORMATION:
996e3f2c991SKeyur Desai 	case SMB_FILE_ATTR_TAG_INFORMATION:
997e3f2c991SKeyur Desai 		smbsr_error(sr, NT_STATUS_INVALID_PARAMETER,
998e3f2c991SKeyur Desai 		    ERRDOS, ERROR_INVALID_PARAMETER);
999e3f2c991SKeyur Desai 		return (B_FALSE);
1000e3f2c991SKeyur Desai 	}
1001e3f2c991SKeyur Desai 
1002e3f2c991SKeyur Desai 	return (B_TRUE);
1003e3f2c991SKeyur Desai }
1004