xref: /illumos-gate/usr/src/uts/common/fs/smbsrv/smb2_close.c (revision b3403853e80914bd0aade9b5b605da4878078173)
1 /*
2  * This file and its contents are supplied under the terms of the
3  * Common Development and Distribution License ("CDDL"), version 1.0.
4  * You may only use this file in accordance with the terms of version
5  * 1.0 of the CDDL.
6  *
7  * A full copy of the text of the CDDL should have accompanied this
8  * source.  A copy of the CDDL is also available via the Internet at
9  * http://www.illumos.org/license/CDDL.
10  */
11 
12 /*
13  * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
14  */
15 
16 /*
17  * Dispatch function for SMB2_CLOSE
18  */
19 
20 #include <smbsrv/smb2_kproto.h>
21 
22 smb_sdrc_t
23 smb2_close(smb_request_t *sr)
24 {
25 	smb_attr_t attr;
26 	smb_ofile_t *of;
27 	uint16_t StructSize;
28 	uint16_t Flags;
29 	uint32_t reserved;
30 	smb2fid_t smb2fid;
31 	uint32_t status;
32 	int rc = 0;
33 
34 	/*
35 	 * SMB2 Close request
36 	 */
37 	rc = smb_mbc_decodef(
38 	    &sr->smb_data, "wwlqq",
39 	    &StructSize,		/* w */
40 	    &Flags,			/* w */
41 	    &reserved,			/* l */
42 	    &smb2fid.persistent,	/* q */
43 	    &smb2fid.temporal);		/* q */
44 	if (rc)
45 		return (SDRC_ERROR);
46 	if (StructSize != 24)
47 		return (SDRC_ERROR);
48 
49 	/*
50 	 * Want FID lookup before the start probe.
51 	 */
52 	status = smb2sr_lookup_fid(sr, &smb2fid);
53 	of = sr->fid_ofile;
54 
55 	DTRACE_SMB2_START(op__Close, smb_request_t *, sr);
56 
57 	if (status)
58 		goto errout; /* Bad FID */
59 
60 	bzero(&attr, sizeof (attr));
61 	if (Flags & SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB) {
62 		attr.sa_mask = SMB_AT_ALL;
63 		status = smb2_ofile_getattr(sr, of, &attr);
64 		if (status) {
65 			/*
66 			 * We could not stat the open file.
67 			 * Let's not fail the close call,
68 			 * but just turn off the flag.
69 			 */
70 			Flags = 0;
71 		}
72 	}
73 
74 	if (of->dh_persist)
75 		smb2_dh_setdoc_persistent(of);
76 	smb_ofile_close(of, 0);
77 
78 errout:
79 	sr->smb2_status = status;
80 	DTRACE_SMB2_DONE(op__Close, smb_request_t *, sr);
81 
82 	if (status) {
83 		smb2sr_put_error(sr, status);
84 		return (SDRC_SUCCESS);
85 	}
86 
87 	/*
88 	 * SMB2 Close reply
89 	 */
90 	(void) smb_mbc_encodef(
91 	    &sr->reply,
92 	    "wwlTTTTqql",
93 	    60,	/* StructSize */	/* w */
94 	    Flags,			/* w */
95 	    0, /* reserved */		/* l */
96 	    &attr.sa_crtime,		/* T */
97 	    &attr.sa_vattr.va_atime,	/* T */
98 	    &attr.sa_vattr.va_mtime,	/* T */
99 	    &attr.sa_vattr.va_ctime,	/* T */
100 	    attr.sa_allocsz,		/* q */
101 	    attr.sa_vattr.va_size,	/* q */
102 	    attr.sa_dosattr);		/* l */
103 
104 	return (SDRC_SUCCESS);
105 }
106