18934SJose.Borrego@Sun.COM /*
28934SJose.Borrego@Sun.COM * CDDL HEADER START
38934SJose.Borrego@Sun.COM *
48934SJose.Borrego@Sun.COM * The contents of this file are subject to the terms of the
58934SJose.Borrego@Sun.COM * Common Development and Distribution License (the "License").
68934SJose.Borrego@Sun.COM * You may not use this file except in compliance with the License.
78934SJose.Borrego@Sun.COM *
88934SJose.Borrego@Sun.COM * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
98934SJose.Borrego@Sun.COM * or http://www.opensolaris.org/os/licensing.
108934SJose.Borrego@Sun.COM * See the License for the specific language governing permissions
118934SJose.Borrego@Sun.COM * and limitations under the License.
128934SJose.Borrego@Sun.COM *
138934SJose.Borrego@Sun.COM * When distributing Covered Code, include this CDDL HEADER in each
148934SJose.Borrego@Sun.COM * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
158934SJose.Borrego@Sun.COM * If applicable, add the following below this CDDL HEADER, with the
168934SJose.Borrego@Sun.COM * fields enclosed by brackets "[]" replaced with your own identifying
178934SJose.Borrego@Sun.COM * information: Portions Copyright [yyyy] [name of copyright owner]
188934SJose.Borrego@Sun.COM *
198934SJose.Borrego@Sun.COM * CDDL HEADER END
208934SJose.Borrego@Sun.COM */
218934SJose.Borrego@Sun.COM /*
2211447Samw@Sun.COM * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
238934SJose.Borrego@Sun.COM * Use is subject to license terms.
248934SJose.Borrego@Sun.COM */
258934SJose.Borrego@Sun.COM
2610966SJordan.Brown@Sun.COM #include <smbsrv/smb_kproto.h>
278934SJose.Borrego@Sun.COM #include <smbsrv/smbinfo.h>
288934SJose.Borrego@Sun.COM #include <smbsrv/smb_fsops.h>
298934SJose.Borrego@Sun.COM
308934SJose.Borrego@Sun.COM /*
318934SJose.Borrego@Sun.COM * The create directory message is sent to create a new directory. The
328934SJose.Borrego@Sun.COM * appropriate Tid and additional pathname are passed. The directory must
338934SJose.Borrego@Sun.COM * not exist for it to be created.
348934SJose.Borrego@Sun.COM *
358934SJose.Borrego@Sun.COM * Client Request Description
368934SJose.Borrego@Sun.COM * ================================== =================================
378934SJose.Borrego@Sun.COM * UCHAR WordCount; Count of parameter words = 0
388934SJose.Borrego@Sun.COM * USHORT ByteCount; Count of data bytes; min = 2
398934SJose.Borrego@Sun.COM * UCHAR BufferFormat; 0x04
408934SJose.Borrego@Sun.COM * STRING DirectoryName[]; Directory name
418934SJose.Borrego@Sun.COM *
428934SJose.Borrego@Sun.COM * Servers require clients to have at least create permission for the
438934SJose.Borrego@Sun.COM * subtree containing the directory in order to create a new directory.
448934SJose.Borrego@Sun.COM * The creator's access rights to the new directory are be determined by
458934SJose.Borrego@Sun.COM * local policy on the server.
468934SJose.Borrego@Sun.COM *
478934SJose.Borrego@Sun.COM * Server Response Description
488934SJose.Borrego@Sun.COM * ================================== =================================
498934SJose.Borrego@Sun.COM * UCHAR WordCount; Count of parameter words = 0
508934SJose.Borrego@Sun.COM * USHORT ByteCount; Count of data bytes = 0
518934SJose.Borrego@Sun.COM */
528934SJose.Borrego@Sun.COM smb_sdrc_t
smb_pre_create_directory(smb_request_t * sr)538934SJose.Borrego@Sun.COM smb_pre_create_directory(smb_request_t *sr)
548934SJose.Borrego@Sun.COM {
558934SJose.Borrego@Sun.COM int rc;
568934SJose.Borrego@Sun.COM
579343SAfshin.Ardakani@Sun.COM rc = smbsr_decode_data(sr, "%S", sr,
589343SAfshin.Ardakani@Sun.COM &sr->arg.dirop.fqi.fq_path.pn_path);
598934SJose.Borrego@Sun.COM
608934SJose.Borrego@Sun.COM DTRACE_SMB_2(op__CreateDirectory__start, smb_request_t *, sr,
618934SJose.Borrego@Sun.COM struct dirop *, &sr->arg.dirop);
628934SJose.Borrego@Sun.COM
638934SJose.Borrego@Sun.COM return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
648934SJose.Borrego@Sun.COM }
658934SJose.Borrego@Sun.COM
668934SJose.Borrego@Sun.COM void
smb_post_create_directory(smb_request_t * sr)678934SJose.Borrego@Sun.COM smb_post_create_directory(smb_request_t *sr)
688934SJose.Borrego@Sun.COM {
698934SJose.Borrego@Sun.COM DTRACE_SMB_1(op__CreateDirectory__done, smb_request_t *, sr);
708934SJose.Borrego@Sun.COM }
718934SJose.Borrego@Sun.COM
728934SJose.Borrego@Sun.COM smb_sdrc_t
smb_com_create_directory(smb_request_t * sr)738934SJose.Borrego@Sun.COM smb_com_create_directory(smb_request_t *sr)
748934SJose.Borrego@Sun.COM {
758934SJose.Borrego@Sun.COM int rc = 0;
7611337SWilliam.Krier@Sun.COM smb_pathname_t *pn = &sr->arg.dirop.fqi.fq_path;
778934SJose.Borrego@Sun.COM
788934SJose.Borrego@Sun.COM if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
798934SJose.Borrego@Sun.COM smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
808934SJose.Borrego@Sun.COM ERRDOS, ERROR_ACCESS_DENIED);
818934SJose.Borrego@Sun.COM return (SDRC_ERROR);
828934SJose.Borrego@Sun.COM }
838934SJose.Borrego@Sun.COM
8411337SWilliam.Krier@Sun.COM smb_pathname_init(sr, pn, pn->pn_path);
8511337SWilliam.Krier@Sun.COM if (!smb_pathname_validate(sr, pn) ||
8611337SWilliam.Krier@Sun.COM !smb_validate_dirname(sr, pn)) {
878934SJose.Borrego@Sun.COM return (SDRC_ERROR);
888934SJose.Borrego@Sun.COM }
898934SJose.Borrego@Sun.COM
9011337SWilliam.Krier@Sun.COM if ((rc = smb_common_create_directory(sr)) != 0) {
9111337SWilliam.Krier@Sun.COM smbsr_errno(sr, rc);
928934SJose.Borrego@Sun.COM return (SDRC_ERROR);
938934SJose.Borrego@Sun.COM }
948934SJose.Borrego@Sun.COM
958934SJose.Borrego@Sun.COM rc = smbsr_encode_empty_result(sr);
968934SJose.Borrego@Sun.COM return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
978934SJose.Borrego@Sun.COM }
988934SJose.Borrego@Sun.COM
998934SJose.Borrego@Sun.COM /*
1008934SJose.Borrego@Sun.COM * smb_common_create_directory
1018934SJose.Borrego@Sun.COM *
1028934SJose.Borrego@Sun.COM * Currently called from:
1038934SJose.Borrego@Sun.COM * smb_com_create_directory
1048934SJose.Borrego@Sun.COM * smb_com_trans2_create_directory
1058934SJose.Borrego@Sun.COM *
1068934SJose.Borrego@Sun.COM * Returns errno values.
1078934SJose.Borrego@Sun.COM */
1088934SJose.Borrego@Sun.COM int
smb_common_create_directory(smb_request_t * sr)1098934SJose.Borrego@Sun.COM smb_common_create_directory(smb_request_t *sr)
1108934SJose.Borrego@Sun.COM {
1118934SJose.Borrego@Sun.COM int rc;
1128934SJose.Borrego@Sun.COM smb_attr_t new_attr;
11310504SKeyur.Desai@Sun.COM smb_fqi_t *fqi;
11410504SKeyur.Desai@Sun.COM smb_node_t *tnode;
1158934SJose.Borrego@Sun.COM
11610504SKeyur.Desai@Sun.COM fqi = &sr->arg.dirop.fqi;
11710504SKeyur.Desai@Sun.COM tnode = sr->tid_tree->t_snode;
1188934SJose.Borrego@Sun.COM
11910504SKeyur.Desai@Sun.COM rc = smb_pathname_reduce(sr, sr->user_cr, fqi->fq_path.pn_path,
12010504SKeyur.Desai@Sun.COM tnode, tnode, &fqi->fq_dnode, fqi->fq_last_comp);
12110504SKeyur.Desai@Sun.COM if (rc != 0)
1228934SJose.Borrego@Sun.COM return (rc);
1238934SJose.Borrego@Sun.COM
12411337SWilliam.Krier@Sun.COM if (smb_is_invalid_filename(fqi->fq_last_comp)) {
12511337SWilliam.Krier@Sun.COM smb_node_release(fqi->fq_dnode);
12611337SWilliam.Krier@Sun.COM return (EILSEQ); /* NT_STATUS_OBJECT_NAME_INVALID */
12711337SWilliam.Krier@Sun.COM }
12811337SWilliam.Krier@Sun.COM
12910504SKeyur.Desai@Sun.COM /* lookup node - to ensure that it does NOT exist */
13010504SKeyur.Desai@Sun.COM rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
13110504SKeyur.Desai@Sun.COM tnode, fqi->fq_dnode, fqi->fq_last_comp, &fqi->fq_fnode);
13210504SKeyur.Desai@Sun.COM if (rc == 0) {
13310504SKeyur.Desai@Sun.COM smb_node_release(fqi->fq_dnode);
13410504SKeyur.Desai@Sun.COM smb_node_release(fqi->fq_fnode);
13510504SKeyur.Desai@Sun.COM return (EEXIST);
13610504SKeyur.Desai@Sun.COM }
13710504SKeyur.Desai@Sun.COM if (rc != ENOENT) {
13810504SKeyur.Desai@Sun.COM smb_node_release(fqi->fq_dnode);
13910504SKeyur.Desai@Sun.COM return (rc);
14010504SKeyur.Desai@Sun.COM }
1418934SJose.Borrego@Sun.COM
14210504SKeyur.Desai@Sun.COM rc = smb_fsop_access(sr, sr->user_cr, fqi->fq_dnode,
14310504SKeyur.Desai@Sun.COM FILE_ADD_SUBDIRECTORY);
14410504SKeyur.Desai@Sun.COM if (rc != NT_STATUS_SUCCESS) {
14510504SKeyur.Desai@Sun.COM smb_node_release(fqi->fq_dnode);
1468934SJose.Borrego@Sun.COM return (EACCES);
14710504SKeyur.Desai@Sun.COM }
1488934SJose.Borrego@Sun.COM
1498934SJose.Borrego@Sun.COM /*
1508934SJose.Borrego@Sun.COM * Explicitly set sa_dosattr, otherwise the file system may
1518934SJose.Borrego@Sun.COM * automatically apply FILE_ATTRIBUTE_ARCHIVE which, for
1528934SJose.Borrego@Sun.COM * compatibility with windows servers, should not be set.
1538934SJose.Borrego@Sun.COM */
1548934SJose.Borrego@Sun.COM bzero(&new_attr, sizeof (new_attr));
1558934SJose.Borrego@Sun.COM new_attr.sa_dosattr = FILE_ATTRIBUTE_DIRECTORY;
1568934SJose.Borrego@Sun.COM new_attr.sa_vattr.va_type = VDIR;
1578934SJose.Borrego@Sun.COM new_attr.sa_vattr.va_mode = 0777;
1588934SJose.Borrego@Sun.COM new_attr.sa_mask = SMB_AT_TYPE | SMB_AT_MODE | SMB_AT_DOSATTR;
1598934SJose.Borrego@Sun.COM
16010504SKeyur.Desai@Sun.COM rc = smb_fsop_mkdir(sr, sr->user_cr, fqi->fq_dnode, fqi->fq_last_comp,
16110504SKeyur.Desai@Sun.COM &new_attr, &fqi->fq_fnode);
16210504SKeyur.Desai@Sun.COM if (rc != 0) {
16310504SKeyur.Desai@Sun.COM smb_node_release(fqi->fq_dnode);
1648934SJose.Borrego@Sun.COM return (rc);
1658934SJose.Borrego@Sun.COM }
1668934SJose.Borrego@Sun.COM
1678934SJose.Borrego@Sun.COM sr->arg.open.create_options = FILE_DIRECTORY_FILE;
1688934SJose.Borrego@Sun.COM
16910504SKeyur.Desai@Sun.COM smb_node_release(fqi->fq_dnode);
17010504SKeyur.Desai@Sun.COM smb_node_release(fqi->fq_fnode);
1718934SJose.Borrego@Sun.COM return (0);
1728934SJose.Borrego@Sun.COM }
1738934SJose.Borrego@Sun.COM
1748934SJose.Borrego@Sun.COM /*
1758934SJose.Borrego@Sun.COM * The delete directory message is sent to delete an empty directory. The
1768934SJose.Borrego@Sun.COM * appropriate Tid and additional pathname are passed. The directory must
1778934SJose.Borrego@Sun.COM * be empty for it to be deleted.
1788934SJose.Borrego@Sun.COM *
1798934SJose.Borrego@Sun.COM * NT supports a hidden permission known as File Delete Child (FDC). If
1808934SJose.Borrego@Sun.COM * the user has FullControl access to a directory, the user is permitted
1818934SJose.Borrego@Sun.COM * to delete any object in the directory regardless of the permissions
1828934SJose.Borrego@Sun.COM * on the object.
1838934SJose.Borrego@Sun.COM *
1848934SJose.Borrego@Sun.COM * Client Request Description
1858934SJose.Borrego@Sun.COM * ================================== =================================
1868934SJose.Borrego@Sun.COM * UCHAR WordCount; Count of parameter words = 0
1878934SJose.Borrego@Sun.COM * USHORT ByteCount; Count of data bytes; min = 2
1888934SJose.Borrego@Sun.COM * UCHAR BufferFormat; 0x04
1898934SJose.Borrego@Sun.COM * STRING DirectoryName[]; Directory name
1908934SJose.Borrego@Sun.COM *
1918934SJose.Borrego@Sun.COM * The directory to be deleted cannot be the root of the share specified
1928934SJose.Borrego@Sun.COM * by Tid.
1938934SJose.Borrego@Sun.COM *
1948934SJose.Borrego@Sun.COM * Server Response Description
1958934SJose.Borrego@Sun.COM * ================================== =================================
1968934SJose.Borrego@Sun.COM * UCHAR WordCount; Count of parameter words = 0
1978934SJose.Borrego@Sun.COM * USHORT ByteCount; Count of data bytes = 0
1988934SJose.Borrego@Sun.COM */
1998934SJose.Borrego@Sun.COM smb_sdrc_t
smb_pre_delete_directory(smb_request_t * sr)2008934SJose.Borrego@Sun.COM smb_pre_delete_directory(smb_request_t *sr)
2018934SJose.Borrego@Sun.COM {
2028934SJose.Borrego@Sun.COM int rc;
2038934SJose.Borrego@Sun.COM
2049343SAfshin.Ardakani@Sun.COM rc = smbsr_decode_data(sr, "%S", sr,
2059343SAfshin.Ardakani@Sun.COM &sr->arg.dirop.fqi.fq_path.pn_path);
2068934SJose.Borrego@Sun.COM
2078934SJose.Borrego@Sun.COM DTRACE_SMB_2(op__DeleteDirectory__start, smb_request_t *, sr,
2088934SJose.Borrego@Sun.COM struct dirop *, &sr->arg.dirop);
2098934SJose.Borrego@Sun.COM
2108934SJose.Borrego@Sun.COM return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
2118934SJose.Borrego@Sun.COM }
2128934SJose.Borrego@Sun.COM
2138934SJose.Borrego@Sun.COM void
smb_post_delete_directory(smb_request_t * sr)2148934SJose.Borrego@Sun.COM smb_post_delete_directory(smb_request_t *sr)
2158934SJose.Borrego@Sun.COM {
2168934SJose.Borrego@Sun.COM DTRACE_SMB_1(op__DeleteDirectory__done, smb_request_t *, sr);
2178934SJose.Borrego@Sun.COM }
2188934SJose.Borrego@Sun.COM
2198934SJose.Borrego@Sun.COM smb_sdrc_t
smb_com_delete_directory(smb_request_t * sr)2208934SJose.Borrego@Sun.COM smb_com_delete_directory(smb_request_t *sr)
2218934SJose.Borrego@Sun.COM {
2228934SJose.Borrego@Sun.COM int rc;
2239231SAfshin.Ardakani@Sun.COM uint32_t flags = 0;
22410504SKeyur.Desai@Sun.COM smb_fqi_t *fqi;
22510504SKeyur.Desai@Sun.COM smb_node_t *tnode;
2268934SJose.Borrego@Sun.COM
2278934SJose.Borrego@Sun.COM if (!STYPE_ISDSK(sr->tid_tree->t_res_type)) {
2288934SJose.Borrego@Sun.COM smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
2298934SJose.Borrego@Sun.COM ERRDOS, ERROR_ACCESS_DENIED);
2308934SJose.Borrego@Sun.COM return (SDRC_ERROR);
2318934SJose.Borrego@Sun.COM }
2328934SJose.Borrego@Sun.COM
23310504SKeyur.Desai@Sun.COM fqi = &sr->arg.dirop.fqi;
23410504SKeyur.Desai@Sun.COM tnode = sr->tid_tree->t_snode;
2358934SJose.Borrego@Sun.COM
23611337SWilliam.Krier@Sun.COM smb_pathname_init(sr, &fqi->fq_path, fqi->fq_path.pn_path);
23711337SWilliam.Krier@Sun.COM if (!smb_pathname_validate(sr, &fqi->fq_path) ||
23811337SWilliam.Krier@Sun.COM !smb_validate_dirname(sr, &fqi->fq_path)) {
23911337SWilliam.Krier@Sun.COM return (SDRC_ERROR);
24011337SWilliam.Krier@Sun.COM }
24111337SWilliam.Krier@Sun.COM
24210504SKeyur.Desai@Sun.COM rc = smb_pathname_reduce(sr, sr->user_cr, fqi->fq_path.pn_path,
24310504SKeyur.Desai@Sun.COM tnode, tnode, &fqi->fq_dnode, fqi->fq_last_comp);
244*11963SAfshin.Ardakani@Sun.COM
24510504SKeyur.Desai@Sun.COM if (rc != 0) {
24610504SKeyur.Desai@Sun.COM smbsr_errno(sr, rc);
24710504SKeyur.Desai@Sun.COM return (SDRC_ERROR);
24810504SKeyur.Desai@Sun.COM }
24910504SKeyur.Desai@Sun.COM
25010504SKeyur.Desai@Sun.COM rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
25110504SKeyur.Desai@Sun.COM tnode, fqi->fq_dnode, fqi->fq_last_comp, &fqi->fq_fnode);
25210504SKeyur.Desai@Sun.COM if (rc != 0) {
2538934SJose.Borrego@Sun.COM if (rc == ENOENT)
2548934SJose.Borrego@Sun.COM smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND,
2558934SJose.Borrego@Sun.COM ERRDOS, ERROR_FILE_NOT_FOUND);
2568934SJose.Borrego@Sun.COM else
2578934SJose.Borrego@Sun.COM smbsr_errno(sr, rc);
25810504SKeyur.Desai@Sun.COM smb_node_release(fqi->fq_dnode);
2598934SJose.Borrego@Sun.COM return (SDRC_ERROR);
2608934SJose.Borrego@Sun.COM }
2618934SJose.Borrego@Sun.COM
262*11963SAfshin.Ardakani@Sun.COM /*
263*11963SAfshin.Ardakani@Sun.COM * Delete should fail if this is the root of a share
264*11963SAfshin.Ardakani@Sun.COM * or a DFS link
265*11963SAfshin.Ardakani@Sun.COM */
266*11963SAfshin.Ardakani@Sun.COM if ((fqi->fq_fnode == tnode) || smb_node_is_dfslink(fqi->fq_fnode)) {
26711337SWilliam.Krier@Sun.COM smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
26811337SWilliam.Krier@Sun.COM ERRDOS, ERROR_ACCESS_DENIED);
26911337SWilliam.Krier@Sun.COM smb_node_release(fqi->fq_dnode);
27011337SWilliam.Krier@Sun.COM smb_node_release(fqi->fq_fnode);
27111337SWilliam.Krier@Sun.COM return (SDRC_ERROR);
27211337SWilliam.Krier@Sun.COM }
27311337SWilliam.Krier@Sun.COM
274*11963SAfshin.Ardakani@Sun.COM if (!smb_node_is_dir(fqi->fq_fnode)) {
275*11963SAfshin.Ardakani@Sun.COM smbsr_error(sr, NT_STATUS_NOT_A_DIRECTORY,
276*11963SAfshin.Ardakani@Sun.COM ERRDOS, ERROR_PATH_NOT_FOUND);
277*11963SAfshin.Ardakani@Sun.COM smb_node_release(fqi->fq_dnode);
278*11963SAfshin.Ardakani@Sun.COM smb_node_release(fqi->fq_fnode);
279*11963SAfshin.Ardakani@Sun.COM return (SDRC_ERROR);
280*11963SAfshin.Ardakani@Sun.COM }
281*11963SAfshin.Ardakani@Sun.COM
28210504SKeyur.Desai@Sun.COM rc = smb_node_getattr(sr, fqi->fq_fnode, &fqi->fq_fattr);
28310504SKeyur.Desai@Sun.COM if (rc != 0) {
28410504SKeyur.Desai@Sun.COM smbsr_errno(sr, rc);
28510504SKeyur.Desai@Sun.COM smb_node_release(fqi->fq_dnode);
28610504SKeyur.Desai@Sun.COM smb_node_release(fqi->fq_fnode);
2878934SJose.Borrego@Sun.COM return (SDRC_ERROR);
2888934SJose.Borrego@Sun.COM }
2898934SJose.Borrego@Sun.COM
29010504SKeyur.Desai@Sun.COM if ((fqi->fq_fattr.sa_dosattr & FILE_ATTRIBUTE_READONLY) ||
29110504SKeyur.Desai@Sun.COM (smb_fsop_access(sr, sr->user_cr, fqi->fq_fnode, DELETE)
29210504SKeyur.Desai@Sun.COM != NT_STATUS_SUCCESS)) {
29310504SKeyur.Desai@Sun.COM smbsr_error(sr, NT_STATUS_CANNOT_DELETE,
29410504SKeyur.Desai@Sun.COM ERRDOS, ERROR_ACCESS_DENIED);
29510504SKeyur.Desai@Sun.COM smb_node_release(fqi->fq_dnode);
29610504SKeyur.Desai@Sun.COM smb_node_release(fqi->fq_fnode);
29710504SKeyur.Desai@Sun.COM return (SDRC_ERROR);
29810504SKeyur.Desai@Sun.COM }
2998934SJose.Borrego@Sun.COM
3009231SAfshin.Ardakani@Sun.COM if (SMB_TREE_SUPPORTS_CATIA(sr))
3019231SAfshin.Ardakani@Sun.COM flags |= SMB_CATIA;
3029231SAfshin.Ardakani@Sun.COM
30310504SKeyur.Desai@Sun.COM rc = smb_fsop_rmdir(sr, sr->user_cr, fqi->fq_dnode,
30410504SKeyur.Desai@Sun.COM fqi->fq_fnode->od_name, flags);
30510504SKeyur.Desai@Sun.COM
30610504SKeyur.Desai@Sun.COM smb_node_release(fqi->fq_fnode);
30710504SKeyur.Desai@Sun.COM smb_node_release(fqi->fq_dnode);
30810504SKeyur.Desai@Sun.COM
3098934SJose.Borrego@Sun.COM if (rc != 0) {
3108934SJose.Borrego@Sun.COM if (rc == EEXIST)
3118934SJose.Borrego@Sun.COM smbsr_error(sr, NT_STATUS_DIRECTORY_NOT_EMPTY,
3128934SJose.Borrego@Sun.COM ERRDOS, ERROR_DIR_NOT_EMPTY);
3138934SJose.Borrego@Sun.COM else
3148934SJose.Borrego@Sun.COM smbsr_errno(sr, rc);
3158934SJose.Borrego@Sun.COM return (SDRC_ERROR);
3168934SJose.Borrego@Sun.COM }
3178934SJose.Borrego@Sun.COM
3188934SJose.Borrego@Sun.COM rc = smbsr_encode_empty_result(sr);
3198934SJose.Borrego@Sun.COM return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
3208934SJose.Borrego@Sun.COM }
3218934SJose.Borrego@Sun.COM
3228934SJose.Borrego@Sun.COM /*
3238934SJose.Borrego@Sun.COM * This SMB is used to verify that a path exists and is a directory. No
3248934SJose.Borrego@Sun.COM * error is returned if the given path exists and the client has read
3258934SJose.Borrego@Sun.COM * access to it. Client machines which maintain a concept of a "working
3268934SJose.Borrego@Sun.COM * directory" will find this useful to verify the validity of a "change
3278934SJose.Borrego@Sun.COM * working directory" command. Note that the servers do NOT have a concept
3288934SJose.Borrego@Sun.COM * of working directory for a particular client. The client must always
3298934SJose.Borrego@Sun.COM * supply full pathnames relative to the Tid in the SMB header.
3308934SJose.Borrego@Sun.COM *
3318934SJose.Borrego@Sun.COM * Client Request Description
3328934SJose.Borrego@Sun.COM * ================================== =================================
3338934SJose.Borrego@Sun.COM *
3348934SJose.Borrego@Sun.COM * UCHAR WordCount; Count of parameter words = 0
3358934SJose.Borrego@Sun.COM * USHORT ByteCount; Count of data bytes; min = 2
3368934SJose.Borrego@Sun.COM * UCHAR BufferFormat; 0x04
3378934SJose.Borrego@Sun.COM * STRING DirectoryPath[]; Directory path
3388934SJose.Borrego@Sun.COM *
3398934SJose.Borrego@Sun.COM * Server Response Description
3408934SJose.Borrego@Sun.COM * ================================== =================================
3418934SJose.Borrego@Sun.COM *
3428934SJose.Borrego@Sun.COM * UCHAR WordCount; Count of parameter words = 0
3438934SJose.Borrego@Sun.COM * USHORT ByteCount; Count of data bytes = 0
3448934SJose.Borrego@Sun.COM *
3458934SJose.Borrego@Sun.COM * DOS clients, in particular, depend on ERRbadpath if the directory is
3468934SJose.Borrego@Sun.COM * not found.
3478934SJose.Borrego@Sun.COM */
3488934SJose.Borrego@Sun.COM smb_sdrc_t
smb_pre_check_directory(smb_request_t * sr)3498934SJose.Borrego@Sun.COM smb_pre_check_directory(smb_request_t *sr)
3508934SJose.Borrego@Sun.COM {
3518934SJose.Borrego@Sun.COM int rc;
3528934SJose.Borrego@Sun.COM
3539343SAfshin.Ardakani@Sun.COM rc = smbsr_decode_data(sr, "%S", sr,
3549343SAfshin.Ardakani@Sun.COM &sr->arg.dirop.fqi.fq_path.pn_path);
3558934SJose.Borrego@Sun.COM
3568934SJose.Borrego@Sun.COM DTRACE_SMB_2(op__CheckDirectory__start, smb_request_t *, sr,
3578934SJose.Borrego@Sun.COM struct dirop *, &sr->arg.dirop);
3588934SJose.Borrego@Sun.COM
3598934SJose.Borrego@Sun.COM return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
3608934SJose.Borrego@Sun.COM }
3618934SJose.Borrego@Sun.COM
3628934SJose.Borrego@Sun.COM void
smb_post_check_directory(smb_request_t * sr)3638934SJose.Borrego@Sun.COM smb_post_check_directory(smb_request_t *sr)
3648934SJose.Borrego@Sun.COM {
3658934SJose.Borrego@Sun.COM DTRACE_SMB_1(op__CheckDirectory__done, smb_request_t *, sr);
3668934SJose.Borrego@Sun.COM }
3678934SJose.Borrego@Sun.COM
3688934SJose.Borrego@Sun.COM smb_sdrc_t
smb_com_check_directory(smb_request_t * sr)3698934SJose.Borrego@Sun.COM smb_com_check_directory(smb_request_t *sr)
3708934SJose.Borrego@Sun.COM {
3718934SJose.Borrego@Sun.COM int rc;
37210504SKeyur.Desai@Sun.COM smb_fqi_t *fqi;
37310504SKeyur.Desai@Sun.COM smb_node_t *tnode;
374*11963SAfshin.Ardakani@Sun.COM smb_node_t *node;
37510504SKeyur.Desai@Sun.COM char *path;
37611337SWilliam.Krier@Sun.COM smb_pathname_t *pn;
3778934SJose.Borrego@Sun.COM
37811447Samw@Sun.COM if (STYPE_ISIPC(sr->tid_tree->t_res_type)) {
3798934SJose.Borrego@Sun.COM smbsr_error(sr, NT_STATUS_ACCESS_DENIED, ERRDOS,
3808934SJose.Borrego@Sun.COM ERROR_ACCESS_DENIED);
3818934SJose.Borrego@Sun.COM return (SDRC_ERROR);
3828934SJose.Borrego@Sun.COM }
3838934SJose.Borrego@Sun.COM
38410504SKeyur.Desai@Sun.COM fqi = &sr->arg.dirop.fqi;
38511337SWilliam.Krier@Sun.COM pn = &fqi->fq_path;
38610504SKeyur.Desai@Sun.COM
38711337SWilliam.Krier@Sun.COM if (pn->pn_path[0] == '\0') {
3888934SJose.Borrego@Sun.COM rc = smbsr_encode_empty_result(sr);
3898934SJose.Borrego@Sun.COM return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
3908934SJose.Borrego@Sun.COM }
3918934SJose.Borrego@Sun.COM
39211337SWilliam.Krier@Sun.COM smb_pathname_init(sr, pn, pn->pn_path);
39311337SWilliam.Krier@Sun.COM if (!smb_pathname_validate(sr, pn) ||
39411337SWilliam.Krier@Sun.COM !smb_validate_dirname(sr, pn)) {
3958934SJose.Borrego@Sun.COM return (SDRC_ERROR);
3968934SJose.Borrego@Sun.COM }
3978934SJose.Borrego@Sun.COM
39811337SWilliam.Krier@Sun.COM path = pn->pn_path;
39910504SKeyur.Desai@Sun.COM tnode = sr->tid_tree->t_snode;
4008934SJose.Borrego@Sun.COM
40110504SKeyur.Desai@Sun.COM rc = smb_pathname_reduce(sr, sr->user_cr, path, tnode, tnode,
40210504SKeyur.Desai@Sun.COM &fqi->fq_dnode, fqi->fq_last_comp);
40310504SKeyur.Desai@Sun.COM if (rc != 0) {
40410504SKeyur.Desai@Sun.COM smbsr_errno(sr, rc);
40510504SKeyur.Desai@Sun.COM return (SDRC_ERROR);
40610504SKeyur.Desai@Sun.COM }
40710504SKeyur.Desai@Sun.COM
40810504SKeyur.Desai@Sun.COM rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
40910504SKeyur.Desai@Sun.COM tnode, fqi->fq_dnode, fqi->fq_last_comp, &fqi->fq_fnode);
41010504SKeyur.Desai@Sun.COM smb_node_release(fqi->fq_dnode);
41110504SKeyur.Desai@Sun.COM if (rc != 0) {
4128934SJose.Borrego@Sun.COM if (rc == ENOENT)
4138934SJose.Borrego@Sun.COM smbsr_error(sr, NT_STATUS_OBJECT_NAME_NOT_FOUND,
4148934SJose.Borrego@Sun.COM ERRDOS, ERROR_PATH_NOT_FOUND);
4158934SJose.Borrego@Sun.COM else
4168934SJose.Borrego@Sun.COM smbsr_errno(sr, rc);
4178934SJose.Borrego@Sun.COM return (SDRC_ERROR);
4188934SJose.Borrego@Sun.COM }
4198934SJose.Borrego@Sun.COM
420*11963SAfshin.Ardakani@Sun.COM node = fqi->fq_fnode;
421*11963SAfshin.Ardakani@Sun.COM if (!smb_node_is_dir(node)) {
422*11963SAfshin.Ardakani@Sun.COM smbsr_error(sr, NT_STATUS_NOT_A_DIRECTORY,
423*11963SAfshin.Ardakani@Sun.COM ERRDOS, ERROR_PATH_NOT_FOUND);
424*11963SAfshin.Ardakani@Sun.COM smb_node_release(node);
4258934SJose.Borrego@Sun.COM return (SDRC_ERROR);
4268934SJose.Borrego@Sun.COM }
4278934SJose.Borrego@Sun.COM
428*11963SAfshin.Ardakani@Sun.COM if ((sr->smb_flg2 & SMB_FLAGS2_DFS) && smb_node_is_dfslink(node)) {
429*11963SAfshin.Ardakani@Sun.COM smbsr_error(sr, NT_STATUS_PATH_NOT_COVERED, ERRSRV, ERRbadpath);
430*11963SAfshin.Ardakani@Sun.COM smb_node_release(node);
43110504SKeyur.Desai@Sun.COM return (SDRC_ERROR);
43210504SKeyur.Desai@Sun.COM }
4338934SJose.Borrego@Sun.COM
434*11963SAfshin.Ardakani@Sun.COM rc = smb_fsop_access(sr, sr->user_cr, node, FILE_TRAVERSE);
43510504SKeyur.Desai@Sun.COM
436*11963SAfshin.Ardakani@Sun.COM smb_node_release(node);
4378934SJose.Borrego@Sun.COM
4388934SJose.Borrego@Sun.COM if (rc != 0) {
4398934SJose.Borrego@Sun.COM smbsr_error(sr, NT_STATUS_ACCESS_DENIED,
4408934SJose.Borrego@Sun.COM ERRDOS, ERROR_ACCESS_DENIED);
4418934SJose.Borrego@Sun.COM return (SDRC_ERROR);
4428934SJose.Borrego@Sun.COM }
4438934SJose.Borrego@Sun.COM
4448934SJose.Borrego@Sun.COM rc = smbsr_encode_empty_result(sr);
4458934SJose.Borrego@Sun.COM return ((rc == 0) ? SDRC_SUCCESS : SDRC_ERROR);
4468934SJose.Borrego@Sun.COM }
447