xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb_directory.c (revision d2488fe8c5950495aef5404c8d98081be7d43487)
12c2961f8Sjose borrego /*
22c2961f8Sjose borrego  * CDDL HEADER START
32c2961f8Sjose borrego  *
42c2961f8Sjose borrego  * The contents of this file are subject to the terms of the
52c2961f8Sjose borrego  * Common Development and Distribution License (the "License").
62c2961f8Sjose borrego  * You may not use this file except in compliance with the License.
72c2961f8Sjose borrego  *
82c2961f8Sjose borrego  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
92c2961f8Sjose borrego  * or http://www.opensolaris.org/os/licensing.
102c2961f8Sjose borrego  * See the License for the specific language governing permissions
112c2961f8Sjose borrego  * and limitations under the License.
122c2961f8Sjose borrego  *
132c2961f8Sjose borrego  * When distributing Covered Code, include this CDDL HEADER in each
142c2961f8Sjose borrego  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
152c2961f8Sjose borrego  * If applicable, add the following below this CDDL HEADER, with the
162c2961f8Sjose borrego  * fields enclosed by brackets "[]" replaced with your own identifying
172c2961f8Sjose borrego  * information: Portions Copyright [yyyy] [name of copyright owner]
182c2961f8Sjose borrego  *
192c2961f8Sjose borrego  * CDDL HEADER END
202c2961f8Sjose borrego  */
212c2961f8Sjose borrego /*
22f96bd5c8SAlan Wright  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
232c2961f8Sjose borrego  * Use is subject to license terms.
245fd03bc0SGordon Ross  *
25*93bc28dbSGordon Ross  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
262c2961f8Sjose borrego  */
272c2961f8Sjose borrego 
28bbf6f00cSJordan Brown #include <smbsrv/smb_kproto.h>
292c2961f8Sjose borrego #include <smbsrv/smbinfo.h>
302c2961f8Sjose borrego #include <smbsrv/smb_fsops.h>
312c2961f8Sjose borrego 
322c2961f8Sjose borrego /*
332c2961f8Sjose borrego  * The create directory message is sent to create a new directory.  The
342c2961f8Sjose borrego  * appropriate Tid and additional pathname are passed.  The directory must
352c2961f8Sjose borrego  * not exist for it to be created.
362c2961f8Sjose borrego  *
372c2961f8Sjose borrego  * Client Request                     Description
382c2961f8Sjose borrego  * ================================== =================================
392c2961f8Sjose borrego  * UCHAR WordCount;                   Count of parameter words = 0
402c2961f8Sjose borrego  * USHORT ByteCount;                  Count of data bytes; min = 2
412c2961f8Sjose borrego  * UCHAR BufferFormat;                0x04
422c2961f8Sjose borrego  * STRING DirectoryName[];            Directory name
432c2961f8Sjose borrego  *
442c2961f8Sjose borrego  * Servers require clients to have at least create permission for the
452c2961f8Sjose borrego  * subtree containing the directory in order to create a new directory.
462c2961f8Sjose borrego  * The creator's access rights to the new directory are be determined by
472c2961f8Sjose borrego  * local policy on the server.
482c2961f8Sjose borrego  *
492c2961f8Sjose borrego  * Server Response                    Description
502c2961f8Sjose borrego  * ================================== =================================
512c2961f8Sjose borrego  * UCHAR WordCount;                   Count of parameter words = 0
522c2961f8Sjose borrego  * USHORT ByteCount;                  Count of data bytes = 0
532c2961f8Sjose borrego  */
542c2961f8Sjose borrego smb_sdrc_t
smb_pre_create_directory(smb_request_t * sr)552c2961f8Sjose borrego smb_pre_create_directory(smb_request_t *sr)
562c2961f8Sjose borrego {
572c2961f8Sjose borrego 	int rc;
582c2961f8Sjose borrego 
59eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	rc = smbsr_decode_data(sr, "%S", sr,
60eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	    &sr->arg.dirop.fqi.fq_path.pn_path);
612c2961f8Sjose borrego 
62*93bc28dbSGordon Ross 	DTRACE_SMB_START(op__CreateDirectory, smb_request_t *, sr);
632c2961f8Sjose borrego 
642c2961f8Sjose borrego 	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
652c2961f8Sjose borrego }
662c2961f8Sjose borrego 
672c2961f8Sjose borrego void
smb_post_create_directory(smb_request_t * sr)682c2961f8Sjose borrego smb_post_create_directory(smb_request_t *sr)
692c2961f8Sjose borrego {
70*93bc28dbSGordon Ross 	DTRACE_SMB_DONE(op__CreateDirectory, smb_request_t *, sr);
712c2961f8Sjose borrego }
722c2961f8Sjose borrego 
732c2961f8Sjose borrego smb_sdrc_t
smb_com_create_directory(smb_request_t * sr)742c2961f8Sjose borrego smb_com_create_directory(smb_request_t *sr)
752c2961f8Sjose borrego {
762c2961f8Sjose borrego 	int rc = 0;
77fe1c642dSBill Krier 	smb_pathname_t *pn = &sr->arg.dirop.fqi.fq_path;
782c2961f8Sjose borrego 
792c2961f8Sjose borrego 	if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
802c2961f8Sjose borrego 		smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
812c2961f8Sjose borrego 		    ERRDOS, ERROR_ACCESS_DENIED);
822c2961f8Sjose borrego 		return (SDRC_ERROR);
832c2961f8Sjose borrego 	}
842c2961f8Sjose borrego 
85fe1c642dSBill Krier 	smb_pathname_init(sr, pn, pn->pn_path);
86fe1c642dSBill Krier 	if (!smb_pathname_validate(sr, pn) ||
87fe1c642dSBill Krier 	    !smb_validate_dirname(sr, pn)) {
882c2961f8Sjose borrego 		return (SDRC_ERROR);
892c2961f8Sjose borrego 	}
902c2961f8Sjose borrego 
91fe1c642dSBill Krier 	if ((rc = smb_common_create_directory(sr)) != 0) {
922c2961f8Sjose borrego 		smbsr_errno(sr, rc);
932c2961f8Sjose borrego 		return (SDRC_ERROR);
942c2961f8Sjose borrego 	}
952c2961f8Sjose borrego 
962c2961f8Sjose borrego 	rc = smbsr_encode_empty_result(sr);
972c2961f8Sjose borrego 	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
982c2961f8Sjose borrego }
992c2961f8Sjose borrego 
1002c2961f8Sjose borrego /*
1012c2961f8Sjose borrego  * smb_common_create_directory
1022c2961f8Sjose borrego  *
1032c2961f8Sjose borrego  * Currently called from:
1042c2961f8Sjose borrego  *		smb_com_create_directory
1052c2961f8Sjose borrego  *		smb_com_trans2_create_directory
1062c2961f8Sjose borrego  *
1072c2961f8Sjose borrego  * Returns errno values.
1082c2961f8Sjose borrego  */
1092c2961f8Sjose borrego int
smb_common_create_directory(smb_request_t * sr)1102c2961f8Sjose borrego smb_common_create_directory(smb_request_t *sr)
1112c2961f8Sjose borrego {
1122c2961f8Sjose borrego 	int rc;
1132c2961f8Sjose borrego 	smb_attr_t new_attr;
114e3f2c991SKeyur Desai 	smb_fqi_t *fqi;
115e3f2c991SKeyur Desai 	smb_node_t *tnode;
1162c2961f8Sjose borrego 
117e3f2c991SKeyur Desai 	fqi = &sr->arg.dirop.fqi;
118e3f2c991SKeyur Desai 	tnode = sr->tid_tree->t_snode;
1192c2961f8Sjose borrego 
120e3f2c991SKeyur Desai 	rc = smb_pathname_reduce(sr, sr->user_cr, fqi->fq_path.pn_path,
121e3f2c991SKeyur Desai 	    tnode, tnode, &fqi->fq_dnode, fqi->fq_last_comp);
122e3f2c991SKeyur Desai 	if (rc != 0)
1232c2961f8Sjose borrego 		return (rc);
1242c2961f8Sjose borrego 
125fe1c642dSBill Krier 	if (smb_is_invalid_filename(fqi->fq_last_comp)) {
126fe1c642dSBill Krier 		smb_node_release(fqi->fq_dnode);
127fe1c642dSBill Krier 		return (EILSEQ); /* NT_STATUS_OBJECT_NAME_INVALID */
128fe1c642dSBill Krier 	}
129fe1c642dSBill Krier 
130e3f2c991SKeyur Desai 	/* lookup node - to ensure that it does NOT exist */
131e3f2c991SKeyur Desai 	rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
132e3f2c991SKeyur Desai 	    tnode, fqi->fq_dnode, fqi->fq_last_comp, &fqi->fq_fnode);
133e3f2c991SKeyur Desai 	if (rc == 0) {
134e3f2c991SKeyur Desai 		smb_node_release(fqi->fq_dnode);
135e3f2c991SKeyur Desai 		smb_node_release(fqi->fq_fnode);
136e3f2c991SKeyur Desai 		return (EEXIST);
137e3f2c991SKeyur Desai 	}
138e3f2c991SKeyur Desai 	if (rc != ENOENT) {
139e3f2c991SKeyur Desai 		smb_node_release(fqi->fq_dnode);
140e3f2c991SKeyur Desai 		return (rc);
141e3f2c991SKeyur Desai 	}
1422c2961f8Sjose borrego 
143e3f2c991SKeyur Desai 	rc = smb_fsop_access(sr, sr->user_cr, fqi->fq_dnode,
144e3f2c991SKeyur Desai 	    FILE_ADD_SUBDIRECTORY);
145e3f2c991SKeyur Desai 	if (rc != NT_STATUS_SUCCESS) {
146e3f2c991SKeyur Desai 		smb_node_release(fqi->fq_dnode);
1472c2961f8Sjose borrego 		return (EACCES);
148e3f2c991SKeyur Desai 	}
1492c2961f8Sjose borrego 
1502c2961f8Sjose borrego 	/*
1512c2961f8Sjose borrego 	 * Explicitly set sa_dosattr, otherwise the file system may
1522c2961f8Sjose borrego 	 * automatically apply FILE_ATTRIBUTE_ARCHIVE which, for
1532c2961f8Sjose borrego 	 * compatibility with windows servers, should not be set.
1542c2961f8Sjose borrego 	 */
1552c2961f8Sjose borrego 	bzero(&new_attr, sizeof (new_attr));
1562c2961f8Sjose borrego 	new_attr.sa_dosattr = FILE_ATTRIBUTE_DIRECTORY;
1572c2961f8Sjose borrego 	new_attr.sa_vattr.va_type = VDIR;
1582c2961f8Sjose borrego 	new_attr.sa_vattr.va_mode = 0777;
1592c2961f8Sjose borrego 	new_attr.sa_mask = SMB_AT_TYPE | SMB_AT_MODE | SMB_AT_DOSATTR;
1602c2961f8Sjose borrego 
161e3f2c991SKeyur Desai 	rc = smb_fsop_mkdir(sr, sr->user_cr, fqi->fq_dnode, fqi->fq_last_comp,
162e3f2c991SKeyur Desai 	    &new_attr, &fqi->fq_fnode);
163037cac00Sjoyce mcintosh 	if (rc != 0) {
164e3f2c991SKeyur Desai 		smb_node_release(fqi->fq_dnode);
165037cac00Sjoyce mcintosh 		return (rc);
166037cac00Sjoyce mcintosh 	}
1672c2961f8Sjose borrego 
1682c2961f8Sjose borrego 	sr->arg.open.create_options = FILE_DIRECTORY_FILE;
1692c2961f8Sjose borrego 
170e3f2c991SKeyur Desai 	smb_node_release(fqi->fq_dnode);
171e3f2c991SKeyur Desai 	smb_node_release(fqi->fq_fnode);
1722c2961f8Sjose borrego 	return (0);
1732c2961f8Sjose borrego }
1742c2961f8Sjose borrego 
1752c2961f8Sjose borrego /*
1762c2961f8Sjose borrego  * The delete directory message is sent to delete an empty directory. The
1772c2961f8Sjose borrego  * appropriate Tid and additional pathname are passed. The directory must
1782c2961f8Sjose borrego  * be empty for it to be deleted.
1792c2961f8Sjose borrego  *
1802c2961f8Sjose borrego  * NT supports a hidden permission known as File Delete Child (FDC). If
1812c2961f8Sjose borrego  * the user has FullControl access to a directory, the user is permitted
1822c2961f8Sjose borrego  * to delete any object in the directory regardless of the permissions
1832c2961f8Sjose borrego  * on the object.
1842c2961f8Sjose borrego  *
1852c2961f8Sjose borrego  * Client Request                     Description
1862c2961f8Sjose borrego  * ================================== =================================
1872c2961f8Sjose borrego  * UCHAR WordCount;                   Count of parameter words = 0
1882c2961f8Sjose borrego  * USHORT ByteCount;                  Count of data bytes; min = 2
1892c2961f8Sjose borrego  * UCHAR BufferFormat;                0x04
1902c2961f8Sjose borrego  * STRING DirectoryName[];            Directory name
1912c2961f8Sjose borrego  *
1922c2961f8Sjose borrego  * The directory to be deleted cannot be the root of the share specified
1932c2961f8Sjose borrego  * by Tid.
1942c2961f8Sjose borrego  *
1952c2961f8Sjose borrego  * Server Response                    Description
1962c2961f8Sjose borrego  * ================================== =================================
1972c2961f8Sjose borrego  * UCHAR WordCount;                   Count of parameter words = 0
1982c2961f8Sjose borrego  * USHORT ByteCount;                  Count of data bytes = 0
1992c2961f8Sjose borrego  */
2002c2961f8Sjose borrego smb_sdrc_t
smb_pre_delete_directory(smb_request_t * sr)2012c2961f8Sjose borrego smb_pre_delete_directory(smb_request_t *sr)
2022c2961f8Sjose borrego {
2032c2961f8Sjose borrego 	int rc;
2042c2961f8Sjose borrego 
205eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	rc = smbsr_decode_data(sr, "%S", sr,
206eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	    &sr->arg.dirop.fqi.fq_path.pn_path);
2072c2961f8Sjose borrego 
208*93bc28dbSGordon Ross 	DTRACE_SMB_START(op__DeleteDirectory, smb_request_t *, sr);
2092c2961f8Sjose borrego 
2102c2961f8Sjose borrego 	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
2112c2961f8Sjose borrego }
2122c2961f8Sjose borrego 
2132c2961f8Sjose borrego void
smb_post_delete_directory(smb_request_t * sr)2142c2961f8Sjose borrego smb_post_delete_directory(smb_request_t *sr)
2152c2961f8Sjose borrego {
216*93bc28dbSGordon Ross 	DTRACE_SMB_DONE(op__DeleteDirectory, smb_request_t *, sr);
2172c2961f8Sjose borrego }
2182c2961f8Sjose borrego 
2192c2961f8Sjose borrego smb_sdrc_t
smb_com_delete_directory(smb_request_t * sr)2202c2961f8Sjose borrego smb_com_delete_directory(smb_request_t *sr)
2212c2961f8Sjose borrego {
2222c2961f8Sjose borrego 	int rc;
2238b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	uint32_t flags = 0;
224e3f2c991SKeyur Desai 	smb_fqi_t *fqi;
225e3f2c991SKeyur Desai 	smb_node_t *tnode;
2262c2961f8Sjose borrego 
2272c2961f8Sjose borrego 	if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
2282c2961f8Sjose borrego 		smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
2292c2961f8Sjose borrego 		    ERRDOS, ERROR_ACCESS_DENIED);
2302c2961f8Sjose borrego 		return (SDRC_ERROR);
2312c2961f8Sjose borrego 	}
2322c2961f8Sjose borrego 
233e3f2c991SKeyur Desai 	fqi = &sr->arg.dirop.fqi;
234e3f2c991SKeyur Desai 	tnode = sr->tid_tree->t_snode;
2352c2961f8Sjose borrego 
236fe1c642dSBill Krier 	smb_pathname_init(sr, &fqi->fq_path, fqi->fq_path.pn_path);
237fe1c642dSBill Krier 	if (!smb_pathname_validate(sr, &fqi->fq_path) ||
238fe1c642dSBill Krier 	    !smb_validate_dirname(sr, &fqi->fq_path)) {
239fe1c642dSBill Krier 		return (SDRC_ERROR);
240fe1c642dSBill Krier 	}
241fe1c642dSBill Krier 
242e3f2c991SKeyur Desai 	rc = smb_pathname_reduce(sr, sr->user_cr, fqi->fq_path.pn_path,
243e3f2c991SKeyur Desai 	    tnode, tnode, &fqi->fq_dnode, fqi->fq_last_comp);
2449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
245e3f2c991SKeyur Desai 	if (rc != 0) {
246e3f2c991SKeyur Desai 		smbsr_errno(sr, rc);
247e3f2c991SKeyur Desai 		return (SDRC_ERROR);
248e3f2c991SKeyur Desai 	}
249e3f2c991SKeyur Desai 
250e3f2c991SKeyur Desai 	rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
251e3f2c991SKeyur Desai 	    tnode, fqi->fq_dnode, fqi->fq_last_comp, &fqi->fq_fnode);
252e3f2c991SKeyur Desai 	if (rc != 0) {
2532c2961f8Sjose borrego 		smbsr_errno(sr, rc);
254e3f2c991SKeyur Desai 		smb_node_release(fqi->fq_dnode);
2552c2961f8Sjose borrego 		return (SDRC_ERROR);
2562c2961f8Sjose borrego 	}
2572c2961f8Sjose borrego 
2589fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	/*
2599fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	 * Delete should fail if this is the root of a share
2609fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	 * or a DFS link
2619fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	 */
2629fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((fqi->fq_fnode == tnode) || smb_node_is_dfslink(fqi->fq_fnode)) {
263fe1c642dSBill Krier 		smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
264fe1c642dSBill Krier 		    ERRDOS, ERROR_ACCESS_DENIED);
265fe1c642dSBill Krier 		smb_node_release(fqi->fq_dnode);
266fe1c642dSBill Krier 		smb_node_release(fqi->fq_fnode);
267fe1c642dSBill Krier 		return (SDRC_ERROR);
268fe1c642dSBill Krier 	}
269fe1c642dSBill Krier 
2709fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_node_is_dir(fqi->fq_fnode)) {
2719fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smbsr_error(sr, NT_STATUS_NOT_A_DIRECTORY,
2729fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		    ERRDOS, ERROR_PATH_NOT_FOUND);
2739fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_node_release(fqi->fq_dnode);
2749fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_node_release(fqi->fq_fnode);
2759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SDRC_ERROR);
2769fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
2779fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
2785fd03bc0SGordon Ross 	/*
2795fd03bc0SGordon Ross 	 * Using kcred because we just want the DOS attrs
2805fd03bc0SGordon Ross 	 * and don't want access errors for this.
2815fd03bc0SGordon Ross 	 */
2825fd03bc0SGordon Ross 	fqi->fq_fattr.sa_mask = SMB_AT_DOSATTR;
2838622ec45SGordon Ross 	rc = smb_node_getattr(sr, fqi->fq_fnode, zone_kcred(), NULL,
2845fd03bc0SGordon Ross 	    &fqi->fq_fattr);
285e3f2c991SKeyur Desai 	if (rc != 0) {
286e3f2c991SKeyur Desai 		smbsr_errno(sr, rc);
287e3f2c991SKeyur Desai 		smb_node_release(fqi->fq_dnode);
288e3f2c991SKeyur Desai 		smb_node_release(fqi->fq_fnode);
289e3f2c991SKeyur Desai 		return (SDRC_ERROR);
290e3f2c991SKeyur Desai 	}
291e3f2c991SKeyur Desai 
292e3f2c991SKeyur Desai 	if ((fqi->fq_fattr.sa_dosattr & FILE_ATTRIBUTE_READONLY) ||
293e3f2c991SKeyur Desai 	    (smb_fsop_access(sr, sr->user_cr, fqi->fq_fnode, DELETE)
294e3f2c991SKeyur Desai 	    != NT_STATUS_SUCCESS)) {
2952c2961f8Sjose borrego 		smbsr_error(sr, NT_STATUS_CANNOT_DELETE,
2962c2961f8Sjose borrego 		    ERRDOS, ERROR_ACCESS_DENIED);
297e3f2c991SKeyur Desai 		smb_node_release(fqi->fq_dnode);
298e3f2c991SKeyur Desai 		smb_node_release(fqi->fq_fnode);
2992c2961f8Sjose borrego 		return (SDRC_ERROR);
3002c2961f8Sjose borrego 	}
3012c2961f8Sjose borrego 
3028b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 	if (SMB_TREE_SUPPORTS_CATIA(sr))
3038b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 		flags |= SMB_CATIA;
3048b2cc8acSafshin salek ardakani - Sun Microsystems - Irvine United States 
305e3f2c991SKeyur Desai 	rc = smb_fsop_rmdir(sr, sr->user_cr, fqi->fq_dnode,
306e3f2c991SKeyur Desai 	    fqi->fq_fnode->od_name, flags);
307e3f2c991SKeyur Desai 
308e3f2c991SKeyur Desai 	smb_node_release(fqi->fq_fnode);
309e3f2c991SKeyur Desai 	smb_node_release(fqi->fq_dnode);
310e3f2c991SKeyur Desai 
3112c2961f8Sjose borrego 	if (rc != 0) {
3122c2961f8Sjose borrego 		if (rc == EEXIST)
3132c2961f8Sjose borrego 			smbsr_error(sr, NT_STATUS_DIRECTORY_NOT_EMPTY,
3142c2961f8Sjose borrego 			    ERRDOS, ERROR_DIR_NOT_EMPTY);
3152c2961f8Sjose borrego 		else
3162c2961f8Sjose borrego 			smbsr_errno(sr, rc);
3172c2961f8Sjose borrego 		return (SDRC_ERROR);
3182c2961f8Sjose borrego 	}
3192c2961f8Sjose borrego 
3202c2961f8Sjose borrego 	rc = smbsr_encode_empty_result(sr);
3212c2961f8Sjose borrego 	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
3222c2961f8Sjose borrego }
3232c2961f8Sjose borrego 
3242c2961f8Sjose borrego /*
3252c2961f8Sjose borrego  * This SMB is used to verify that a path exists and is a directory.  No
3262c2961f8Sjose borrego  * error is returned if the given path exists and the client has read
3272c2961f8Sjose borrego  * access to it.  Client machines which maintain a concept of a "working
3282c2961f8Sjose borrego  * directory" will find this useful to verify the validity of a "change
3292c2961f8Sjose borrego  * working directory" command.  Note that the servers do NOT have a concept
3302c2961f8Sjose borrego  * of working directory for a particular client.  The client must always
3312c2961f8Sjose borrego  * supply full pathnames relative to the Tid in the SMB header.
3322c2961f8Sjose borrego  *
3332c2961f8Sjose borrego  * Client Request                     Description
3342c2961f8Sjose borrego  * ================================== =================================
3352c2961f8Sjose borrego  *
3362c2961f8Sjose borrego  * UCHAR WordCount;                   Count of parameter words = 0
3372c2961f8Sjose borrego  * USHORT ByteCount;                  Count of data bytes;    min = 2
3382c2961f8Sjose borrego  * UCHAR BufferFormat;                0x04
3392c2961f8Sjose borrego  * STRING DirectoryPath[];            Directory path
3402c2961f8Sjose borrego  *
3412c2961f8Sjose borrego  * Server Response                    Description
3422c2961f8Sjose borrego  * ================================== =================================
3432c2961f8Sjose borrego  *
3442c2961f8Sjose borrego  * UCHAR WordCount;                   Count of parameter words = 0
3452c2961f8Sjose borrego  * USHORT ByteCount;                  Count of data bytes = 0
3462c2961f8Sjose borrego  *
3472c2961f8Sjose borrego  * DOS clients, in particular, depend on ERRbadpath if the directory is
3482c2961f8Sjose borrego  * not found.
3492c2961f8Sjose borrego  */
3502c2961f8Sjose borrego smb_sdrc_t
smb_pre_check_directory(smb_request_t * sr)3512c2961f8Sjose borrego smb_pre_check_directory(smb_request_t *sr)
3522c2961f8Sjose borrego {
3532c2961f8Sjose borrego 	int rc;
3542c2961f8Sjose borrego 
355eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	rc = smbsr_decode_data(sr, "%S", sr,
356eb1d736bSafshin salek ardakani - Sun Microsystems - Irvine United States 	    &sr->arg.dirop.fqi.fq_path.pn_path);
3572c2961f8Sjose borrego 
358*93bc28dbSGordon Ross 	DTRACE_SMB_START(op__CheckDirectory, smb_request_t *, sr);
3592c2961f8Sjose borrego 
3602c2961f8Sjose borrego 	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
3612c2961f8Sjose borrego }
3622c2961f8Sjose borrego 
3632c2961f8Sjose borrego void
smb_post_check_directory(smb_request_t * sr)3642c2961f8Sjose borrego smb_post_check_directory(smb_request_t *sr)
3652c2961f8Sjose borrego {
366*93bc28dbSGordon Ross 	DTRACE_SMB_DONE(op__CheckDirectory, smb_request_t *, sr);
3672c2961f8Sjose borrego }
3682c2961f8Sjose borrego 
3692c2961f8Sjose borrego smb_sdrc_t
smb_com_check_directory(smb_request_t * sr)3702c2961f8Sjose borrego smb_com_check_directory(smb_request_t *sr)
3712c2961f8Sjose borrego {
3722c2961f8Sjose borrego 	int rc;
373e3f2c991SKeyur Desai 	smb_fqi_t *fqi;
374e3f2c991SKeyur Desai 	smb_node_t *tnode;
3759fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_node_t *node;
376e3f2c991SKeyur Desai 	char *path;
377fe1c642dSBill Krier 	smb_pathname_t *pn;
3782c2961f8Sjose borrego 
379f96bd5c8SAlan Wright 	if (STYPE_ISIPC(sr->tid_tree->t_res_type)) {
3802c2961f8Sjose borrego 		smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
3812c2961f8Sjose borrego 		    ERROR_ACCESS_DENIED);
3822c2961f8Sjose borrego 		return (SDRC_ERROR);
3832c2961f8Sjose borrego 	}
3842c2961f8Sjose borrego 
385e3f2c991SKeyur Desai 	fqi = &sr->arg.dirop.fqi;
386fe1c642dSBill Krier 	pn = &fqi->fq_path;
387e3f2c991SKeyur Desai 
388fe1c642dSBill Krier 	if (pn->pn_path[0] == '\0') {
3892c2961f8Sjose borrego 		rc = smbsr_encode_empty_result(sr);
3902c2961f8Sjose borrego 		return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
3912c2961f8Sjose borrego 	}
3922c2961f8Sjose borrego 
393fe1c642dSBill Krier 	smb_pathname_init(sr, pn, pn->pn_path);
394fe1c642dSBill Krier 	if (!smb_pathname_validate(sr, pn) ||
395fe1c642dSBill Krier 	    !smb_validate_dirname(sr, pn)) {
3962c2961f8Sjose borrego 		return (SDRC_ERROR);
3972c2961f8Sjose borrego 	}
3982c2961f8Sjose borrego 
399fe1c642dSBill Krier 	path = pn->pn_path;
400e3f2c991SKeyur Desai 	tnode = sr->tid_tree->t_snode;
4012c2961f8Sjose borrego 
402e3f2c991SKeyur Desai 	rc = smb_pathname_reduce(sr, sr->user_cr, path, tnode, tnode,
403e3f2c991SKeyur Desai 	    &fqi->fq_dnode, fqi->fq_last_comp);
404e3f2c991SKeyur Desai 	if (rc != 0) {
405e3f2c991SKeyur Desai 		smbsr_errno(sr, rc);
406e3f2c991SKeyur Desai 		return (SDRC_ERROR);
407e3f2c991SKeyur Desai 	}
408e3f2c991SKeyur Desai 
409e3f2c991SKeyur Desai 	rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
410e3f2c991SKeyur Desai 	    tnode, fqi->fq_dnode, fqi->fq_last_comp, &fqi->fq_fnode);
411e3f2c991SKeyur Desai 	smb_node_release(fqi->fq_dnode);
412e3f2c991SKeyur Desai 	if (rc != 0) {
4132c2961f8Sjose borrego 		smbsr_errno(sr, rc);
4142c2961f8Sjose borrego 		return (SDRC_ERROR);
4152c2961f8Sjose borrego 	}
4162c2961f8Sjose borrego 
4179fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	node = fqi->fq_fnode;
4189fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if (!smb_node_is_dir(node)) {
419e3f2c991SKeyur Desai 		smbsr_error(sr, NT_STATUS_NOT_A_DIRECTORY,
420e3f2c991SKeyur Desai 		    ERRDOS, ERROR_PATH_NOT_FOUND);
4219fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_node_release(node);
422e3f2c991SKeyur Desai 		return (SDRC_ERROR);
423e3f2c991SKeyur Desai 	}
4242c2961f8Sjose borrego 
4259fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	if ((sr->smb_flg2 & SMB_FLAGS2_DFS) && smb_node_is_dfslink(node)) {
4269fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smbsr_error(sr, NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
4279fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		smb_node_release(node);
4289fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 		return (SDRC_ERROR);
4299fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	}
430e3f2c991SKeyur Desai 
4319fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	rc = smb_fsop_access(sr, sr->user_cr, node, FILE_TRAVERSE);
4329fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
4339fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_node_release(node);
4342c2961f8Sjose borrego 
4352c2961f8Sjose borrego 	if (rc != 0) {
4362c2961f8Sjose borrego 		smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
4372c2961f8Sjose borrego 		    ERRDOS, ERROR_ACCESS_DENIED);
4382c2961f8Sjose borrego 		return (SDRC_ERROR);
4392c2961f8Sjose borrego 	}
4402c2961f8Sjose borrego 
4412c2961f8Sjose borrego 	rc = smbsr_encode_empty_result(sr);
4422c2961f8Sjose borrego 	return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
4432c2961f8Sjose borrego }
444