1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org>
4 * Copyright (C) 2018 Samsung Electronics Co., Ltd.
7 #include <linux/inetdevice.h>
8 #include <net/addrconf.h>
9 #include <linux/syscalls.h>
10 #include <linux/namei.h>
11 #include <linux/statfs.h>
12 #include <linux/ethtool.h>
13 #include <linux/falloc.h>
14 #include <linux/mount.h>
15 #include <linux/filelock.h>
24 #include "connection.h"
25 #include "transport_ipc.h"
26 #include "transport_rdma.h"
28 #include "vfs_cache.h"
32 #include "smb_common.h"
33 #include "../common/smb2status.h"
34 #include "ksmbd_work.h"
35 #include "mgmt/user_config.h"
36 #include "mgmt/share_config.h"
37 #include "mgmt/tree_connect.h"
38 #include "mgmt/user_session.h"
39 #include "mgmt/ksmbd_ida.h"
42 static void __wbuf(struct ksmbd_work
*work
, void **req
, void **rsp
)
44 if (work
->next_smb2_rcv_hdr_off
) {
45 *req
= ksmbd_req_buf_next(work
);
46 *rsp
= ksmbd_resp_buf_next(work
);
48 *req
= smb2_get_msg(work
->request_buf
);
49 *rsp
= smb2_get_msg(work
->response_buf
);
53 #define WORK_BUFFERS(w, rq, rs) __wbuf((w), (void **)&(rq), (void **)&(rs))
56 * check_session_id() - check for valid session id in smb header
57 * @conn: connection instance
58 * @id: session id from smb header
60 * Return: 1 if valid session id, otherwise 0
62 static inline bool check_session_id(struct ksmbd_conn
*conn
, u64 id
)
64 struct ksmbd_session
*sess
;
66 if (id
== 0 || id
== -1)
69 sess
= ksmbd_session_lookup_all(conn
, id
);
72 pr_err("Invalid user session id: %llu\n", id
);
76 struct channel
*lookup_chann_list(struct ksmbd_session
*sess
, struct ksmbd_conn
*conn
)
78 return xa_load(&sess
->ksmbd_chann_list
, (long)conn
);
82 * smb2_get_ksmbd_tcon() - get tree connection information using a tree id.
85 * Return: 0 if there is a tree connection matched or these are
86 * skipable commands, otherwise error
88 int smb2_get_ksmbd_tcon(struct ksmbd_work
*work
)
90 struct smb2_hdr
*req_hdr
= ksmbd_req_buf_next(work
);
91 unsigned int cmd
= le16_to_cpu(req_hdr
->Command
);
94 if (cmd
== SMB2_TREE_CONNECT_HE
||
95 cmd
== SMB2_CANCEL_HE
||
96 cmd
== SMB2_LOGOFF_HE
) {
97 ksmbd_debug(SMB
, "skip to check tree connect request\n");
101 if (xa_empty(&work
->sess
->tree_conns
)) {
102 ksmbd_debug(SMB
, "NO tree connected\n");
106 tree_id
= le32_to_cpu(req_hdr
->Id
.SyncId
.TreeId
);
109 * If request is not the first in Compound request,
110 * Just validate tree id in header with work->tcon->id.
112 if (work
->next_smb2_rcv_hdr_off
) {
114 pr_err("The first operation in the compound does not have tcon\n");
117 if (tree_id
!= UINT_MAX
&& work
->tcon
->id
!= tree_id
) {
118 pr_err("tree id(%u) is different with id(%u) in first operation\n",
119 tree_id
, work
->tcon
->id
);
125 work
->tcon
= ksmbd_tree_conn_lookup(work
->sess
, tree_id
);
127 pr_err("Invalid tid %d\n", tree_id
);
135 * smb2_set_err_rsp() - set error response code on smb response
136 * @work: smb work containing response buffer
138 void smb2_set_err_rsp(struct ksmbd_work
*work
)
140 struct smb2_err_rsp
*err_rsp
;
142 if (work
->next_smb2_rcv_hdr_off
)
143 err_rsp
= ksmbd_resp_buf_next(work
);
145 err_rsp
= smb2_get_msg(work
->response_buf
);
147 if (err_rsp
->hdr
.Status
!= STATUS_STOPPED_ON_SYMLINK
) {
150 err_rsp
->StructureSize
= SMB2_ERROR_STRUCTURE_SIZE2_LE
;
151 err_rsp
->ErrorContextCount
= 0;
152 err_rsp
->Reserved
= 0;
153 err_rsp
->ByteCount
= 0;
154 err_rsp
->ErrorData
[0] = 0;
155 err
= ksmbd_iov_pin_rsp(work
, (void *)err_rsp
,
156 __SMB2_HEADER_STRUCTURE_SIZE
+
157 SMB2_ERROR_STRUCTURE_SIZE2
);
159 work
->send_no_response
= 1;
164 * is_smb2_neg_cmd() - is it smb2 negotiation command
165 * @work: smb work containing smb header
167 * Return: true if smb2 negotiation command, otherwise false
169 bool is_smb2_neg_cmd(struct ksmbd_work
*work
)
171 struct smb2_hdr
*hdr
= smb2_get_msg(work
->request_buf
);
173 /* is it SMB2 header ? */
174 if (hdr
->ProtocolId
!= SMB2_PROTO_NUMBER
)
177 /* make sure it is request not response message */
178 if (hdr
->Flags
& SMB2_FLAGS_SERVER_TO_REDIR
)
181 if (hdr
->Command
!= SMB2_NEGOTIATE
)
188 * is_smb2_rsp() - is it smb2 response
189 * @work: smb work containing smb response buffer
191 * Return: true if smb2 response, otherwise false
193 bool is_smb2_rsp(struct ksmbd_work
*work
)
195 struct smb2_hdr
*hdr
= smb2_get_msg(work
->response_buf
);
197 /* is it SMB2 header ? */
198 if (hdr
->ProtocolId
!= SMB2_PROTO_NUMBER
)
201 /* make sure it is response not request message */
202 if (!(hdr
->Flags
& SMB2_FLAGS_SERVER_TO_REDIR
))
209 * get_smb2_cmd_val() - get smb command code from smb header
210 * @work: smb work containing smb request buffer
212 * Return: smb2 request command value
214 u16
get_smb2_cmd_val(struct ksmbd_work
*work
)
216 struct smb2_hdr
*rcv_hdr
;
218 if (work
->next_smb2_rcv_hdr_off
)
219 rcv_hdr
= ksmbd_req_buf_next(work
);
221 rcv_hdr
= smb2_get_msg(work
->request_buf
);
222 return le16_to_cpu(rcv_hdr
->Command
);
226 * set_smb2_rsp_status() - set error response code on smb2 header
227 * @work: smb work containing response buffer
228 * @err: error response code
230 void set_smb2_rsp_status(struct ksmbd_work
*work
, __le32 err
)
232 struct smb2_hdr
*rsp_hdr
;
234 rsp_hdr
= smb2_get_msg(work
->response_buf
);
235 rsp_hdr
->Status
= err
;
239 work
->next_smb2_rcv_hdr_off
= 0;
240 smb2_set_err_rsp(work
);
244 * init_smb2_neg_rsp() - initialize smb2 response for negotiate command
245 * @work: smb work containing smb request buffer
247 * smb2 negotiate response is sent in reply of smb1 negotiate command for
248 * dialect auto-negotiation.
250 int init_smb2_neg_rsp(struct ksmbd_work
*work
)
252 struct smb2_hdr
*rsp_hdr
;
253 struct smb2_negotiate_rsp
*rsp
;
254 struct ksmbd_conn
*conn
= work
->conn
;
257 rsp_hdr
= smb2_get_msg(work
->response_buf
);
258 memset(rsp_hdr
, 0, sizeof(struct smb2_hdr
) + 2);
259 rsp_hdr
->ProtocolId
= SMB2_PROTO_NUMBER
;
260 rsp_hdr
->StructureSize
= SMB2_HEADER_STRUCTURE_SIZE
;
261 rsp_hdr
->CreditRequest
= cpu_to_le16(2);
262 rsp_hdr
->Command
= SMB2_NEGOTIATE
;
263 rsp_hdr
->Flags
= (SMB2_FLAGS_SERVER_TO_REDIR
);
264 rsp_hdr
->NextCommand
= 0;
265 rsp_hdr
->MessageId
= 0;
266 rsp_hdr
->Id
.SyncId
.ProcessId
= 0;
267 rsp_hdr
->Id
.SyncId
.TreeId
= 0;
268 rsp_hdr
->SessionId
= 0;
269 memset(rsp_hdr
->Signature
, 0, 16);
271 rsp
= smb2_get_msg(work
->response_buf
);
273 WARN_ON(ksmbd_conn_good(conn
));
275 rsp
->StructureSize
= cpu_to_le16(65);
276 ksmbd_debug(SMB
, "conn->dialect 0x%x\n", conn
->dialect
);
277 rsp
->DialectRevision
= cpu_to_le16(conn
->dialect
);
278 /* Not setting conn guid rsp->ServerGUID, as it
279 * not used by client for identifying connection
281 rsp
->Capabilities
= cpu_to_le32(conn
->vals
->capabilities
);
282 /* Default Max Message Size till SMB2.0, 64K*/
283 rsp
->MaxTransactSize
= cpu_to_le32(conn
->vals
->max_trans_size
);
284 rsp
->MaxReadSize
= cpu_to_le32(conn
->vals
->max_read_size
);
285 rsp
->MaxWriteSize
= cpu_to_le32(conn
->vals
->max_write_size
);
287 rsp
->SystemTime
= cpu_to_le64(ksmbd_systime());
288 rsp
->ServerStartTime
= 0;
290 rsp
->SecurityBufferOffset
= cpu_to_le16(128);
291 rsp
->SecurityBufferLength
= cpu_to_le16(AUTH_GSS_LENGTH
);
292 ksmbd_copy_gss_neg_header((char *)(&rsp
->hdr
) +
293 le16_to_cpu(rsp
->SecurityBufferOffset
));
294 rsp
->SecurityMode
= SMB2_NEGOTIATE_SIGNING_ENABLED_LE
;
295 if (server_conf
.signing
== KSMBD_CONFIG_OPT_MANDATORY
)
296 rsp
->SecurityMode
|= SMB2_NEGOTIATE_SIGNING_REQUIRED_LE
;
297 err
= ksmbd_iov_pin_rsp(work
, rsp
,
298 sizeof(struct smb2_negotiate_rsp
) + AUTH_GSS_LENGTH
);
301 conn
->use_spnego
= true;
303 ksmbd_conn_set_need_negotiate(conn
);
308 * smb2_set_rsp_credits() - set number of credits in response buffer
309 * @work: smb work containing smb response buffer
311 int smb2_set_rsp_credits(struct ksmbd_work
*work
)
313 struct smb2_hdr
*req_hdr
= ksmbd_req_buf_next(work
);
314 struct smb2_hdr
*hdr
= ksmbd_resp_buf_next(work
);
315 struct ksmbd_conn
*conn
= work
->conn
;
316 unsigned short credits_requested
, aux_max
;
317 unsigned short credit_charge
, credits_granted
= 0;
319 if (work
->send_no_response
)
322 hdr
->CreditCharge
= req_hdr
->CreditCharge
;
324 if (conn
->total_credits
> conn
->vals
->max_credits
) {
325 hdr
->CreditRequest
= 0;
326 pr_err("Total credits overflow: %d\n", conn
->total_credits
);
330 credit_charge
= max_t(unsigned short,
331 le16_to_cpu(req_hdr
->CreditCharge
), 1);
332 if (credit_charge
> conn
->total_credits
) {
333 ksmbd_debug(SMB
, "Insufficient credits granted, given: %u, granted: %u\n",
334 credit_charge
, conn
->total_credits
);
338 conn
->total_credits
-= credit_charge
;
339 conn
->outstanding_credits
-= credit_charge
;
340 credits_requested
= max_t(unsigned short,
341 le16_to_cpu(req_hdr
->CreditRequest
), 1);
343 /* according to smb2.credits smbtorture, Windows server
344 * 2016 or later grant up to 8192 credits at once.
346 * TODO: Need to adjuct CreditRequest value according to
349 if (hdr
->Command
== SMB2_NEGOTIATE
)
352 aux_max
= conn
->vals
->max_credits
- conn
->total_credits
;
353 credits_granted
= min_t(unsigned short, credits_requested
, aux_max
);
355 conn
->total_credits
+= credits_granted
;
356 work
->credits_granted
+= credits_granted
;
358 if (!req_hdr
->NextCommand
) {
359 /* Update CreditRequest in last request */
360 hdr
->CreditRequest
= cpu_to_le16(work
->credits_granted
);
363 "credits: requested[%d] granted[%d] total_granted[%d]\n",
364 credits_requested
, credits_granted
,
365 conn
->total_credits
);
370 * init_chained_smb2_rsp() - initialize smb2 chained response
371 * @work: smb work containing smb response buffer
373 static void init_chained_smb2_rsp(struct ksmbd_work
*work
)
375 struct smb2_hdr
*req
= ksmbd_req_buf_next(work
);
376 struct smb2_hdr
*rsp
= ksmbd_resp_buf_next(work
);
377 struct smb2_hdr
*rsp_hdr
;
378 struct smb2_hdr
*rcv_hdr
;
379 int next_hdr_offset
= 0;
382 /* Len of this response = updated RFC len - offset of previous cmd
383 * in the compound rsp
386 /* Storing the current local FID which may be needed by subsequent
387 * command in the compound request
389 if (req
->Command
== SMB2_CREATE
&& rsp
->Status
== STATUS_SUCCESS
) {
390 work
->compound_fid
= ((struct smb2_create_rsp
*)rsp
)->VolatileFileId
;
391 work
->compound_pfid
= ((struct smb2_create_rsp
*)rsp
)->PersistentFileId
;
392 work
->compound_sid
= le64_to_cpu(rsp
->SessionId
);
395 len
= get_rfc1002_len(work
->response_buf
) - work
->next_smb2_rsp_hdr_off
;
396 next_hdr_offset
= le32_to_cpu(req
->NextCommand
);
398 new_len
= ALIGN(len
, 8);
399 work
->iov
[work
->iov_idx
].iov_len
+= (new_len
- len
);
400 inc_rfc1001_len(work
->response_buf
, new_len
- len
);
401 rsp
->NextCommand
= cpu_to_le32(new_len
);
403 work
->next_smb2_rcv_hdr_off
+= next_hdr_offset
;
404 work
->curr_smb2_rsp_hdr_off
= work
->next_smb2_rsp_hdr_off
;
405 work
->next_smb2_rsp_hdr_off
+= new_len
;
407 "Compound req new_len = %d rcv off = %d rsp off = %d\n",
408 new_len
, work
->next_smb2_rcv_hdr_off
,
409 work
->next_smb2_rsp_hdr_off
);
411 rsp_hdr
= ksmbd_resp_buf_next(work
);
412 rcv_hdr
= ksmbd_req_buf_next(work
);
414 if (!(rcv_hdr
->Flags
& SMB2_FLAGS_RELATED_OPERATIONS
)) {
415 ksmbd_debug(SMB
, "related flag should be set\n");
416 work
->compound_fid
= KSMBD_NO_FID
;
417 work
->compound_pfid
= KSMBD_NO_FID
;
419 memset((char *)rsp_hdr
, 0, sizeof(struct smb2_hdr
) + 2);
420 rsp_hdr
->ProtocolId
= SMB2_PROTO_NUMBER
;
421 rsp_hdr
->StructureSize
= SMB2_HEADER_STRUCTURE_SIZE
;
422 rsp_hdr
->Command
= rcv_hdr
->Command
;
425 * Message is response. We don't grant oplock yet.
427 rsp_hdr
->Flags
= (SMB2_FLAGS_SERVER_TO_REDIR
|
428 SMB2_FLAGS_RELATED_OPERATIONS
);
429 rsp_hdr
->NextCommand
= 0;
430 rsp_hdr
->MessageId
= rcv_hdr
->MessageId
;
431 rsp_hdr
->Id
.SyncId
.ProcessId
= rcv_hdr
->Id
.SyncId
.ProcessId
;
432 rsp_hdr
->Id
.SyncId
.TreeId
= rcv_hdr
->Id
.SyncId
.TreeId
;
433 rsp_hdr
->SessionId
= rcv_hdr
->SessionId
;
434 memcpy(rsp_hdr
->Signature
, rcv_hdr
->Signature
, 16);
438 * is_chained_smb2_message() - check for chained command
439 * @work: smb work containing smb request buffer
441 * Return: true if chained request, otherwise false
443 bool is_chained_smb2_message(struct ksmbd_work
*work
)
445 struct smb2_hdr
*hdr
= smb2_get_msg(work
->request_buf
);
446 unsigned int len
, next_cmd
;
448 if (hdr
->ProtocolId
!= SMB2_PROTO_NUMBER
)
451 hdr
= ksmbd_req_buf_next(work
);
452 next_cmd
= le32_to_cpu(hdr
->NextCommand
);
454 if ((u64
)work
->next_smb2_rcv_hdr_off
+ next_cmd
+
455 __SMB2_HEADER_STRUCTURE_SIZE
>
456 get_rfc1002_len(work
->request_buf
)) {
457 pr_err("next command(%u) offset exceeds smb msg size\n",
462 if ((u64
)get_rfc1002_len(work
->response_buf
) + MAX_CIFS_SMALL_BUFFER_SIZE
>
464 pr_err("next response offset exceeds response buffer size\n");
468 ksmbd_debug(SMB
, "got SMB2 chained command\n");
469 init_chained_smb2_rsp(work
);
471 } else if (work
->next_smb2_rcv_hdr_off
) {
473 * This is last request in chained command,
474 * align response to 8 byte
476 len
= ALIGN(get_rfc1002_len(work
->response_buf
), 8);
477 len
= len
- get_rfc1002_len(work
->response_buf
);
479 ksmbd_debug(SMB
, "padding len %u\n", len
);
480 work
->iov
[work
->iov_idx
].iov_len
+= len
;
481 inc_rfc1001_len(work
->response_buf
, len
);
483 work
->curr_smb2_rsp_hdr_off
= work
->next_smb2_rsp_hdr_off
;
489 * init_smb2_rsp_hdr() - initialize smb2 response
490 * @work: smb work containing smb request buffer
494 int init_smb2_rsp_hdr(struct ksmbd_work
*work
)
496 struct smb2_hdr
*rsp_hdr
= smb2_get_msg(work
->response_buf
);
497 struct smb2_hdr
*rcv_hdr
= smb2_get_msg(work
->request_buf
);
499 memset(rsp_hdr
, 0, sizeof(struct smb2_hdr
) + 2);
500 rsp_hdr
->ProtocolId
= rcv_hdr
->ProtocolId
;
501 rsp_hdr
->StructureSize
= SMB2_HEADER_STRUCTURE_SIZE
;
502 rsp_hdr
->Command
= rcv_hdr
->Command
;
505 * Message is response. We don't grant oplock yet.
507 rsp_hdr
->Flags
= (SMB2_FLAGS_SERVER_TO_REDIR
);
508 rsp_hdr
->NextCommand
= 0;
509 rsp_hdr
->MessageId
= rcv_hdr
->MessageId
;
510 rsp_hdr
->Id
.SyncId
.ProcessId
= rcv_hdr
->Id
.SyncId
.ProcessId
;
511 rsp_hdr
->Id
.SyncId
.TreeId
= rcv_hdr
->Id
.SyncId
.TreeId
;
512 rsp_hdr
->SessionId
= rcv_hdr
->SessionId
;
513 memcpy(rsp_hdr
->Signature
, rcv_hdr
->Signature
, 16);
519 * smb2_allocate_rsp_buf() - allocate smb2 response buffer
520 * @work: smb work containing smb request buffer
522 * Return: 0 on success, otherwise error
524 int smb2_allocate_rsp_buf(struct ksmbd_work
*work
)
526 struct smb2_hdr
*hdr
= smb2_get_msg(work
->request_buf
);
527 size_t small_sz
= MAX_CIFS_SMALL_BUFFER_SIZE
;
528 size_t large_sz
= small_sz
+ work
->conn
->vals
->max_trans_size
;
529 size_t sz
= small_sz
;
530 int cmd
= le16_to_cpu(hdr
->Command
);
532 if (cmd
== SMB2_IOCTL_HE
|| cmd
== SMB2_QUERY_DIRECTORY_HE
)
535 if (cmd
== SMB2_QUERY_INFO_HE
) {
536 struct smb2_query_info_req
*req
;
538 if (get_rfc1002_len(work
->request_buf
) <
539 offsetof(struct smb2_query_info_req
, OutputBufferLength
))
542 req
= smb2_get_msg(work
->request_buf
);
543 if ((req
->InfoType
== SMB2_O_INFO_FILE
&&
544 (req
->FileInfoClass
== FILE_FULL_EA_INFORMATION
||
545 req
->FileInfoClass
== FILE_ALL_INFORMATION
)) ||
546 req
->InfoType
== SMB2_O_INFO_SECURITY
)
550 /* allocate large response buf for chained commands */
551 if (le32_to_cpu(hdr
->NextCommand
) > 0)
554 work
->response_buf
= kvzalloc(sz
, GFP_KERNEL
);
555 if (!work
->response_buf
)
558 work
->response_sz
= sz
;
563 * smb2_check_user_session() - check for valid session for a user
564 * @work: smb work containing smb request buffer
566 * Return: 0 on success, otherwise error
568 int smb2_check_user_session(struct ksmbd_work
*work
)
570 struct smb2_hdr
*req_hdr
= ksmbd_req_buf_next(work
);
571 struct ksmbd_conn
*conn
= work
->conn
;
572 unsigned int cmd
= le16_to_cpu(req_hdr
->Command
);
573 unsigned long long sess_id
;
576 * SMB2_ECHO, SMB2_NEGOTIATE, SMB2_SESSION_SETUP command do not
577 * require a session id, so no need to validate user session's for
580 if (cmd
== SMB2_ECHO_HE
|| cmd
== SMB2_NEGOTIATE_HE
||
581 cmd
== SMB2_SESSION_SETUP_HE
)
584 if (!ksmbd_conn_good(conn
))
587 sess_id
= le64_to_cpu(req_hdr
->SessionId
);
590 * If request is not the first in Compound request,
591 * Just validate session id in header with work->sess->id.
593 if (work
->next_smb2_rcv_hdr_off
) {
595 pr_err("The first operation in the compound does not have sess\n");
598 if (sess_id
!= ULLONG_MAX
&& work
->sess
->id
!= sess_id
) {
599 pr_err("session id(%llu) is different with the first operation(%lld)\n",
600 sess_id
, work
->sess
->id
);
606 /* Check for validity of user session */
607 work
->sess
= ksmbd_session_lookup_all(conn
, sess_id
);
610 ksmbd_debug(SMB
, "Invalid user session, Uid %llu\n", sess_id
);
615 * smb2_get_name() - get filename string from on the wire smb format
616 * @src: source buffer
617 * @maxlen: maxlen of source string
618 * @local_nls: nls_table pointer
620 * Return: matching converted filename on success, otherwise error ptr
623 smb2_get_name(const char *src
, const int maxlen
, struct nls_table
*local_nls
)
627 name
= smb_strndup_from_utf16(src
, maxlen
, 1, local_nls
);
629 pr_err("failed to get name %ld\n", PTR_ERR(name
));
634 pr_err("not allow directory name included leading slash\n");
636 return ERR_PTR(-EINVAL
);
639 ksmbd_conv_path_to_unix(name
);
640 ksmbd_strip_last_slash(name
);
644 int setup_async_work(struct ksmbd_work
*work
, void (*fn
)(void **), void **arg
)
646 struct ksmbd_conn
*conn
= work
->conn
;
649 id
= ksmbd_acquire_async_msg_id(&conn
->async_ida
);
651 pr_err("Failed to alloc async message id\n");
654 work
->asynchronous
= true;
658 "Send interim Response to inform async request id : %d\n",
661 work
->cancel_fn
= fn
;
662 work
->cancel_argv
= arg
;
664 if (list_empty(&work
->async_request_entry
)) {
665 spin_lock(&conn
->request_lock
);
666 list_add_tail(&work
->async_request_entry
, &conn
->async_requests
);
667 spin_unlock(&conn
->request_lock
);
673 void release_async_work(struct ksmbd_work
*work
)
675 struct ksmbd_conn
*conn
= work
->conn
;
677 spin_lock(&conn
->request_lock
);
678 list_del_init(&work
->async_request_entry
);
679 spin_unlock(&conn
->request_lock
);
681 work
->asynchronous
= 0;
682 work
->cancel_fn
= NULL
;
683 kfree(work
->cancel_argv
);
684 work
->cancel_argv
= NULL
;
685 if (work
->async_id
) {
686 ksmbd_release_id(&conn
->async_ida
, work
->async_id
);
691 void smb2_send_interim_resp(struct ksmbd_work
*work
, __le32 status
)
693 struct smb2_hdr
*rsp_hdr
;
694 struct ksmbd_work
*in_work
= ksmbd_alloc_work_struct();
696 if (allocate_interim_rsp_buf(in_work
)) {
697 pr_err("smb_allocate_rsp_buf failed!\n");
698 ksmbd_free_work_struct(in_work
);
702 in_work
->conn
= work
->conn
;
703 memcpy(smb2_get_msg(in_work
->response_buf
), ksmbd_resp_buf_next(work
),
704 __SMB2_HEADER_STRUCTURE_SIZE
);
706 rsp_hdr
= smb2_get_msg(in_work
->response_buf
);
707 rsp_hdr
->Flags
|= SMB2_FLAGS_ASYNC_COMMAND
;
708 rsp_hdr
->Id
.AsyncId
= cpu_to_le64(work
->async_id
);
709 smb2_set_err_rsp(in_work
);
710 rsp_hdr
->Status
= status
;
712 ksmbd_conn_write(in_work
);
713 ksmbd_free_work_struct(in_work
);
716 static __le32
smb2_get_reparse_tag_special_file(umode_t mode
)
718 if (S_ISDIR(mode
) || S_ISREG(mode
))
722 return IO_REPARSE_TAG_LX_SYMLINK_LE
;
723 else if (S_ISFIFO(mode
))
724 return IO_REPARSE_TAG_LX_FIFO_LE
;
725 else if (S_ISSOCK(mode
))
726 return IO_REPARSE_TAG_AF_UNIX_LE
;
727 else if (S_ISCHR(mode
))
728 return IO_REPARSE_TAG_LX_CHR_LE
;
729 else if (S_ISBLK(mode
))
730 return IO_REPARSE_TAG_LX_BLK_LE
;
736 * smb2_get_dos_mode() - get file mode in dos format from unix mode
737 * @stat: kstat containing file mode
738 * @attribute: attribute flags
740 * Return: converted dos mode
742 static int smb2_get_dos_mode(struct kstat
*stat
, int attribute
)
746 if (S_ISDIR(stat
->mode
)) {
747 attr
= FILE_ATTRIBUTE_DIRECTORY
|
748 (attribute
& (FILE_ATTRIBUTE_HIDDEN
| FILE_ATTRIBUTE_SYSTEM
));
750 attr
= (attribute
& 0x00005137) | FILE_ATTRIBUTE_ARCHIVE
;
751 attr
&= ~(FILE_ATTRIBUTE_DIRECTORY
);
752 if (S_ISREG(stat
->mode
) && (server_conf
.share_fake_fscaps
&
753 FILE_SUPPORTS_SPARSE_FILES
))
754 attr
|= FILE_ATTRIBUTE_SPARSE_FILE
;
756 if (smb2_get_reparse_tag_special_file(stat
->mode
))
757 attr
|= FILE_ATTRIBUTE_REPARSE_POINT
;
763 static void build_preauth_ctxt(struct smb2_preauth_neg_context
*pneg_ctxt
,
766 pneg_ctxt
->ContextType
= SMB2_PREAUTH_INTEGRITY_CAPABILITIES
;
767 pneg_ctxt
->DataLength
= cpu_to_le16(38);
768 pneg_ctxt
->HashAlgorithmCount
= cpu_to_le16(1);
769 pneg_ctxt
->Reserved
= cpu_to_le32(0);
770 pneg_ctxt
->SaltLength
= cpu_to_le16(SMB311_SALT_SIZE
);
771 get_random_bytes(pneg_ctxt
->Salt
, SMB311_SALT_SIZE
);
772 pneg_ctxt
->HashAlgorithms
= hash_id
;
775 static void build_encrypt_ctxt(struct smb2_encryption_neg_context
*pneg_ctxt
,
778 pneg_ctxt
->ContextType
= SMB2_ENCRYPTION_CAPABILITIES
;
779 pneg_ctxt
->DataLength
= cpu_to_le16(4);
780 pneg_ctxt
->Reserved
= cpu_to_le32(0);
781 pneg_ctxt
->CipherCount
= cpu_to_le16(1);
782 pneg_ctxt
->Ciphers
[0] = cipher_type
;
785 static void build_sign_cap_ctxt(struct smb2_signing_capabilities
*pneg_ctxt
,
788 pneg_ctxt
->ContextType
= SMB2_SIGNING_CAPABILITIES
;
789 pneg_ctxt
->DataLength
=
790 cpu_to_le16((sizeof(struct smb2_signing_capabilities
) + 2)
791 - sizeof(struct smb2_neg_context
));
792 pneg_ctxt
->Reserved
= cpu_to_le32(0);
793 pneg_ctxt
->SigningAlgorithmCount
= cpu_to_le16(1);
794 pneg_ctxt
->SigningAlgorithms
[0] = sign_algo
;
797 static void build_posix_ctxt(struct smb2_posix_neg_context
*pneg_ctxt
)
799 pneg_ctxt
->ContextType
= SMB2_POSIX_EXTENSIONS_AVAILABLE
;
800 pneg_ctxt
->DataLength
= cpu_to_le16(POSIX_CTXT_DATA_LEN
);
801 /* SMB2_CREATE_TAG_POSIX is "0x93AD25509CB411E7B42383DE968BCD7C" */
802 pneg_ctxt
->Name
[0] = 0x93;
803 pneg_ctxt
->Name
[1] = 0xAD;
804 pneg_ctxt
->Name
[2] = 0x25;
805 pneg_ctxt
->Name
[3] = 0x50;
806 pneg_ctxt
->Name
[4] = 0x9C;
807 pneg_ctxt
->Name
[5] = 0xB4;
808 pneg_ctxt
->Name
[6] = 0x11;
809 pneg_ctxt
->Name
[7] = 0xE7;
810 pneg_ctxt
->Name
[8] = 0xB4;
811 pneg_ctxt
->Name
[9] = 0x23;
812 pneg_ctxt
->Name
[10] = 0x83;
813 pneg_ctxt
->Name
[11] = 0xDE;
814 pneg_ctxt
->Name
[12] = 0x96;
815 pneg_ctxt
->Name
[13] = 0x8B;
816 pneg_ctxt
->Name
[14] = 0xCD;
817 pneg_ctxt
->Name
[15] = 0x7C;
820 static unsigned int assemble_neg_contexts(struct ksmbd_conn
*conn
,
821 struct smb2_negotiate_rsp
*rsp
)
823 char * const pneg_ctxt
= (char *)rsp
+
824 le32_to_cpu(rsp
->NegotiateContextOffset
);
825 int neg_ctxt_cnt
= 1;
829 "assemble SMB2_PREAUTH_INTEGRITY_CAPABILITIES context\n");
830 build_preauth_ctxt((struct smb2_preauth_neg_context
*)pneg_ctxt
,
831 conn
->preauth_info
->Preauth_HashId
);
832 ctxt_size
= sizeof(struct smb2_preauth_neg_context
);
834 if (conn
->cipher_type
) {
835 /* Round to 8 byte boundary */
836 ctxt_size
= round_up(ctxt_size
, 8);
838 "assemble SMB2_ENCRYPTION_CAPABILITIES context\n");
839 build_encrypt_ctxt((struct smb2_encryption_neg_context
*)
840 (pneg_ctxt
+ ctxt_size
),
843 ctxt_size
+= sizeof(struct smb2_encryption_neg_context
) + 2;
846 /* compression context not yet supported */
847 WARN_ON(conn
->compress_algorithm
!= SMB3_COMPRESS_NONE
);
849 if (conn
->posix_ext_supported
) {
850 ctxt_size
= round_up(ctxt_size
, 8);
852 "assemble SMB2_POSIX_EXTENSIONS_AVAILABLE context\n");
853 build_posix_ctxt((struct smb2_posix_neg_context
*)
854 (pneg_ctxt
+ ctxt_size
));
856 ctxt_size
+= sizeof(struct smb2_posix_neg_context
);
859 if (conn
->signing_negotiated
) {
860 ctxt_size
= round_up(ctxt_size
, 8);
862 "assemble SMB2_SIGNING_CAPABILITIES context\n");
863 build_sign_cap_ctxt((struct smb2_signing_capabilities
*)
864 (pneg_ctxt
+ ctxt_size
),
865 conn
->signing_algorithm
);
867 ctxt_size
+= sizeof(struct smb2_signing_capabilities
) + 2;
870 rsp
->NegotiateContextCount
= cpu_to_le16(neg_ctxt_cnt
);
871 return ctxt_size
+ AUTH_GSS_PADDING
;
874 static __le32
decode_preauth_ctxt(struct ksmbd_conn
*conn
,
875 struct smb2_preauth_neg_context
*pneg_ctxt
,
879 * sizeof(smb2_preauth_neg_context) assumes SMB311_SALT_SIZE Salt,
880 * which may not be present. Only check for used HashAlgorithms[1].
883 sizeof(struct smb2_neg_context
) + MIN_PREAUTH_CTXT_DATA_LEN
)
884 return STATUS_INVALID_PARAMETER
;
886 if (pneg_ctxt
->HashAlgorithms
!= SMB2_PREAUTH_INTEGRITY_SHA512
)
887 return STATUS_NO_PREAUTH_INTEGRITY_HASH_OVERLAP
;
889 conn
->preauth_info
->Preauth_HashId
= SMB2_PREAUTH_INTEGRITY_SHA512
;
890 return STATUS_SUCCESS
;
893 static void decode_encrypt_ctxt(struct ksmbd_conn
*conn
,
894 struct smb2_encryption_neg_context
*pneg_ctxt
,
900 if (sizeof(struct smb2_encryption_neg_context
) > ctxt_len
) {
901 pr_err("Invalid SMB2_ENCRYPTION_CAPABILITIES context size\n");
905 conn
->cipher_type
= 0;
907 cph_cnt
= le16_to_cpu(pneg_ctxt
->CipherCount
);
908 cphs_size
= cph_cnt
* sizeof(__le16
);
910 if (sizeof(struct smb2_encryption_neg_context
) + cphs_size
>
912 pr_err("Invalid cipher count(%d)\n", cph_cnt
);
916 if (server_conf
.flags
& KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF
)
919 for (i
= 0; i
< cph_cnt
; i
++) {
920 if (pneg_ctxt
->Ciphers
[i
] == SMB2_ENCRYPTION_AES128_GCM
||
921 pneg_ctxt
->Ciphers
[i
] == SMB2_ENCRYPTION_AES128_CCM
||
922 pneg_ctxt
->Ciphers
[i
] == SMB2_ENCRYPTION_AES256_CCM
||
923 pneg_ctxt
->Ciphers
[i
] == SMB2_ENCRYPTION_AES256_GCM
) {
924 ksmbd_debug(SMB
, "Cipher ID = 0x%x\n",
925 pneg_ctxt
->Ciphers
[i
]);
926 conn
->cipher_type
= pneg_ctxt
->Ciphers
[i
];
933 * smb3_encryption_negotiated() - checks if server and client agreed on enabling encryption
934 * @conn: smb connection
936 * Return: true if connection should be encrypted, else false
938 bool smb3_encryption_negotiated(struct ksmbd_conn
*conn
)
940 if (!conn
->ops
->generate_encryptionkey
)
944 * SMB 3.0 and 3.0.2 dialects use the SMB2_GLOBAL_CAP_ENCRYPTION flag.
945 * SMB 3.1.1 uses the cipher_type field.
947 return (conn
->vals
->capabilities
& SMB2_GLOBAL_CAP_ENCRYPTION
) ||
951 static void decode_compress_ctxt(struct ksmbd_conn
*conn
,
952 struct smb2_compression_capabilities_context
*pneg_ctxt
)
954 conn
->compress_algorithm
= SMB3_COMPRESS_NONE
;
957 static void decode_sign_cap_ctxt(struct ksmbd_conn
*conn
,
958 struct smb2_signing_capabilities
*pneg_ctxt
,
962 int i
, sign_alos_size
;
964 if (sizeof(struct smb2_signing_capabilities
) > ctxt_len
) {
965 pr_err("Invalid SMB2_SIGNING_CAPABILITIES context length\n");
969 conn
->signing_negotiated
= false;
970 sign_algo_cnt
= le16_to_cpu(pneg_ctxt
->SigningAlgorithmCount
);
971 sign_alos_size
= sign_algo_cnt
* sizeof(__le16
);
973 if (sizeof(struct smb2_signing_capabilities
) + sign_alos_size
>
975 pr_err("Invalid signing algorithm count(%d)\n", sign_algo_cnt
);
979 for (i
= 0; i
< sign_algo_cnt
; i
++) {
980 if (pneg_ctxt
->SigningAlgorithms
[i
] == SIGNING_ALG_HMAC_SHA256_LE
||
981 pneg_ctxt
->SigningAlgorithms
[i
] == SIGNING_ALG_AES_CMAC_LE
) {
982 ksmbd_debug(SMB
, "Signing Algorithm ID = 0x%x\n",
983 pneg_ctxt
->SigningAlgorithms
[i
]);
984 conn
->signing_negotiated
= true;
985 conn
->signing_algorithm
=
986 pneg_ctxt
->SigningAlgorithms
[i
];
992 static __le32
deassemble_neg_contexts(struct ksmbd_conn
*conn
,
993 struct smb2_negotiate_req
*req
,
994 unsigned int len_of_smb
)
996 /* +4 is to account for the RFC1001 len field */
997 struct smb2_neg_context
*pctx
= (struct smb2_neg_context
*)req
;
998 int i
= 0, len_of_ctxts
;
999 unsigned int offset
= le32_to_cpu(req
->NegotiateContextOffset
);
1000 unsigned int neg_ctxt_cnt
= le16_to_cpu(req
->NegotiateContextCount
);
1001 __le32 status
= STATUS_INVALID_PARAMETER
;
1003 ksmbd_debug(SMB
, "decoding %d negotiate contexts\n", neg_ctxt_cnt
);
1004 if (len_of_smb
<= offset
) {
1005 ksmbd_debug(SMB
, "Invalid response: negotiate context offset\n");
1009 len_of_ctxts
= len_of_smb
- offset
;
1011 while (i
++ < neg_ctxt_cnt
) {
1014 if (len_of_ctxts
< (int)sizeof(struct smb2_neg_context
))
1017 pctx
= (struct smb2_neg_context
*)((char *)pctx
+ offset
);
1018 clen
= le16_to_cpu(pctx
->DataLength
);
1019 ctxt_len
= clen
+ sizeof(struct smb2_neg_context
);
1021 if (ctxt_len
> len_of_ctxts
)
1024 if (pctx
->ContextType
== SMB2_PREAUTH_INTEGRITY_CAPABILITIES
) {
1026 "deassemble SMB2_PREAUTH_INTEGRITY_CAPABILITIES context\n");
1027 if (conn
->preauth_info
->Preauth_HashId
)
1030 status
= decode_preauth_ctxt(conn
,
1031 (struct smb2_preauth_neg_context
*)pctx
,
1033 if (status
!= STATUS_SUCCESS
)
1035 } else if (pctx
->ContextType
== SMB2_ENCRYPTION_CAPABILITIES
) {
1037 "deassemble SMB2_ENCRYPTION_CAPABILITIES context\n");
1038 if (conn
->cipher_type
)
1041 decode_encrypt_ctxt(conn
,
1042 (struct smb2_encryption_neg_context
*)pctx
,
1044 } else if (pctx
->ContextType
== SMB2_COMPRESSION_CAPABILITIES
) {
1046 "deassemble SMB2_COMPRESSION_CAPABILITIES context\n");
1047 if (conn
->compress_algorithm
)
1050 decode_compress_ctxt(conn
,
1051 (struct smb2_compression_capabilities_context
*)pctx
);
1052 } else if (pctx
->ContextType
== SMB2_NETNAME_NEGOTIATE_CONTEXT_ID
) {
1054 "deassemble SMB2_NETNAME_NEGOTIATE_CONTEXT_ID context\n");
1055 } else if (pctx
->ContextType
== SMB2_POSIX_EXTENSIONS_AVAILABLE
) {
1057 "deassemble SMB2_POSIX_EXTENSIONS_AVAILABLE context\n");
1058 conn
->posix_ext_supported
= true;
1059 } else if (pctx
->ContextType
== SMB2_SIGNING_CAPABILITIES
) {
1061 "deassemble SMB2_SIGNING_CAPABILITIES context\n");
1063 decode_sign_cap_ctxt(conn
,
1064 (struct smb2_signing_capabilities
*)pctx
,
1068 /* offsets must be 8 byte aligned */
1069 offset
= (ctxt_len
+ 7) & ~0x7;
1070 len_of_ctxts
-= offset
;
1076 * smb2_handle_negotiate() - handler for smb2 negotiate command
1077 * @work: smb work containing smb request buffer
1081 int smb2_handle_negotiate(struct ksmbd_work
*work
)
1083 struct ksmbd_conn
*conn
= work
->conn
;
1084 struct smb2_negotiate_req
*req
= smb2_get_msg(work
->request_buf
);
1085 struct smb2_negotiate_rsp
*rsp
= smb2_get_msg(work
->response_buf
);
1087 unsigned int smb2_buf_len
, smb2_neg_size
, neg_ctxt_len
= 0;
1090 ksmbd_debug(SMB
, "Received negotiate request\n");
1091 conn
->need_neg
= false;
1092 if (ksmbd_conn_good(conn
)) {
1093 pr_err("conn->tcp_status is already in CifsGood State\n");
1094 work
->send_no_response
= 1;
1098 smb2_buf_len
= get_rfc1002_len(work
->request_buf
);
1099 smb2_neg_size
= offsetof(struct smb2_negotiate_req
, Dialects
);
1100 if (smb2_neg_size
> smb2_buf_len
) {
1101 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
1106 if (req
->DialectCount
== 0) {
1107 pr_err("malformed packet\n");
1108 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
1113 if (conn
->dialect
== SMB311_PROT_ID
) {
1114 unsigned int nego_ctxt_off
= le32_to_cpu(req
->NegotiateContextOffset
);
1116 if (smb2_buf_len
< nego_ctxt_off
) {
1117 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
1122 if (smb2_neg_size
> nego_ctxt_off
) {
1123 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
1128 if (smb2_neg_size
+ le16_to_cpu(req
->DialectCount
) * sizeof(__le16
) >
1130 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
1135 if (smb2_neg_size
+ le16_to_cpu(req
->DialectCount
) * sizeof(__le16
) >
1137 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
1143 conn
->cli_cap
= le32_to_cpu(req
->Capabilities
);
1144 switch (conn
->dialect
) {
1145 case SMB311_PROT_ID
:
1146 conn
->preauth_info
=
1147 kzalloc(sizeof(struct preauth_integrity_info
),
1149 if (!conn
->preauth_info
) {
1151 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
1155 status
= deassemble_neg_contexts(conn
, req
,
1156 get_rfc1002_len(work
->request_buf
));
1157 if (status
!= STATUS_SUCCESS
) {
1158 pr_err("deassemble_neg_contexts error(0x%x)\n",
1160 rsp
->hdr
.Status
= status
;
1162 kfree(conn
->preauth_info
);
1163 conn
->preauth_info
= NULL
;
1167 rc
= init_smb3_11_server(conn
);
1169 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
1170 kfree(conn
->preauth_info
);
1171 conn
->preauth_info
= NULL
;
1175 ksmbd_gen_preauth_integrity_hash(conn
,
1177 conn
->preauth_info
->Preauth_HashValue
);
1178 rsp
->NegotiateContextOffset
=
1179 cpu_to_le32(OFFSET_OF_NEG_CONTEXT
);
1180 neg_ctxt_len
= assemble_neg_contexts(conn
, rsp
);
1182 case SMB302_PROT_ID
:
1183 init_smb3_02_server(conn
);
1186 init_smb3_0_server(conn
);
1189 init_smb2_1_server(conn
);
1194 ksmbd_debug(SMB
, "Server dialect :0x%x not supported\n",
1196 rsp
->hdr
.Status
= STATUS_NOT_SUPPORTED
;
1200 rsp
->Capabilities
= cpu_to_le32(conn
->vals
->capabilities
);
1203 conn
->connection_type
= conn
->dialect
;
1205 rsp
->MaxTransactSize
= cpu_to_le32(conn
->vals
->max_trans_size
);
1206 rsp
->MaxReadSize
= cpu_to_le32(conn
->vals
->max_read_size
);
1207 rsp
->MaxWriteSize
= cpu_to_le32(conn
->vals
->max_write_size
);
1209 memcpy(conn
->ClientGUID
, req
->ClientGUID
,
1210 SMB2_CLIENT_GUID_SIZE
);
1211 conn
->cli_sec_mode
= le16_to_cpu(req
->SecurityMode
);
1213 rsp
->StructureSize
= cpu_to_le16(65);
1214 rsp
->DialectRevision
= cpu_to_le16(conn
->dialect
);
1215 /* Not setting conn guid rsp->ServerGUID, as it
1216 * not used by client for identifying server
1218 memset(rsp
->ServerGUID
, 0, SMB2_CLIENT_GUID_SIZE
);
1220 rsp
->SystemTime
= cpu_to_le64(ksmbd_systime());
1221 rsp
->ServerStartTime
= 0;
1222 ksmbd_debug(SMB
, "negotiate context offset %d, count %d\n",
1223 le32_to_cpu(rsp
->NegotiateContextOffset
),
1224 le16_to_cpu(rsp
->NegotiateContextCount
));
1226 rsp
->SecurityBufferOffset
= cpu_to_le16(128);
1227 rsp
->SecurityBufferLength
= cpu_to_le16(AUTH_GSS_LENGTH
);
1228 ksmbd_copy_gss_neg_header((char *)(&rsp
->hdr
) +
1229 le16_to_cpu(rsp
->SecurityBufferOffset
));
1231 rsp
->SecurityMode
= SMB2_NEGOTIATE_SIGNING_ENABLED_LE
;
1232 conn
->use_spnego
= true;
1234 if ((server_conf
.signing
== KSMBD_CONFIG_OPT_AUTO
||
1235 server_conf
.signing
== KSMBD_CONFIG_OPT_DISABLED
) &&
1236 req
->SecurityMode
& SMB2_NEGOTIATE_SIGNING_REQUIRED_LE
)
1238 else if (server_conf
.signing
== KSMBD_CONFIG_OPT_MANDATORY
) {
1239 server_conf
.enforced_signing
= true;
1240 rsp
->SecurityMode
|= SMB2_NEGOTIATE_SIGNING_REQUIRED_LE
;
1244 conn
->srv_sec_mode
= le16_to_cpu(rsp
->SecurityMode
);
1245 ksmbd_conn_set_need_negotiate(conn
);
1249 rsp
->hdr
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
1252 rc
= ksmbd_iov_pin_rsp(work
, rsp
,
1253 sizeof(struct smb2_negotiate_rsp
) +
1254 AUTH_GSS_LENGTH
+ neg_ctxt_len
);
1256 smb2_set_err_rsp(work
);
1260 static int alloc_preauth_hash(struct ksmbd_session
*sess
,
1261 struct ksmbd_conn
*conn
)
1263 if (sess
->Preauth_HashValue
)
1266 sess
->Preauth_HashValue
= kmemdup(conn
->preauth_info
->Preauth_HashValue
,
1267 PREAUTH_HASHVALUE_SIZE
, GFP_KERNEL
);
1268 if (!sess
->Preauth_HashValue
)
1274 static int generate_preauth_hash(struct ksmbd_work
*work
)
1276 struct ksmbd_conn
*conn
= work
->conn
;
1277 struct ksmbd_session
*sess
= work
->sess
;
1280 if (conn
->dialect
!= SMB311_PROT_ID
)
1283 if (conn
->binding
) {
1284 struct preauth_session
*preauth_sess
;
1286 preauth_sess
= ksmbd_preauth_session_lookup(conn
, sess
->id
);
1287 if (!preauth_sess
) {
1288 preauth_sess
= ksmbd_preauth_session_alloc(conn
, sess
->id
);
1293 preauth_hash
= preauth_sess
->Preauth_HashValue
;
1295 if (!sess
->Preauth_HashValue
)
1296 if (alloc_preauth_hash(sess
, conn
))
1298 preauth_hash
= sess
->Preauth_HashValue
;
1301 ksmbd_gen_preauth_integrity_hash(conn
, work
->request_buf
, preauth_hash
);
1305 static int decode_negotiation_token(struct ksmbd_conn
*conn
,
1306 struct negotiate_message
*negblob
,
1309 if (!conn
->use_spnego
)
1312 if (ksmbd_decode_negTokenInit((char *)negblob
, sz
, conn
)) {
1313 if (ksmbd_decode_negTokenTarg((char *)negblob
, sz
, conn
)) {
1314 conn
->auth_mechs
|= KSMBD_AUTH_NTLMSSP
;
1315 conn
->preferred_auth_mech
= KSMBD_AUTH_NTLMSSP
;
1316 conn
->use_spnego
= false;
1322 static int ntlm_negotiate(struct ksmbd_work
*work
,
1323 struct negotiate_message
*negblob
,
1324 size_t negblob_len
, struct smb2_sess_setup_rsp
*rsp
)
1326 struct challenge_message
*chgblob
;
1327 unsigned char *spnego_blob
= NULL
;
1328 u16 spnego_blob_len
;
1332 ksmbd_debug(SMB
, "negotiate phase\n");
1333 rc
= ksmbd_decode_ntlmssp_neg_blob(negblob
, negblob_len
, work
->conn
);
1337 sz
= le16_to_cpu(rsp
->SecurityBufferOffset
);
1338 chgblob
= (struct challenge_message
*)rsp
->Buffer
;
1339 memset(chgblob
, 0, sizeof(struct challenge_message
));
1341 if (!work
->conn
->use_spnego
) {
1342 sz
= ksmbd_build_ntlmssp_challenge_blob(chgblob
, work
->conn
);
1346 rsp
->SecurityBufferLength
= cpu_to_le16(sz
);
1350 sz
= sizeof(struct challenge_message
);
1351 sz
+= (strlen(ksmbd_netbios_name()) * 2 + 1 + 4) * 6;
1353 neg_blob
= kzalloc(sz
, GFP_KERNEL
);
1357 chgblob
= (struct challenge_message
*)neg_blob
;
1358 sz
= ksmbd_build_ntlmssp_challenge_blob(chgblob
, work
->conn
);
1364 rc
= build_spnego_ntlmssp_neg_blob(&spnego_blob
, &spnego_blob_len
,
1371 memcpy(rsp
->Buffer
, spnego_blob
, spnego_blob_len
);
1372 rsp
->SecurityBufferLength
= cpu_to_le16(spnego_blob_len
);
1380 static struct authenticate_message
*user_authblob(struct ksmbd_conn
*conn
,
1381 struct smb2_sess_setup_req
*req
)
1385 if (conn
->use_spnego
&& conn
->mechToken
)
1386 return (struct authenticate_message
*)conn
->mechToken
;
1388 sz
= le16_to_cpu(req
->SecurityBufferOffset
);
1389 return (struct authenticate_message
*)((char *)&req
->hdr
.ProtocolId
1393 static struct ksmbd_user
*session_user(struct ksmbd_conn
*conn
,
1394 struct smb2_sess_setup_req
*req
)
1396 struct authenticate_message
*authblob
;
1397 struct ksmbd_user
*user
;
1399 unsigned int name_off
, name_len
, secbuf_len
;
1401 if (conn
->use_spnego
&& conn
->mechToken
)
1402 secbuf_len
= conn
->mechTokenLen
;
1404 secbuf_len
= le16_to_cpu(req
->SecurityBufferLength
);
1405 if (secbuf_len
< sizeof(struct authenticate_message
)) {
1406 ksmbd_debug(SMB
, "blob len %d too small\n", secbuf_len
);
1409 authblob
= user_authblob(conn
, req
);
1410 name_off
= le32_to_cpu(authblob
->UserName
.BufferOffset
);
1411 name_len
= le16_to_cpu(authblob
->UserName
.Length
);
1413 if (secbuf_len
< (u64
)name_off
+ name_len
)
1416 name
= smb_strndup_from_utf16((const char *)authblob
+ name_off
,
1421 pr_err("cannot allocate memory\n");
1425 ksmbd_debug(SMB
, "session setup request for user %s\n", name
);
1426 user
= ksmbd_login_user(name
);
1431 static int ntlm_authenticate(struct ksmbd_work
*work
,
1432 struct smb2_sess_setup_req
*req
,
1433 struct smb2_sess_setup_rsp
*rsp
)
1435 struct ksmbd_conn
*conn
= work
->conn
;
1436 struct ksmbd_session
*sess
= work
->sess
;
1437 struct channel
*chann
= NULL
;
1438 struct ksmbd_user
*user
;
1442 ksmbd_debug(SMB
, "authenticate phase\n");
1443 if (conn
->use_spnego
) {
1444 unsigned char *spnego_blob
;
1445 u16 spnego_blob_len
;
1447 rc
= build_spnego_ntlmssp_auth_blob(&spnego_blob
,
1453 memcpy(rsp
->Buffer
, spnego_blob
, spnego_blob_len
);
1454 rsp
->SecurityBufferLength
= cpu_to_le16(spnego_blob_len
);
1458 user
= session_user(conn
, req
);
1460 ksmbd_debug(SMB
, "Unknown user name or an error\n");
1464 /* Check for previous session */
1465 prev_id
= le64_to_cpu(req
->PreviousSessionId
);
1466 if (prev_id
&& prev_id
!= sess
->id
)
1467 destroy_previous_session(conn
, user
, prev_id
);
1469 if (sess
->state
== SMB2_SESSION_VALID
) {
1471 * Reuse session if anonymous try to connect
1472 * on reauthetication.
1474 if (conn
->binding
== false && ksmbd_anonymous_user(user
)) {
1475 ksmbd_free_user(user
);
1479 if (!ksmbd_compare_user(sess
->user
, user
)) {
1480 ksmbd_free_user(user
);
1483 ksmbd_free_user(user
);
1488 if (conn
->binding
== false && user_guest(sess
->user
)) {
1489 rsp
->SessionFlags
= SMB2_SESSION_FLAG_IS_GUEST_LE
;
1491 struct authenticate_message
*authblob
;
1493 authblob
= user_authblob(conn
, req
);
1494 if (conn
->use_spnego
&& conn
->mechToken
)
1495 sz
= conn
->mechTokenLen
;
1497 sz
= le16_to_cpu(req
->SecurityBufferLength
);
1498 rc
= ksmbd_decode_ntlmssp_auth_blob(authblob
, sz
, conn
, sess
);
1500 set_user_flag(sess
->user
, KSMBD_USER_FLAG_BAD_PASSWORD
);
1501 ksmbd_debug(SMB
, "authentication failed\n");
1507 * If session state is SMB2_SESSION_VALID, We can assume
1508 * that it is reauthentication. And the user/password
1509 * has been verified, so return it here.
1511 if (sess
->state
== SMB2_SESSION_VALID
) {
1513 goto binding_session
;
1517 if ((rsp
->SessionFlags
!= SMB2_SESSION_FLAG_IS_GUEST_LE
&&
1518 (conn
->sign
|| server_conf
.enforced_signing
)) ||
1519 (req
->SecurityMode
& SMB2_NEGOTIATE_SIGNING_REQUIRED
))
1522 if (smb3_encryption_negotiated(conn
) &&
1523 !(req
->Flags
& SMB2_SESSION_REQ_FLAG_BINDING
)) {
1524 rc
= conn
->ops
->generate_encryptionkey(conn
, sess
);
1527 "SMB3 encryption key generation failed\n");
1531 if (server_conf
.flags
& KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION
)
1532 rsp
->SessionFlags
= SMB2_SESSION_FLAG_ENCRYPT_DATA_LE
;
1534 * signing is disable if encryption is enable
1541 if (conn
->dialect
>= SMB30_PROT_ID
) {
1542 chann
= lookup_chann_list(sess
, conn
);
1544 chann
= kmalloc(sizeof(struct channel
), GFP_KERNEL
);
1549 xa_store(&sess
->ksmbd_chann_list
, (long)conn
, chann
, GFP_KERNEL
);
1553 if (conn
->ops
->generate_signingkey
) {
1554 rc
= conn
->ops
->generate_signingkey(sess
, conn
);
1556 ksmbd_debug(SMB
, "SMB3 signing key generation failed\n");
1561 if (!ksmbd_conn_lookup_dialect(conn
)) {
1562 pr_err("fail to verify the dialect\n");
1568 #ifdef CONFIG_SMB_SERVER_KERBEROS5
1569 static int krb5_authenticate(struct ksmbd_work
*work
,
1570 struct smb2_sess_setup_req
*req
,
1571 struct smb2_sess_setup_rsp
*rsp
)
1573 struct ksmbd_conn
*conn
= work
->conn
;
1574 struct ksmbd_session
*sess
= work
->sess
;
1575 char *in_blob
, *out_blob
;
1576 struct channel
*chann
= NULL
;
1578 int in_len
, out_len
;
1581 in_blob
= (char *)&req
->hdr
.ProtocolId
+
1582 le16_to_cpu(req
->SecurityBufferOffset
);
1583 in_len
= le16_to_cpu(req
->SecurityBufferLength
);
1584 out_blob
= (char *)&rsp
->hdr
.ProtocolId
+
1585 le16_to_cpu(rsp
->SecurityBufferOffset
);
1586 out_len
= work
->response_sz
-
1587 (le16_to_cpu(rsp
->SecurityBufferOffset
) + 4);
1589 /* Check previous session */
1590 prev_sess_id
= le64_to_cpu(req
->PreviousSessionId
);
1591 if (prev_sess_id
&& prev_sess_id
!= sess
->id
)
1592 destroy_previous_session(conn
, sess
->user
, prev_sess_id
);
1594 if (sess
->state
== SMB2_SESSION_VALID
)
1595 ksmbd_free_user(sess
->user
);
1597 retval
= ksmbd_krb5_authenticate(sess
, in_blob
, in_len
,
1598 out_blob
, &out_len
);
1600 ksmbd_debug(SMB
, "krb5 authentication failed\n");
1603 rsp
->SecurityBufferLength
= cpu_to_le16(out_len
);
1605 if ((conn
->sign
|| server_conf
.enforced_signing
) ||
1606 (req
->SecurityMode
& SMB2_NEGOTIATE_SIGNING_REQUIRED
))
1609 if (smb3_encryption_negotiated(conn
)) {
1610 retval
= conn
->ops
->generate_encryptionkey(conn
, sess
);
1613 "SMB3 encryption key generation failed\n");
1617 if (server_conf
.flags
& KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION
)
1618 rsp
->SessionFlags
= SMB2_SESSION_FLAG_ENCRYPT_DATA_LE
;
1622 if (conn
->dialect
>= SMB30_PROT_ID
) {
1623 chann
= lookup_chann_list(sess
, conn
);
1625 chann
= kmalloc(sizeof(struct channel
), GFP_KERNEL
);
1630 xa_store(&sess
->ksmbd_chann_list
, (long)conn
, chann
, GFP_KERNEL
);
1634 if (conn
->ops
->generate_signingkey
) {
1635 retval
= conn
->ops
->generate_signingkey(sess
, conn
);
1637 ksmbd_debug(SMB
, "SMB3 signing key generation failed\n");
1642 if (!ksmbd_conn_lookup_dialect(conn
)) {
1643 pr_err("fail to verify the dialect\n");
1649 static int krb5_authenticate(struct ksmbd_work
*work
,
1650 struct smb2_sess_setup_req
*req
,
1651 struct smb2_sess_setup_rsp
*rsp
)
1657 int smb2_sess_setup(struct ksmbd_work
*work
)
1659 struct ksmbd_conn
*conn
= work
->conn
;
1660 struct smb2_sess_setup_req
*req
;
1661 struct smb2_sess_setup_rsp
*rsp
;
1662 struct ksmbd_session
*sess
;
1663 struct negotiate_message
*negblob
;
1664 unsigned int negblob_len
, negblob_off
;
1667 ksmbd_debug(SMB
, "Received request for session setup\n");
1669 WORK_BUFFERS(work
, req
, rsp
);
1671 rsp
->StructureSize
= cpu_to_le16(9);
1672 rsp
->SessionFlags
= 0;
1673 rsp
->SecurityBufferOffset
= cpu_to_le16(72);
1674 rsp
->SecurityBufferLength
= 0;
1676 ksmbd_conn_lock(conn
);
1677 if (!req
->hdr
.SessionId
) {
1678 sess
= ksmbd_smb2_session_create();
1683 rsp
->hdr
.SessionId
= cpu_to_le64(sess
->id
);
1684 rc
= ksmbd_session_register(conn
, sess
);
1688 conn
->binding
= false;
1689 } else if (conn
->dialect
>= SMB30_PROT_ID
&&
1690 (server_conf
.flags
& KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL
) &&
1691 req
->Flags
& SMB2_SESSION_REQ_FLAG_BINDING
) {
1692 u64 sess_id
= le64_to_cpu(req
->hdr
.SessionId
);
1694 sess
= ksmbd_session_lookup_slowpath(sess_id
);
1700 if (conn
->dialect
!= sess
->dialect
) {
1705 if (!(req
->hdr
.Flags
& SMB2_FLAGS_SIGNED
)) {
1710 if (strncmp(conn
->ClientGUID
, sess
->ClientGUID
,
1711 SMB2_CLIENT_GUID_SIZE
)) {
1716 if (sess
->state
== SMB2_SESSION_IN_PROGRESS
) {
1721 if (sess
->state
== SMB2_SESSION_EXPIRED
) {
1726 if (ksmbd_conn_need_reconnect(conn
)) {
1732 if (ksmbd_session_lookup(conn
, sess_id
)) {
1737 if (user_guest(sess
->user
)) {
1742 conn
->binding
= true;
1743 } else if ((conn
->dialect
< SMB30_PROT_ID
||
1744 server_conf
.flags
& KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL
) &&
1745 (req
->Flags
& SMB2_SESSION_REQ_FLAG_BINDING
)) {
1750 sess
= ksmbd_session_lookup(conn
,
1751 le64_to_cpu(req
->hdr
.SessionId
));
1757 if (sess
->state
== SMB2_SESSION_EXPIRED
) {
1762 if (ksmbd_conn_need_reconnect(conn
)) {
1768 conn
->binding
= false;
1772 negblob_off
= le16_to_cpu(req
->SecurityBufferOffset
);
1773 negblob_len
= le16_to_cpu(req
->SecurityBufferLength
);
1774 if (negblob_off
< offsetof(struct smb2_sess_setup_req
, Buffer
)) {
1779 negblob
= (struct negotiate_message
*)((char *)&req
->hdr
.ProtocolId
+
1782 if (decode_negotiation_token(conn
, negblob
, negblob_len
) == 0) {
1783 if (conn
->mechToken
) {
1784 negblob
= (struct negotiate_message
*)conn
->mechToken
;
1785 negblob_len
= conn
->mechTokenLen
;
1789 if (negblob_len
< offsetof(struct negotiate_message
, NegotiateFlags
)) {
1794 if (server_conf
.auth_mechs
& conn
->auth_mechs
) {
1795 rc
= generate_preauth_hash(work
);
1799 if (conn
->preferred_auth_mech
&
1800 (KSMBD_AUTH_KRB5
| KSMBD_AUTH_MSKRB5
)) {
1801 rc
= krb5_authenticate(work
, req
, rsp
);
1807 if (!ksmbd_conn_need_reconnect(conn
)) {
1808 ksmbd_conn_set_good(conn
);
1809 sess
->state
= SMB2_SESSION_VALID
;
1811 kfree(sess
->Preauth_HashValue
);
1812 sess
->Preauth_HashValue
= NULL
;
1813 } else if (conn
->preferred_auth_mech
== KSMBD_AUTH_NTLMSSP
) {
1814 if (negblob
->MessageType
== NtLmNegotiate
) {
1815 rc
= ntlm_negotiate(work
, negblob
, negblob_len
, rsp
);
1819 STATUS_MORE_PROCESSING_REQUIRED
;
1820 } else if (negblob
->MessageType
== NtLmAuthenticate
) {
1821 rc
= ntlm_authenticate(work
, req
, rsp
);
1825 if (!ksmbd_conn_need_reconnect(conn
)) {
1826 ksmbd_conn_set_good(conn
);
1827 sess
->state
= SMB2_SESSION_VALID
;
1829 if (conn
->binding
) {
1830 struct preauth_session
*preauth_sess
;
1833 ksmbd_preauth_session_lookup(conn
, sess
->id
);
1835 list_del(&preauth_sess
->preauth_entry
);
1836 kfree(preauth_sess
);
1839 kfree(sess
->Preauth_HashValue
);
1840 sess
->Preauth_HashValue
= NULL
;
1842 pr_info_ratelimited("Unknown NTLMSSP message type : 0x%x\n",
1843 le32_to_cpu(negblob
->MessageType
));
1847 /* TODO: need one more negotiation */
1848 pr_err("Not support the preferred authentication\n");
1852 pr_err("Not support authentication\n");
1858 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
1859 else if (rc
== -ENOENT
)
1860 rsp
->hdr
.Status
= STATUS_USER_SESSION_DELETED
;
1861 else if (rc
== -EACCES
)
1862 rsp
->hdr
.Status
= STATUS_REQUEST_NOT_ACCEPTED
;
1863 else if (rc
== -EFAULT
)
1864 rsp
->hdr
.Status
= STATUS_NETWORK_SESSION_EXPIRED
;
1865 else if (rc
== -ENOMEM
)
1866 rsp
->hdr
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
1867 else if (rc
== -EOPNOTSUPP
)
1868 rsp
->hdr
.Status
= STATUS_NOT_SUPPORTED
;
1870 rsp
->hdr
.Status
= STATUS_LOGON_FAILURE
;
1872 if (conn
->use_spnego
&& conn
->mechToken
) {
1873 kfree(conn
->mechToken
);
1874 conn
->mechToken
= NULL
;
1879 * SecurityBufferOffset should be set to zero
1880 * in session setup error response.
1882 rsp
->SecurityBufferOffset
= 0;
1885 bool try_delay
= false;
1888 * To avoid dictionary attacks (repeated session setups rapidly sent) to
1889 * connect to server, ksmbd make a delay of a 5 seconds on session setup
1890 * failure to make it harder to send enough random connection requests
1891 * to break into a server.
1893 if (sess
->user
&& sess
->user
->flags
& KSMBD_USER_FLAG_DELAY_SESSION
)
1896 sess
->last_active
= jiffies
;
1897 sess
->state
= SMB2_SESSION_EXPIRED
;
1899 ksmbd_conn_set_need_reconnect(conn
);
1901 ksmbd_conn_set_need_negotiate(conn
);
1904 smb2_set_err_rsp(work
);
1906 unsigned int iov_len
;
1908 if (rsp
->SecurityBufferLength
)
1909 iov_len
= offsetof(struct smb2_sess_setup_rsp
, Buffer
) +
1910 le16_to_cpu(rsp
->SecurityBufferLength
);
1912 iov_len
= sizeof(struct smb2_sess_setup_rsp
);
1913 rc
= ksmbd_iov_pin_rsp(work
, rsp
, iov_len
);
1915 rsp
->hdr
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
1918 ksmbd_conn_unlock(conn
);
1923 * smb2_tree_connect() - handler for smb2 tree connect command
1924 * @work: smb work containing smb request buffer
1926 * Return: 0 on success, otherwise error
1928 int smb2_tree_connect(struct ksmbd_work
*work
)
1930 struct ksmbd_conn
*conn
= work
->conn
;
1931 struct smb2_tree_connect_req
*req
;
1932 struct smb2_tree_connect_rsp
*rsp
;
1933 struct ksmbd_session
*sess
= work
->sess
;
1934 char *treename
= NULL
, *name
= NULL
;
1935 struct ksmbd_tree_conn_status status
;
1936 struct ksmbd_share_config
*share
= NULL
;
1939 WORK_BUFFERS(work
, req
, rsp
);
1941 treename
= smb_strndup_from_utf16((char *)req
+ le16_to_cpu(req
->PathOffset
),
1942 le16_to_cpu(req
->PathLength
), true,
1944 if (IS_ERR(treename
)) {
1945 pr_err("treename is NULL\n");
1946 status
.ret
= KSMBD_TREE_CONN_STATUS_ERROR
;
1950 name
= ksmbd_extract_sharename(conn
->um
, treename
);
1952 status
.ret
= KSMBD_TREE_CONN_STATUS_ERROR
;
1956 ksmbd_debug(SMB
, "tree connect request for tree %s treename %s\n",
1959 status
= ksmbd_tree_conn_connect(work
, name
);
1960 if (status
.ret
== KSMBD_TREE_CONN_STATUS_OK
)
1961 rsp
->hdr
.Id
.SyncId
.TreeId
= cpu_to_le32(status
.tree_conn
->id
);
1965 share
= status
.tree_conn
->share_conf
;
1966 if (test_share_config_flag(share
, KSMBD_SHARE_FLAG_PIPE
)) {
1967 ksmbd_debug(SMB
, "IPC share path request\n");
1968 rsp
->ShareType
= SMB2_SHARE_TYPE_PIPE
;
1969 rsp
->MaximalAccess
= FILE_READ_DATA_LE
| FILE_READ_EA_LE
|
1970 FILE_EXECUTE_LE
| FILE_READ_ATTRIBUTES_LE
|
1971 FILE_DELETE_LE
| FILE_READ_CONTROL_LE
|
1972 FILE_WRITE_DAC_LE
| FILE_WRITE_OWNER_LE
|
1973 FILE_SYNCHRONIZE_LE
;
1975 rsp
->ShareType
= SMB2_SHARE_TYPE_DISK
;
1976 rsp
->MaximalAccess
= FILE_READ_DATA_LE
| FILE_READ_EA_LE
|
1977 FILE_EXECUTE_LE
| FILE_READ_ATTRIBUTES_LE
;
1978 if (test_tree_conn_flag(status
.tree_conn
,
1979 KSMBD_TREE_CONN_FLAG_WRITABLE
)) {
1980 rsp
->MaximalAccess
|= FILE_WRITE_DATA_LE
|
1981 FILE_APPEND_DATA_LE
| FILE_WRITE_EA_LE
|
1982 FILE_DELETE_LE
| FILE_WRITE_ATTRIBUTES_LE
|
1983 FILE_DELETE_CHILD_LE
| FILE_READ_CONTROL_LE
|
1984 FILE_WRITE_DAC_LE
| FILE_WRITE_OWNER_LE
|
1985 FILE_SYNCHRONIZE_LE
;
1989 status
.tree_conn
->maximal_access
= le32_to_cpu(rsp
->MaximalAccess
);
1990 if (conn
->posix_ext_supported
)
1991 status
.tree_conn
->posix_extensions
= true;
1993 write_lock(&sess
->tree_conns_lock
);
1994 status
.tree_conn
->t_state
= TREE_CONNECTED
;
1995 write_unlock(&sess
->tree_conns_lock
);
1996 rsp
->StructureSize
= cpu_to_le16(16);
1998 if (server_conf
.flags
& KSMBD_GLOBAL_FLAG_DURABLE_HANDLE
&& share
&&
1999 test_share_config_flag(share
,
2000 KSMBD_SHARE_FLAG_CONTINUOUS_AVAILABILITY
))
2001 rsp
->Capabilities
= SMB2_SHARE_CAP_CONTINUOUS_AVAILABILITY
;
2003 rsp
->Capabilities
= 0;
2005 /* default manual caching */
2006 rsp
->ShareFlags
= SMB2_SHAREFLAG_MANUAL_CACHING
;
2008 rc
= ksmbd_iov_pin_rsp(work
, rsp
, sizeof(struct smb2_tree_connect_rsp
));
2010 status
.ret
= KSMBD_TREE_CONN_STATUS_NOMEM
;
2012 if (!IS_ERR(treename
))
2017 switch (status
.ret
) {
2018 case KSMBD_TREE_CONN_STATUS_OK
:
2019 rsp
->hdr
.Status
= STATUS_SUCCESS
;
2024 case KSMBD_TREE_CONN_STATUS_NO_SHARE
:
2025 rsp
->hdr
.Status
= STATUS_BAD_NETWORK_NAME
;
2028 case KSMBD_TREE_CONN_STATUS_NOMEM
:
2029 rsp
->hdr
.Status
= STATUS_NO_MEMORY
;
2031 case KSMBD_TREE_CONN_STATUS_ERROR
:
2032 case KSMBD_TREE_CONN_STATUS_TOO_MANY_CONNS
:
2033 case KSMBD_TREE_CONN_STATUS_TOO_MANY_SESSIONS
:
2034 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
2037 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
2040 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
2043 if (status
.ret
!= KSMBD_TREE_CONN_STATUS_OK
)
2044 smb2_set_err_rsp(work
);
2050 * smb2_create_open_flags() - convert smb open flags to unix open flags
2051 * @file_present: is file already present
2052 * @access: file access flags
2053 * @disposition: file disposition flags
2054 * @may_flags: set with MAY_ flags
2055 * @coptions: file creation options
2058 * Return: file open flags
2060 static int smb2_create_open_flags(bool file_present
, __le32 access
,
2066 int oflags
= O_NONBLOCK
| O_LARGEFILE
;
2068 if (coptions
& FILE_DIRECTORY_FILE_LE
|| S_ISDIR(mode
)) {
2069 access
&= ~FILE_WRITE_DESIRE_ACCESS_LE
;
2070 ksmbd_debug(SMB
, "Discard write access to a directory\n");
2073 if (access
& FILE_READ_DESIRED_ACCESS_LE
&&
2074 access
& FILE_WRITE_DESIRE_ACCESS_LE
) {
2076 *may_flags
= MAY_OPEN
| MAY_READ
| MAY_WRITE
;
2077 } else if (access
& FILE_WRITE_DESIRE_ACCESS_LE
) {
2079 *may_flags
= MAY_OPEN
| MAY_WRITE
;
2082 *may_flags
= MAY_OPEN
| MAY_READ
;
2085 if (access
== FILE_READ_ATTRIBUTES_LE
|| S_ISBLK(mode
) || S_ISCHR(mode
))
2089 switch (disposition
& FILE_CREATE_MASK_LE
) {
2091 case FILE_CREATE_LE
:
2093 case FILE_SUPERSEDE_LE
:
2094 case FILE_OVERWRITE_LE
:
2095 case FILE_OVERWRITE_IF_LE
:
2102 switch (disposition
& FILE_CREATE_MASK_LE
) {
2103 case FILE_SUPERSEDE_LE
:
2104 case FILE_CREATE_LE
:
2105 case FILE_OPEN_IF_LE
:
2106 case FILE_OVERWRITE_IF_LE
:
2110 case FILE_OVERWRITE_LE
:
2122 * smb2_tree_disconnect() - handler for smb tree connect request
2123 * @work: smb work containing request buffer
2127 int smb2_tree_disconnect(struct ksmbd_work
*work
)
2129 struct smb2_tree_disconnect_rsp
*rsp
;
2130 struct smb2_tree_disconnect_req
*req
;
2131 struct ksmbd_session
*sess
= work
->sess
;
2132 struct ksmbd_tree_connect
*tcon
= work
->tcon
;
2135 WORK_BUFFERS(work
, req
, rsp
);
2137 ksmbd_debug(SMB
, "request\n");
2140 ksmbd_debug(SMB
, "Invalid tid %d\n", req
->hdr
.Id
.SyncId
.TreeId
);
2142 rsp
->hdr
.Status
= STATUS_NETWORK_NAME_DELETED
;
2147 ksmbd_close_tree_conn_fds(work
);
2149 write_lock(&sess
->tree_conns_lock
);
2150 if (tcon
->t_state
== TREE_DISCONNECTED
) {
2151 write_unlock(&sess
->tree_conns_lock
);
2152 rsp
->hdr
.Status
= STATUS_NETWORK_NAME_DELETED
;
2157 WARN_ON_ONCE(atomic_dec_and_test(&tcon
->refcount
));
2158 tcon
->t_state
= TREE_DISCONNECTED
;
2159 write_unlock(&sess
->tree_conns_lock
);
2161 err
= ksmbd_tree_conn_disconnect(sess
, tcon
);
2163 rsp
->hdr
.Status
= STATUS_NETWORK_NAME_DELETED
;
2169 rsp
->StructureSize
= cpu_to_le16(4);
2170 err
= ksmbd_iov_pin_rsp(work
, rsp
,
2171 sizeof(struct smb2_tree_disconnect_rsp
));
2173 rsp
->hdr
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
2180 smb2_set_err_rsp(work
);
2186 * smb2_session_logoff() - handler for session log off request
2187 * @work: smb work containing request buffer
2191 int smb2_session_logoff(struct ksmbd_work
*work
)
2193 struct ksmbd_conn
*conn
= work
->conn
;
2194 struct smb2_logoff_req
*req
;
2195 struct smb2_logoff_rsp
*rsp
;
2196 struct ksmbd_session
*sess
;
2200 WORK_BUFFERS(work
, req
, rsp
);
2202 ksmbd_debug(SMB
, "request\n");
2204 ksmbd_conn_lock(conn
);
2205 if (!ksmbd_conn_good(conn
)) {
2206 ksmbd_conn_unlock(conn
);
2207 rsp
->hdr
.Status
= STATUS_NETWORK_NAME_DELETED
;
2208 smb2_set_err_rsp(work
);
2211 sess_id
= le64_to_cpu(req
->hdr
.SessionId
);
2212 ksmbd_all_conn_set_status(sess_id
, KSMBD_SESS_NEED_RECONNECT
);
2213 ksmbd_conn_unlock(conn
);
2215 ksmbd_close_session_fds(work
);
2216 ksmbd_conn_wait_idle(conn
);
2219 * Re-lookup session to validate if session is deleted
2220 * while waiting request complete
2222 sess
= ksmbd_session_lookup_all(conn
, sess_id
);
2223 if (ksmbd_tree_conn_session_logoff(sess
)) {
2224 ksmbd_debug(SMB
, "Invalid tid %d\n", req
->hdr
.Id
.SyncId
.TreeId
);
2225 rsp
->hdr
.Status
= STATUS_NETWORK_NAME_DELETED
;
2226 smb2_set_err_rsp(work
);
2230 ksmbd_destroy_file_table(&sess
->file_table
);
2231 sess
->state
= SMB2_SESSION_EXPIRED
;
2233 ksmbd_free_user(sess
->user
);
2235 ksmbd_all_conn_set_status(sess_id
, KSMBD_SESS_NEED_NEGOTIATE
);
2237 rsp
->StructureSize
= cpu_to_le16(4);
2238 err
= ksmbd_iov_pin_rsp(work
, rsp
, sizeof(struct smb2_logoff_rsp
));
2240 rsp
->hdr
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
2241 smb2_set_err_rsp(work
);
2248 * create_smb2_pipe() - create IPC pipe
2249 * @work: smb work containing request buffer
2251 * Return: 0 on success, otherwise error
2253 static noinline
int create_smb2_pipe(struct ksmbd_work
*work
)
2255 struct smb2_create_rsp
*rsp
;
2256 struct smb2_create_req
*req
;
2261 WORK_BUFFERS(work
, req
, rsp
);
2263 name
= smb_strndup_from_utf16(req
->Buffer
, le16_to_cpu(req
->NameLength
),
2264 1, work
->conn
->local_nls
);
2266 rsp
->hdr
.Status
= STATUS_NO_MEMORY
;
2267 err
= PTR_ERR(name
);
2271 id
= ksmbd_session_rpc_open(work
->sess
, name
);
2273 pr_err("Unable to open RPC pipe: %d\n", id
);
2278 rsp
->hdr
.Status
= STATUS_SUCCESS
;
2279 rsp
->StructureSize
= cpu_to_le16(89);
2280 rsp
->OplockLevel
= SMB2_OPLOCK_LEVEL_NONE
;
2282 rsp
->CreateAction
= cpu_to_le32(FILE_OPENED
);
2284 rsp
->CreationTime
= cpu_to_le64(0);
2285 rsp
->LastAccessTime
= cpu_to_le64(0);
2286 rsp
->ChangeTime
= cpu_to_le64(0);
2287 rsp
->AllocationSize
= cpu_to_le64(0);
2288 rsp
->EndofFile
= cpu_to_le64(0);
2289 rsp
->FileAttributes
= FILE_ATTRIBUTE_NORMAL_LE
;
2291 rsp
->VolatileFileId
= id
;
2292 rsp
->PersistentFileId
= 0;
2293 rsp
->CreateContextsOffset
= 0;
2294 rsp
->CreateContextsLength
= 0;
2296 err
= ksmbd_iov_pin_rsp(work
, rsp
, offsetof(struct smb2_create_rsp
, Buffer
));
2306 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
2310 rsp
->hdr
.Status
= STATUS_NO_MEMORY
;
2317 smb2_set_err_rsp(work
);
2322 * smb2_set_ea() - handler for setting extended attributes using set
2324 * @eabuf: set info command buffer
2325 * @buf_len: set info command buffer length
2326 * @path: dentry path for get ea
2327 * @get_write: get write access to a mount
2329 * Return: 0 on success, otherwise error
2331 static int smb2_set_ea(struct smb2_ea_info
*eabuf
, unsigned int buf_len
,
2332 const struct path
*path
, bool get_write
)
2334 struct mnt_idmap
*idmap
= mnt_idmap(path
->mnt
);
2335 char *attr_name
= NULL
, *value
;
2337 unsigned int next
= 0;
2339 if (buf_len
< sizeof(struct smb2_ea_info
) + eabuf
->EaNameLength
+
2340 le16_to_cpu(eabuf
->EaValueLength
))
2343 attr_name
= kmalloc(XATTR_NAME_MAX
+ 1, GFP_KERNEL
);
2348 if (!eabuf
->EaNameLength
)
2352 "name : <%s>, name_len : %u, value_len : %u, next : %u\n",
2353 eabuf
->name
, eabuf
->EaNameLength
,
2354 le16_to_cpu(eabuf
->EaValueLength
),
2355 le32_to_cpu(eabuf
->NextEntryOffset
));
2357 if (eabuf
->EaNameLength
>
2358 (XATTR_NAME_MAX
- XATTR_USER_PREFIX_LEN
)) {
2363 memcpy(attr_name
, XATTR_USER_PREFIX
, XATTR_USER_PREFIX_LEN
);
2364 memcpy(&attr_name
[XATTR_USER_PREFIX_LEN
], eabuf
->name
,
2365 eabuf
->EaNameLength
);
2366 attr_name
[XATTR_USER_PREFIX_LEN
+ eabuf
->EaNameLength
] = '\0';
2367 value
= (char *)&eabuf
->name
+ eabuf
->EaNameLength
+ 1;
2369 if (!eabuf
->EaValueLength
) {
2370 rc
= ksmbd_vfs_casexattr_len(idmap
,
2373 XATTR_USER_PREFIX_LEN
+
2374 eabuf
->EaNameLength
);
2376 /* delete the EA only when it exits */
2378 rc
= ksmbd_vfs_remove_xattr(idmap
,
2385 "remove xattr failed(%d)\n",
2391 /* if the EA doesn't exist, just do nothing. */
2394 rc
= ksmbd_vfs_setxattr(idmap
, path
, attr_name
, value
,
2395 le16_to_cpu(eabuf
->EaValueLength
),
2399 "ksmbd_vfs_setxattr is failed(%d)\n",
2406 next
= le32_to_cpu(eabuf
->NextEntryOffset
);
2407 if (next
== 0 || buf_len
< next
)
2410 eabuf
= (struct smb2_ea_info
*)((char *)eabuf
+ next
);
2411 if (buf_len
< sizeof(struct smb2_ea_info
)) {
2416 if (buf_len
< sizeof(struct smb2_ea_info
) + eabuf
->EaNameLength
+
2417 le16_to_cpu(eabuf
->EaValueLength
)) {
2421 } while (next
!= 0);
2427 static noinline
int smb2_set_stream_name_xattr(const struct path
*path
,
2428 struct ksmbd_file
*fp
,
2429 char *stream_name
, int s_type
)
2431 struct mnt_idmap
*idmap
= mnt_idmap(path
->mnt
);
2432 size_t xattr_stream_size
;
2433 char *xattr_stream_name
;
2436 rc
= ksmbd_vfs_xattr_stream_name(stream_name
,
2443 fp
->stream
.name
= xattr_stream_name
;
2444 fp
->stream
.size
= xattr_stream_size
;
2446 /* Check if there is stream prefix in xattr space */
2447 rc
= ksmbd_vfs_casexattr_len(idmap
,
2454 if (fp
->cdoption
== FILE_OPEN_LE
) {
2455 ksmbd_debug(SMB
, "XATTR stream name lookup failed: %d\n", rc
);
2459 rc
= ksmbd_vfs_setxattr(idmap
, path
, xattr_stream_name
, NULL
, 0, 0, false);
2461 pr_err("Failed to store XATTR stream name :%d\n", rc
);
2465 static int smb2_remove_smb_xattrs(const struct path
*path
)
2467 struct mnt_idmap
*idmap
= mnt_idmap(path
->mnt
);
2468 char *name
, *xattr_list
= NULL
;
2469 ssize_t xattr_list_len
;
2472 xattr_list_len
= ksmbd_vfs_listxattr(path
->dentry
, &xattr_list
);
2473 if (xattr_list_len
< 0) {
2475 } else if (!xattr_list_len
) {
2476 ksmbd_debug(SMB
, "empty xattr in the file\n");
2480 for (name
= xattr_list
; name
- xattr_list
< xattr_list_len
;
2481 name
+= strlen(name
) + 1) {
2482 ksmbd_debug(SMB
, "%s, len %zd\n", name
, strlen(name
));
2484 if (!strncmp(name
, XATTR_USER_PREFIX
, XATTR_USER_PREFIX_LEN
) &&
2485 !strncmp(&name
[XATTR_USER_PREFIX_LEN
], STREAM_PREFIX
,
2486 STREAM_PREFIX_LEN
)) {
2487 err
= ksmbd_vfs_remove_xattr(idmap
, path
,
2490 ksmbd_debug(SMB
, "remove xattr failed : %s\n",
2499 static int smb2_create_truncate(const struct path
*path
)
2501 int rc
= vfs_truncate(path
, 0);
2504 pr_err("vfs_truncate failed, rc %d\n", rc
);
2508 rc
= smb2_remove_smb_xattrs(path
);
2509 if (rc
== -EOPNOTSUPP
)
2513 "ksmbd_truncate_stream_name_xattr failed, rc %d\n",
2518 static void smb2_new_xattrs(struct ksmbd_tree_connect
*tcon
, const struct path
*path
,
2519 struct ksmbd_file
*fp
)
2521 struct xattr_dos_attrib da
= {0};
2524 if (!test_share_config_flag(tcon
->share_conf
,
2525 KSMBD_SHARE_FLAG_STORE_DOS_ATTRS
))
2529 da
.attr
= le32_to_cpu(fp
->f_ci
->m_fattr
);
2530 da
.itime
= da
.create_time
= fp
->create_time
;
2531 da
.flags
= XATTR_DOSINFO_ATTRIB
| XATTR_DOSINFO_CREATE_TIME
|
2532 XATTR_DOSINFO_ITIME
;
2534 rc
= ksmbd_vfs_set_dos_attrib_xattr(mnt_idmap(path
->mnt
), path
, &da
, true);
2536 ksmbd_debug(SMB
, "failed to store file attribute into xattr\n");
2539 static void smb2_update_xattrs(struct ksmbd_tree_connect
*tcon
,
2540 const struct path
*path
, struct ksmbd_file
*fp
)
2542 struct xattr_dos_attrib da
;
2545 fp
->f_ci
->m_fattr
&= ~(FILE_ATTRIBUTE_HIDDEN_LE
| FILE_ATTRIBUTE_SYSTEM_LE
);
2547 /* get FileAttributes from XATTR_NAME_DOS_ATTRIBUTE */
2548 if (!test_share_config_flag(tcon
->share_conf
,
2549 KSMBD_SHARE_FLAG_STORE_DOS_ATTRS
))
2552 rc
= ksmbd_vfs_get_dos_attrib_xattr(mnt_idmap(path
->mnt
),
2555 fp
->f_ci
->m_fattr
= cpu_to_le32(da
.attr
);
2556 fp
->create_time
= da
.create_time
;
2557 fp
->itime
= da
.itime
;
2561 static int smb2_creat(struct ksmbd_work
*work
, struct path
*parent_path
,
2562 struct path
*path
, char *name
, int open_flags
,
2563 umode_t posix_mode
, bool is_dir
)
2565 struct ksmbd_tree_connect
*tcon
= work
->tcon
;
2566 struct ksmbd_share_config
*share
= tcon
->share_conf
;
2570 if (!(open_flags
& O_CREAT
))
2573 ksmbd_debug(SMB
, "file does not exist, so creating\n");
2574 if (is_dir
== true) {
2575 ksmbd_debug(SMB
, "creating directory\n");
2577 mode
= share_config_directory_mode(share
, posix_mode
);
2578 rc
= ksmbd_vfs_mkdir(work
, name
, mode
);
2582 ksmbd_debug(SMB
, "creating regular file\n");
2584 mode
= share_config_create_mode(share
, posix_mode
);
2585 rc
= ksmbd_vfs_create(work
, name
, mode
);
2590 rc
= ksmbd_vfs_kern_path_locked(work
, name
, 0, parent_path
, path
, 0);
2592 pr_err("cannot get linux path (%s), err = %d\n",
2599 static int smb2_create_sd_buffer(struct ksmbd_work
*work
,
2600 struct smb2_create_req
*req
,
2601 const struct path
*path
)
2603 struct create_context
*context
;
2604 struct create_sd_buf_req
*sd_buf
;
2606 if (!req
->CreateContextsOffset
)
2609 /* Parse SD BUFFER create contexts */
2610 context
= smb2_find_context_vals(req
, SMB2_CREATE_SD_BUFFER
, 4);
2613 else if (IS_ERR(context
))
2614 return PTR_ERR(context
);
2617 "Set ACLs using SMB2_CREATE_SD_BUFFER context\n");
2618 sd_buf
= (struct create_sd_buf_req
*)context
;
2619 if (le16_to_cpu(context
->DataOffset
) +
2620 le32_to_cpu(context
->DataLength
) <
2621 sizeof(struct create_sd_buf_req
))
2623 return set_info_sec(work
->conn
, work
->tcon
, path
, &sd_buf
->ntsd
,
2624 le32_to_cpu(sd_buf
->ccontext
.DataLength
), true, false);
2627 static void ksmbd_acls_fattr(struct smb_fattr
*fattr
,
2628 struct mnt_idmap
*idmap
,
2629 struct inode
*inode
)
2631 vfsuid_t vfsuid
= i_uid_into_vfsuid(idmap
, inode
);
2632 vfsgid_t vfsgid
= i_gid_into_vfsgid(idmap
, inode
);
2634 fattr
->cf_uid
= vfsuid_into_kuid(vfsuid
);
2635 fattr
->cf_gid
= vfsgid_into_kgid(vfsgid
);
2636 fattr
->cf_mode
= inode
->i_mode
;
2637 fattr
->cf_acls
= NULL
;
2638 fattr
->cf_dacls
= NULL
;
2640 if (IS_ENABLED(CONFIG_FS_POSIX_ACL
)) {
2641 fattr
->cf_acls
= get_inode_acl(inode
, ACL_TYPE_ACCESS
);
2642 if (S_ISDIR(inode
->i_mode
))
2643 fattr
->cf_dacls
= get_inode_acl(inode
, ACL_TYPE_DEFAULT
);
2648 DURABLE_RECONN_V2
= 1,
2654 struct durable_info
{
2655 struct ksmbd_file
*fp
;
2656 unsigned short int type
;
2659 unsigned int timeout
;
2663 static int parse_durable_handle_context(struct ksmbd_work
*work
,
2664 struct smb2_create_req
*req
,
2665 struct lease_ctx_info
*lc
,
2666 struct durable_info
*dh_info
)
2668 struct ksmbd_conn
*conn
= work
->conn
;
2669 struct create_context
*context
;
2670 int dh_idx
, err
= 0;
2671 u64 persistent_id
= 0;
2673 static const char * const durable_arr
[] = {"DH2C", "DHnC", "DH2Q", "DHnQ"};
2675 req_op_level
= req
->RequestedOplockLevel
;
2676 for (dh_idx
= DURABLE_RECONN_V2
; dh_idx
<= ARRAY_SIZE(durable_arr
);
2678 context
= smb2_find_context_vals(req
, durable_arr
[dh_idx
- 1], 4);
2679 if (IS_ERR(context
)) {
2680 err
= PTR_ERR(context
);
2687 case DURABLE_RECONN_V2
:
2689 struct create_durable_reconn_v2_req
*recon_v2
;
2691 if (dh_info
->type
== DURABLE_RECONN
||
2692 dh_info
->type
== DURABLE_REQ_V2
) {
2697 recon_v2
= (struct create_durable_reconn_v2_req
*)context
;
2698 persistent_id
= recon_v2
->Fid
.PersistentFileId
;
2699 dh_info
->fp
= ksmbd_lookup_durable_fd(persistent_id
);
2701 ksmbd_debug(SMB
, "Failed to get durable handle state\n");
2706 if (memcmp(dh_info
->fp
->create_guid
, recon_v2
->CreateGuid
,
2707 SMB2_CREATE_GUID_SIZE
)) {
2709 ksmbd_put_durable_fd(dh_info
->fp
);
2713 dh_info
->type
= dh_idx
;
2714 dh_info
->reconnected
= true;
2716 "reconnect v2 Persistent-id from reconnect = %llu\n",
2720 case DURABLE_RECONN
:
2722 struct create_durable_reconn_req
*recon
;
2724 if (dh_info
->type
== DURABLE_RECONN_V2
||
2725 dh_info
->type
== DURABLE_REQ_V2
) {
2730 recon
= (struct create_durable_reconn_req
*)context
;
2731 persistent_id
= recon
->Data
.Fid
.PersistentFileId
;
2732 dh_info
->fp
= ksmbd_lookup_durable_fd(persistent_id
);
2734 ksmbd_debug(SMB
, "Failed to get durable handle state\n");
2739 dh_info
->type
= dh_idx
;
2740 dh_info
->reconnected
= true;
2741 ksmbd_debug(SMB
, "reconnect Persistent-id from reconnect = %llu\n",
2745 case DURABLE_REQ_V2
:
2747 struct create_durable_req_v2
*durable_v2_blob
;
2749 if (dh_info
->type
== DURABLE_RECONN
||
2750 dh_info
->type
== DURABLE_RECONN_V2
) {
2756 (struct create_durable_req_v2
*)context
;
2757 ksmbd_debug(SMB
, "Request for durable v2 open\n");
2758 dh_info
->fp
= ksmbd_lookup_fd_cguid(durable_v2_blob
->CreateGuid
);
2760 if (!memcmp(conn
->ClientGUID
, dh_info
->fp
->client_guid
,
2761 SMB2_CLIENT_GUID_SIZE
)) {
2762 if (!(req
->hdr
.Flags
& SMB2_FLAGS_REPLAY_OPERATION
)) {
2767 dh_info
->fp
->conn
= conn
;
2768 dh_info
->reconnected
= true;
2773 if ((lc
&& (lc
->req_state
& SMB2_LEASE_HANDLE_CACHING_LE
)) ||
2774 req_op_level
== SMB2_OPLOCK_LEVEL_BATCH
) {
2775 dh_info
->CreateGuid
=
2776 durable_v2_blob
->CreateGuid
;
2777 dh_info
->persistent
=
2778 le32_to_cpu(durable_v2_blob
->Flags
);
2780 le32_to_cpu(durable_v2_blob
->Timeout
);
2781 dh_info
->type
= dh_idx
;
2786 if (dh_info
->type
== DURABLE_RECONN
)
2788 if (dh_info
->type
== DURABLE_RECONN_V2
||
2789 dh_info
->type
== DURABLE_REQ_V2
) {
2794 if ((lc
&& (lc
->req_state
& SMB2_LEASE_HANDLE_CACHING_LE
)) ||
2795 req_op_level
== SMB2_OPLOCK_LEVEL_BATCH
) {
2796 ksmbd_debug(SMB
, "Request for durable open\n");
2797 dh_info
->type
= dh_idx
;
2807 * smb2_open() - handler for smb file open request
2808 * @work: smb work containing request buffer
2810 * Return: 0 on success, otherwise error
2812 int smb2_open(struct ksmbd_work
*work
)
2814 struct ksmbd_conn
*conn
= work
->conn
;
2815 struct ksmbd_session
*sess
= work
->sess
;
2816 struct ksmbd_tree_connect
*tcon
= work
->tcon
;
2817 struct smb2_create_req
*req
;
2818 struct smb2_create_rsp
*rsp
;
2819 struct path path
, parent_path
;
2820 struct ksmbd_share_config
*share
= tcon
->share_conf
;
2821 struct ksmbd_file
*fp
= NULL
;
2822 struct file
*filp
= NULL
;
2823 struct mnt_idmap
*idmap
= NULL
;
2825 struct create_context
*context
;
2826 struct lease_ctx_info
*lc
= NULL
;
2827 struct create_ea_buf_req
*ea_buf
= NULL
;
2828 struct oplock_info
*opinfo
;
2829 struct durable_info dh_info
= {0};
2830 __le32
*next_ptr
= NULL
;
2831 int req_op_level
= 0, open_flags
= 0, may_flags
= 0, file_info
= 0;
2833 int contxt_cnt
= 0, query_disk_id
= 0;
2834 int maximal_access_ctxt
= 0, posix_ctxt
= 0;
2838 char *stream_name
= NULL
;
2839 bool file_present
= false, created
= false, already_permitted
= false;
2840 int share_ret
, need_truncate
= 0;
2842 umode_t posix_mode
= 0;
2843 __le32 daccess
, maximal_access
= 0;
2846 WORK_BUFFERS(work
, req
, rsp
);
2848 if (req
->hdr
.NextCommand
&& !work
->next_smb2_rcv_hdr_off
&&
2849 (req
->hdr
.Flags
& SMB2_FLAGS_RELATED_OPERATIONS
)) {
2850 ksmbd_debug(SMB
, "invalid flag in chained command\n");
2851 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
2852 smb2_set_err_rsp(work
);
2856 if (test_share_config_flag(share
, KSMBD_SHARE_FLAG_PIPE
)) {
2857 ksmbd_debug(SMB
, "IPC pipe create request\n");
2858 return create_smb2_pipe(work
);
2861 if (req
->NameLength
) {
2862 name
= smb2_get_name((char *)req
+ le16_to_cpu(req
->NameOffset
),
2863 le16_to_cpu(req
->NameLength
),
2864 work
->conn
->local_nls
);
2871 ksmbd_debug(SMB
, "converted name = %s\n", name
);
2872 if (strchr(name
, ':')) {
2873 if (!test_share_config_flag(work
->tcon
->share_conf
,
2874 KSMBD_SHARE_FLAG_STREAMS
)) {
2878 rc
= parse_stream_name(name
, &stream_name
, &s_type
);
2883 rc
= ksmbd_validate_filename(name
);
2887 if (ksmbd_share_veto_filename(share
, name
)) {
2889 ksmbd_debug(SMB
, "Reject open(), vetoed file: %s\n",
2894 name
= kstrdup("", GFP_KERNEL
);
2901 req_op_level
= req
->RequestedOplockLevel
;
2903 if (server_conf
.flags
& KSMBD_GLOBAL_FLAG_DURABLE_HANDLE
&&
2904 req
->CreateContextsOffset
) {
2905 lc
= parse_lease_state(req
);
2906 rc
= parse_durable_handle_context(work
, req
, lc
, &dh_info
);
2908 ksmbd_debug(SMB
, "error parsing durable handle context\n");
2912 if (dh_info
.reconnected
== true) {
2913 rc
= smb2_check_durable_oplock(conn
, share
, dh_info
.fp
, lc
, name
);
2915 ksmbd_put_durable_fd(dh_info
.fp
);
2919 rc
= ksmbd_reopen_durable_fd(work
, dh_info
.fp
);
2921 ksmbd_put_durable_fd(dh_info
.fp
);
2925 if (ksmbd_override_fsids(work
)) {
2927 ksmbd_put_durable_fd(dh_info
.fp
);
2932 file_info
= FILE_OPENED
;
2934 rc
= ksmbd_vfs_getattr(&fp
->filp
->f_path
, &stat
);
2938 ksmbd_put_durable_fd(fp
);
2939 goto reconnected_fp
;
2941 } else if (req_op_level
== SMB2_OPLOCK_LEVEL_LEASE
)
2942 lc
= parse_lease_state(req
);
2944 if (le32_to_cpu(req
->ImpersonationLevel
) > le32_to_cpu(IL_DELEGATE
)) {
2945 pr_err("Invalid impersonationlevel : 0x%x\n",
2946 le32_to_cpu(req
->ImpersonationLevel
));
2948 rsp
->hdr
.Status
= STATUS_BAD_IMPERSONATION_LEVEL
;
2952 if (req
->CreateOptions
&& !(req
->CreateOptions
& CREATE_OPTIONS_MASK_LE
)) {
2953 pr_err("Invalid create options : 0x%x\n",
2954 le32_to_cpu(req
->CreateOptions
));
2958 if (req
->CreateOptions
& FILE_SEQUENTIAL_ONLY_LE
&&
2959 req
->CreateOptions
& FILE_RANDOM_ACCESS_LE
)
2960 req
->CreateOptions
= ~(FILE_SEQUENTIAL_ONLY_LE
);
2962 if (req
->CreateOptions
&
2963 (FILE_OPEN_BY_FILE_ID_LE
| CREATE_TREE_CONNECTION
|
2964 FILE_RESERVE_OPFILTER_LE
)) {
2969 if (req
->CreateOptions
& FILE_DIRECTORY_FILE_LE
) {
2970 if (req
->CreateOptions
& FILE_NON_DIRECTORY_FILE_LE
) {
2973 } else if (req
->CreateOptions
& FILE_NO_COMPRESSION_LE
) {
2974 req
->CreateOptions
= ~(FILE_NO_COMPRESSION_LE
);
2979 if (le32_to_cpu(req
->CreateDisposition
) >
2980 le32_to_cpu(FILE_OVERWRITE_IF_LE
)) {
2981 pr_err("Invalid create disposition : 0x%x\n",
2982 le32_to_cpu(req
->CreateDisposition
));
2987 if (!(req
->DesiredAccess
& DESIRED_ACCESS_MASK
)) {
2988 pr_err("Invalid desired access : 0x%x\n",
2989 le32_to_cpu(req
->DesiredAccess
));
2994 if (req
->FileAttributes
&& !(req
->FileAttributes
& FILE_ATTRIBUTE_MASK_LE
)) {
2995 pr_err("Invalid file attribute : 0x%x\n",
2996 le32_to_cpu(req
->FileAttributes
));
3001 if (req
->CreateContextsOffset
) {
3002 /* Parse non-durable handle create contexts */
3003 context
= smb2_find_context_vals(req
, SMB2_CREATE_EA_BUFFER
, 4);
3004 if (IS_ERR(context
)) {
3005 rc
= PTR_ERR(context
);
3007 } else if (context
) {
3008 ea_buf
= (struct create_ea_buf_req
*)context
;
3009 if (le16_to_cpu(context
->DataOffset
) +
3010 le32_to_cpu(context
->DataLength
) <
3011 sizeof(struct create_ea_buf_req
)) {
3015 if (req
->CreateOptions
& FILE_NO_EA_KNOWLEDGE_LE
) {
3016 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
3022 context
= smb2_find_context_vals(req
,
3023 SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST
, 4);
3024 if (IS_ERR(context
)) {
3025 rc
= PTR_ERR(context
);
3027 } else if (context
) {
3029 "get query maximal access context\n");
3030 maximal_access_ctxt
= 1;
3033 context
= smb2_find_context_vals(req
,
3034 SMB2_CREATE_TIMEWARP_REQUEST
, 4);
3035 if (IS_ERR(context
)) {
3036 rc
= PTR_ERR(context
);
3038 } else if (context
) {
3039 ksmbd_debug(SMB
, "get timewarp context\n");
3044 if (tcon
->posix_extensions
) {
3045 context
= smb2_find_context_vals(req
,
3046 SMB2_CREATE_TAG_POSIX
, 16);
3047 if (IS_ERR(context
)) {
3048 rc
= PTR_ERR(context
);
3050 } else if (context
) {
3051 struct create_posix
*posix
=
3052 (struct create_posix
*)context
;
3053 if (le16_to_cpu(context
->DataOffset
) +
3054 le32_to_cpu(context
->DataLength
) <
3055 sizeof(struct create_posix
) - 4) {
3059 ksmbd_debug(SMB
, "get posix context\n");
3061 posix_mode
= le32_to_cpu(posix
->Mode
);
3067 if (ksmbd_override_fsids(work
)) {
3072 rc
= ksmbd_vfs_kern_path_locked(work
, name
, LOOKUP_NO_SYMLINKS
,
3073 &parent_path
, &path
, 1);
3075 file_present
= true;
3077 if (req
->CreateOptions
& FILE_DELETE_ON_CLOSE_LE
) {
3079 * If file exists with under flags, return access
3082 if (req
->CreateDisposition
== FILE_OVERWRITE_IF_LE
||
3083 req
->CreateDisposition
== FILE_OPEN_IF_LE
) {
3088 if (!test_tree_conn_flag(tcon
, KSMBD_TREE_CONN_FLAG_WRITABLE
)) {
3090 "User does not have write permission\n");
3094 } else if (d_is_symlink(path
.dentry
)) {
3099 idmap
= mnt_idmap(path
.mnt
);
3103 ksmbd_debug(SMB
, "can not get linux path for %s, rc = %d\n",
3109 if (req
->CreateOptions
& FILE_DIRECTORY_FILE_LE
) {
3110 if (s_type
== DATA_STREAM
) {
3112 rsp
->hdr
.Status
= STATUS_NOT_A_DIRECTORY
;
3115 if (file_present
&& S_ISDIR(d_inode(path
.dentry
)->i_mode
) &&
3116 s_type
== DATA_STREAM
) {
3118 rsp
->hdr
.Status
= STATUS_FILE_IS_A_DIRECTORY
;
3122 if (req
->CreateOptions
& FILE_DIRECTORY_FILE_LE
&&
3123 req
->FileAttributes
& FILE_ATTRIBUTE_NORMAL_LE
) {
3124 rsp
->hdr
.Status
= STATUS_NOT_A_DIRECTORY
;
3132 if (file_present
&& req
->CreateOptions
& FILE_NON_DIRECTORY_FILE_LE
&&
3133 S_ISDIR(d_inode(path
.dentry
)->i_mode
) &&
3134 !(req
->CreateOptions
& FILE_DELETE_ON_CLOSE_LE
)) {
3135 ksmbd_debug(SMB
, "open() argument is a directory: %s, %x\n",
3136 name
, req
->CreateOptions
);
3137 rsp
->hdr
.Status
= STATUS_FILE_IS_A_DIRECTORY
;
3142 if (file_present
&& (req
->CreateOptions
& FILE_DIRECTORY_FILE_LE
) &&
3143 !(req
->CreateDisposition
== FILE_CREATE_LE
) &&
3144 !S_ISDIR(d_inode(path
.dentry
)->i_mode
)) {
3145 rsp
->hdr
.Status
= STATUS_NOT_A_DIRECTORY
;
3150 if (!stream_name
&& file_present
&&
3151 req
->CreateDisposition
== FILE_CREATE_LE
) {
3156 daccess
= smb_map_generic_desired_access(req
->DesiredAccess
);
3158 if (file_present
&& !(req
->CreateOptions
& FILE_DELETE_ON_CLOSE_LE
)) {
3159 rc
= smb_check_perm_dacl(conn
, &path
, &daccess
,
3165 if (daccess
& FILE_MAXIMAL_ACCESS_LE
) {
3166 if (!file_present
) {
3167 daccess
= cpu_to_le32(GENERIC_ALL_FLAGS
);
3169 ksmbd_vfs_query_maximal_access(idmap
,
3172 already_permitted
= true;
3174 maximal_access
= daccess
;
3177 open_flags
= smb2_create_open_flags(file_present
, daccess
,
3178 req
->CreateDisposition
,
3181 file_present
? d_inode(path
.dentry
)->i_mode
: 0);
3183 if (!test_tree_conn_flag(tcon
, KSMBD_TREE_CONN_FLAG_WRITABLE
)) {
3184 if (open_flags
& (O_CREAT
| O_TRUNC
)) {
3186 "User does not have write permission\n");
3192 /*create file if not present */
3193 if (!file_present
) {
3194 rc
= smb2_creat(work
, &parent_path
, &path
, name
, open_flags
,
3196 req
->CreateOptions
& FILE_DIRECTORY_FILE_LE
);
3198 if (rc
== -ENOENT
) {
3200 rsp
->hdr
.Status
= STATUS_OBJECT_PATH_NOT_FOUND
;
3206 idmap
= mnt_idmap(path
.mnt
);
3208 if (le32_to_cpu(ea_buf
->ccontext
.DataLength
) <
3209 sizeof(struct smb2_ea_info
)) {
3214 rc
= smb2_set_ea(&ea_buf
->ea
,
3215 le32_to_cpu(ea_buf
->ccontext
.DataLength
),
3217 if (rc
== -EOPNOTSUPP
)
3222 } else if (!already_permitted
) {
3223 /* FILE_READ_ATTRIBUTE is allowed without inode_permission,
3224 * because execute(search) permission on a parent directory,
3225 * is already granted.
3227 if (daccess
& ~(FILE_READ_ATTRIBUTES_LE
| FILE_READ_CONTROL_LE
)) {
3228 rc
= inode_permission(idmap
,
3229 d_inode(path
.dentry
),
3234 if ((daccess
& FILE_DELETE_LE
) ||
3235 (req
->CreateOptions
& FILE_DELETE_ON_CLOSE_LE
)) {
3236 rc
= inode_permission(idmap
,
3237 d_inode(path
.dentry
->d_parent
),
3238 MAY_EXEC
| MAY_WRITE
);
3245 rc
= ksmbd_query_inode_status(path
.dentry
->d_parent
);
3246 if (rc
== KSMBD_INODE_STATUS_PENDING_DELETE
) {
3252 filp
= dentry_open(&path
, open_flags
, current_cred());
3255 pr_err("dentry open for dir failed, rc %d\n", rc
);
3260 if (!(open_flags
& O_TRUNC
))
3261 file_info
= FILE_OPENED
;
3263 file_info
= FILE_OVERWRITTEN
;
3265 if ((req
->CreateDisposition
& FILE_CREATE_MASK_LE
) ==
3267 file_info
= FILE_SUPERSEDED
;
3268 } else if (open_flags
& O_CREAT
) {
3269 file_info
= FILE_CREATED
;
3272 ksmbd_vfs_set_fadvise(filp
, req
->CreateOptions
);
3274 /* Obtain Volatile-ID */
3275 fp
= ksmbd_open_fd(work
, filp
);
3283 /* Get Persistent-ID */
3284 ksmbd_open_durable_fd(fp
);
3285 if (!has_file_id(fp
->persistent_id
)) {
3290 fp
->cdoption
= req
->CreateDisposition
;
3291 fp
->daccess
= daccess
;
3292 fp
->saccess
= req
->ShareAccess
;
3293 fp
->coption
= req
->CreateOptions
;
3295 /* Set default windows and posix acls if creating new file */
3298 struct inode
*inode
= d_inode(path
.dentry
);
3300 posix_acl_rc
= ksmbd_vfs_inherit_posix_acl(idmap
,
3302 d_inode(path
.dentry
->d_parent
));
3304 ksmbd_debug(SMB
, "inherit posix acl failed : %d\n", posix_acl_rc
);
3306 if (test_share_config_flag(work
->tcon
->share_conf
,
3307 KSMBD_SHARE_FLAG_ACL_XATTR
)) {
3308 rc
= smb_inherit_dacl(conn
, &path
, sess
->user
->uid
,
3313 rc
= smb2_create_sd_buffer(work
, req
, &path
);
3316 ksmbd_vfs_set_init_posix_acl(idmap
,
3319 if (test_share_config_flag(work
->tcon
->share_conf
,
3320 KSMBD_SHARE_FLAG_ACL_XATTR
)) {
3321 struct smb_fattr fattr
;
3322 struct smb_ntsd
*pntsd
;
3323 int pntsd_size
, ace_num
= 0;
3325 ksmbd_acls_fattr(&fattr
, idmap
, inode
);
3327 ace_num
= fattr
.cf_acls
->a_count
;
3329 ace_num
+= fattr
.cf_dacls
->a_count
;
3331 pntsd
= kmalloc(sizeof(struct smb_ntsd
) +
3332 sizeof(struct smb_sid
) * 3 +
3333 sizeof(struct smb_acl
) +
3334 sizeof(struct smb_ace
) * ace_num
* 2,
3337 posix_acl_release(fattr
.cf_acls
);
3338 posix_acl_release(fattr
.cf_dacls
);
3342 rc
= build_sec_desc(idmap
,
3347 &pntsd_size
, &fattr
);
3348 posix_acl_release(fattr
.cf_acls
);
3349 posix_acl_release(fattr
.cf_dacls
);
3355 rc
= ksmbd_vfs_set_sd_xattr(conn
,
3363 pr_err("failed to store ntacl in xattr : %d\n",
3372 rc
= smb2_set_stream_name_xattr(&path
,
3378 file_info
= FILE_CREATED
;
3381 fp
->attrib_only
= !(req
->DesiredAccess
& ~(FILE_READ_ATTRIBUTES_LE
|
3382 FILE_WRITE_ATTRIBUTES_LE
| FILE_SYNCHRONIZE_LE
));
3384 /* fp should be searchable through ksmbd_inode.m_fp_list
3385 * after daccess, saccess, attrib_only, and stream are
3388 down_write(&fp
->f_ci
->m_lock
);
3389 list_add(&fp
->node
, &fp
->f_ci
->m_fp_list
);
3390 up_write(&fp
->f_ci
->m_lock
);
3392 /* Check delete pending among previous fp before oplock break */
3393 if (ksmbd_inode_pending_delete(fp
)) {
3398 if (file_present
|| created
)
3399 ksmbd_vfs_kern_path_unlock(&parent_path
, &path
);
3401 if (!S_ISDIR(file_inode(filp
)->i_mode
) && open_flags
& O_TRUNC
&&
3402 !fp
->attrib_only
&& !stream_name
) {
3403 smb_break_all_oplock(work
, fp
);
3407 share_ret
= ksmbd_smb_check_shared_mode(fp
->filp
, fp
);
3408 if (!test_share_config_flag(work
->tcon
->share_conf
, KSMBD_SHARE_FLAG_OPLOCKS
) ||
3409 (req_op_level
== SMB2_OPLOCK_LEVEL_LEASE
&&
3410 !(conn
->vals
->capabilities
& SMB2_GLOBAL_CAP_LEASING
))) {
3411 if (share_ret
< 0 && !S_ISDIR(file_inode(fp
->filp
)->i_mode
)) {
3416 if (req_op_level
== SMB2_OPLOCK_LEVEL_LEASE
&& lc
) {
3417 if (S_ISDIR(file_inode(filp
)->i_mode
)) {
3418 lc
->req_state
&= ~SMB2_LEASE_WRITE_CACHING_LE
;
3423 * Compare parent lease using parent key. If there is no
3424 * a lease that has same parent key, Send lease break
3427 smb_send_parent_lease_break_noti(fp
, lc
);
3429 req_op_level
= smb2_map_lease_to_oplock(lc
->req_state
);
3431 "lease req for(%s) req oplock state 0x%x, lease state 0x%x\n",
3432 name
, req_op_level
, lc
->req_state
);
3433 rc
= find_same_lease_key(sess
, fp
->f_ci
, lc
);
3436 } else if (open_flags
== O_RDONLY
&&
3437 (req_op_level
== SMB2_OPLOCK_LEVEL_BATCH
||
3438 req_op_level
== SMB2_OPLOCK_LEVEL_EXCLUSIVE
))
3439 req_op_level
= SMB2_OPLOCK_LEVEL_II
;
3441 rc
= smb_grant_oplock(work
, req_op_level
,
3442 fp
->persistent_id
, fp
,
3443 le32_to_cpu(req
->hdr
.Id
.SyncId
.TreeId
),
3449 if (req
->CreateOptions
& FILE_DELETE_ON_CLOSE_LE
)
3450 ksmbd_fd_set_delete_on_close(fp
, file_info
);
3452 if (need_truncate
) {
3453 rc
= smb2_create_truncate(&fp
->filp
->f_path
);
3458 if (req
->CreateContextsOffset
) {
3459 struct create_alloc_size_req
*az_req
;
3461 az_req
= (struct create_alloc_size_req
*)smb2_find_context_vals(req
,
3462 SMB2_CREATE_ALLOCATION_SIZE
, 4);
3463 if (IS_ERR(az_req
)) {
3464 rc
= PTR_ERR(az_req
);
3466 } else if (az_req
) {
3470 if (le16_to_cpu(az_req
->ccontext
.DataOffset
) +
3471 le32_to_cpu(az_req
->ccontext
.DataLength
) <
3472 sizeof(struct create_alloc_size_req
)) {
3476 alloc_size
= le64_to_cpu(az_req
->AllocationSize
);
3478 "request smb2 create allocate size : %llu\n",
3480 smb_break_all_levII_oplock(work
, fp
, 1);
3481 err
= vfs_fallocate(fp
->filp
, FALLOC_FL_KEEP_SIZE
, 0,
3485 "vfs_fallocate is failed : %d\n",
3489 context
= smb2_find_context_vals(req
, SMB2_CREATE_QUERY_ON_DISK_ID
, 4);
3490 if (IS_ERR(context
)) {
3491 rc
= PTR_ERR(context
);
3493 } else if (context
) {
3494 ksmbd_debug(SMB
, "get query on disk id context\n");
3499 rc
= ksmbd_vfs_getattr(&path
, &stat
);
3503 if (stat
.result_mask
& STATX_BTIME
)
3504 fp
->create_time
= ksmbd_UnixTimeToNT(stat
.btime
);
3506 fp
->create_time
= ksmbd_UnixTimeToNT(stat
.ctime
);
3507 if (req
->FileAttributes
|| fp
->f_ci
->m_fattr
== 0)
3509 cpu_to_le32(smb2_get_dos_mode(&stat
, le32_to_cpu(req
->FileAttributes
)));
3512 smb2_update_xattrs(tcon
, &path
, fp
);
3514 smb2_new_xattrs(tcon
, &path
, fp
);
3516 memcpy(fp
->client_guid
, conn
->ClientGUID
, SMB2_CLIENT_GUID_SIZE
);
3518 if (dh_info
.type
== DURABLE_REQ_V2
|| dh_info
.type
== DURABLE_REQ
) {
3519 if (dh_info
.type
== DURABLE_REQ_V2
&& dh_info
.persistent
&&
3520 test_share_config_flag(work
->tcon
->share_conf
,
3521 KSMBD_SHARE_FLAG_CONTINUOUS_AVAILABILITY
))
3522 fp
->is_persistent
= true;
3524 fp
->is_durable
= true;
3526 if (dh_info
.type
== DURABLE_REQ_V2
) {
3527 memcpy(fp
->create_guid
, dh_info
.CreateGuid
,
3528 SMB2_CREATE_GUID_SIZE
);
3529 if (dh_info
.timeout
)
3530 fp
->durable_timeout
=
3531 min_t(unsigned int, dh_info
.timeout
,
3532 DURABLE_HANDLE_MAX_TIMEOUT
);
3534 fp
->durable_timeout
= 60;
3539 rsp
->StructureSize
= cpu_to_le16(89);
3541 opinfo
= rcu_dereference(fp
->f_opinfo
);
3542 rsp
->OplockLevel
= opinfo
!= NULL
? opinfo
->level
: 0;
3545 rsp
->CreateAction
= cpu_to_le32(file_info
);
3546 rsp
->CreationTime
= cpu_to_le64(fp
->create_time
);
3547 time
= ksmbd_UnixTimeToNT(stat
.atime
);
3548 rsp
->LastAccessTime
= cpu_to_le64(time
);
3549 time
= ksmbd_UnixTimeToNT(stat
.mtime
);
3550 rsp
->LastWriteTime
= cpu_to_le64(time
);
3551 time
= ksmbd_UnixTimeToNT(stat
.ctime
);
3552 rsp
->ChangeTime
= cpu_to_le64(time
);
3553 rsp
->AllocationSize
= S_ISDIR(stat
.mode
) ? 0 :
3554 cpu_to_le64(stat
.blocks
<< 9);
3555 rsp
->EndofFile
= S_ISDIR(stat
.mode
) ? 0 : cpu_to_le64(stat
.size
);
3556 rsp
->FileAttributes
= fp
->f_ci
->m_fattr
;
3560 rsp
->PersistentFileId
= fp
->persistent_id
;
3561 rsp
->VolatileFileId
= fp
->volatile_id
;
3563 rsp
->CreateContextsOffset
= 0;
3564 rsp
->CreateContextsLength
= 0;
3565 iov_len
= offsetof(struct smb2_create_rsp
, Buffer
);
3567 /* If lease is request send lease context response */
3568 if (opinfo
&& opinfo
->is_lease
) {
3569 struct create_context
*lease_ccontext
;
3571 ksmbd_debug(SMB
, "lease granted on(%s) lease state 0x%x\n",
3572 name
, opinfo
->o_lease
->state
);
3573 rsp
->OplockLevel
= SMB2_OPLOCK_LEVEL_LEASE
;
3575 lease_ccontext
= (struct create_context
*)rsp
->Buffer
;
3577 create_lease_buf(rsp
->Buffer
, opinfo
->o_lease
);
3578 le32_add_cpu(&rsp
->CreateContextsLength
,
3579 conn
->vals
->create_lease_size
);
3580 iov_len
+= conn
->vals
->create_lease_size
;
3581 next_ptr
= &lease_ccontext
->Next
;
3582 next_off
= conn
->vals
->create_lease_size
;
3585 if (maximal_access_ctxt
) {
3586 struct create_context
*mxac_ccontext
;
3588 if (maximal_access
== 0)
3589 ksmbd_vfs_query_maximal_access(idmap
,
3592 mxac_ccontext
= (struct create_context
*)(rsp
->Buffer
+
3593 le32_to_cpu(rsp
->CreateContextsLength
));
3595 create_mxac_rsp_buf(rsp
->Buffer
+
3596 le32_to_cpu(rsp
->CreateContextsLength
),
3597 le32_to_cpu(maximal_access
));
3598 le32_add_cpu(&rsp
->CreateContextsLength
,
3599 conn
->vals
->create_mxac_size
);
3600 iov_len
+= conn
->vals
->create_mxac_size
;
3602 *next_ptr
= cpu_to_le32(next_off
);
3603 next_ptr
= &mxac_ccontext
->Next
;
3604 next_off
= conn
->vals
->create_mxac_size
;
3607 if (query_disk_id
) {
3608 struct create_context
*disk_id_ccontext
;
3610 disk_id_ccontext
= (struct create_context
*)(rsp
->Buffer
+
3611 le32_to_cpu(rsp
->CreateContextsLength
));
3613 create_disk_id_rsp_buf(rsp
->Buffer
+
3614 le32_to_cpu(rsp
->CreateContextsLength
),
3615 stat
.ino
, tcon
->id
);
3616 le32_add_cpu(&rsp
->CreateContextsLength
,
3617 conn
->vals
->create_disk_id_size
);
3618 iov_len
+= conn
->vals
->create_disk_id_size
;
3620 *next_ptr
= cpu_to_le32(next_off
);
3621 next_ptr
= &disk_id_ccontext
->Next
;
3622 next_off
= conn
->vals
->create_disk_id_size
;
3625 if (dh_info
.type
== DURABLE_REQ
|| dh_info
.type
== DURABLE_REQ_V2
) {
3626 struct create_context
*durable_ccontext
;
3628 durable_ccontext
= (struct create_context
*)(rsp
->Buffer
+
3629 le32_to_cpu(rsp
->CreateContextsLength
));
3631 if (dh_info
.type
== DURABLE_REQ
) {
3632 create_durable_rsp_buf(rsp
->Buffer
+
3633 le32_to_cpu(rsp
->CreateContextsLength
));
3634 le32_add_cpu(&rsp
->CreateContextsLength
,
3635 conn
->vals
->create_durable_size
);
3636 iov_len
+= conn
->vals
->create_durable_size
;
3638 create_durable_v2_rsp_buf(rsp
->Buffer
+
3639 le32_to_cpu(rsp
->CreateContextsLength
),
3641 le32_add_cpu(&rsp
->CreateContextsLength
,
3642 conn
->vals
->create_durable_v2_size
);
3643 iov_len
+= conn
->vals
->create_durable_v2_size
;
3647 *next_ptr
= cpu_to_le32(next_off
);
3648 next_ptr
= &durable_ccontext
->Next
;
3649 next_off
= conn
->vals
->create_durable_size
;
3654 create_posix_rsp_buf(rsp
->Buffer
+
3655 le32_to_cpu(rsp
->CreateContextsLength
),
3657 le32_add_cpu(&rsp
->CreateContextsLength
,
3658 conn
->vals
->create_posix_size
);
3659 iov_len
+= conn
->vals
->create_posix_size
;
3661 *next_ptr
= cpu_to_le32(next_off
);
3664 if (contxt_cnt
> 0) {
3665 rsp
->CreateContextsOffset
=
3666 cpu_to_le32(offsetof(struct smb2_create_rsp
, Buffer
));
3670 if (rc
&& (file_present
|| created
))
3671 ksmbd_vfs_kern_path_unlock(&parent_path
, &path
);
3674 ksmbd_revert_fsids(work
);
3678 ksmbd_update_fstate(&work
->sess
->file_table
, fp
, FP_INITED
);
3679 rc
= ksmbd_iov_pin_rsp(work
, (void *)rsp
, iov_len
);
3683 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
3684 else if (rc
== -EOPNOTSUPP
)
3685 rsp
->hdr
.Status
= STATUS_NOT_SUPPORTED
;
3686 else if (rc
== -EACCES
|| rc
== -ESTALE
|| rc
== -EXDEV
)
3687 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
3688 else if (rc
== -ENOENT
)
3689 rsp
->hdr
.Status
= STATUS_OBJECT_NAME_INVALID
;
3690 else if (rc
== -EPERM
)
3691 rsp
->hdr
.Status
= STATUS_SHARING_VIOLATION
;
3692 else if (rc
== -EBUSY
)
3693 rsp
->hdr
.Status
= STATUS_DELETE_PENDING
;
3694 else if (rc
== -EBADF
)
3695 rsp
->hdr
.Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
3696 else if (rc
== -ENOEXEC
)
3697 rsp
->hdr
.Status
= STATUS_DUPLICATE_OBJECTID
;
3698 else if (rc
== -ENXIO
)
3699 rsp
->hdr
.Status
= STATUS_NO_SUCH_DEVICE
;
3700 else if (rc
== -EEXIST
)
3701 rsp
->hdr
.Status
= STATUS_OBJECT_NAME_COLLISION
;
3702 else if (rc
== -EMFILE
)
3703 rsp
->hdr
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
3704 if (!rsp
->hdr
.Status
)
3705 rsp
->hdr
.Status
= STATUS_UNEXPECTED_IO_ERROR
;
3708 ksmbd_fd_put(work
, fp
);
3709 smb2_set_err_rsp(work
);
3710 ksmbd_debug(SMB
, "Error response: %x\n", rsp
->hdr
.Status
);
3719 static int readdir_info_level_struct_sz(int info_level
)
3721 switch (info_level
) {
3722 case FILE_FULL_DIRECTORY_INFORMATION
:
3723 return sizeof(struct file_full_directory_info
);
3724 case FILE_BOTH_DIRECTORY_INFORMATION
:
3725 return sizeof(struct file_both_directory_info
);
3726 case FILE_DIRECTORY_INFORMATION
:
3727 return sizeof(struct file_directory_info
);
3728 case FILE_NAMES_INFORMATION
:
3729 return sizeof(struct file_names_info
);
3730 case FILEID_FULL_DIRECTORY_INFORMATION
:
3731 return sizeof(struct file_id_full_dir_info
);
3732 case FILEID_BOTH_DIRECTORY_INFORMATION
:
3733 return sizeof(struct file_id_both_directory_info
);
3734 case SMB_FIND_FILE_POSIX_INFO
:
3735 return sizeof(struct smb2_posix_info
);
3741 static int dentry_name(struct ksmbd_dir_info
*d_info
, int info_level
)
3743 switch (info_level
) {
3744 case FILE_FULL_DIRECTORY_INFORMATION
:
3746 struct file_full_directory_info
*ffdinfo
;
3748 ffdinfo
= (struct file_full_directory_info
*)d_info
->rptr
;
3749 d_info
->rptr
+= le32_to_cpu(ffdinfo
->NextEntryOffset
);
3750 d_info
->name
= ffdinfo
->FileName
;
3751 d_info
->name_len
= le32_to_cpu(ffdinfo
->FileNameLength
);
3754 case FILE_BOTH_DIRECTORY_INFORMATION
:
3756 struct file_both_directory_info
*fbdinfo
;
3758 fbdinfo
= (struct file_both_directory_info
*)d_info
->rptr
;
3759 d_info
->rptr
+= le32_to_cpu(fbdinfo
->NextEntryOffset
);
3760 d_info
->name
= fbdinfo
->FileName
;
3761 d_info
->name_len
= le32_to_cpu(fbdinfo
->FileNameLength
);
3764 case FILE_DIRECTORY_INFORMATION
:
3766 struct file_directory_info
*fdinfo
;
3768 fdinfo
= (struct file_directory_info
*)d_info
->rptr
;
3769 d_info
->rptr
+= le32_to_cpu(fdinfo
->NextEntryOffset
);
3770 d_info
->name
= fdinfo
->FileName
;
3771 d_info
->name_len
= le32_to_cpu(fdinfo
->FileNameLength
);
3774 case FILE_NAMES_INFORMATION
:
3776 struct file_names_info
*fninfo
;
3778 fninfo
= (struct file_names_info
*)d_info
->rptr
;
3779 d_info
->rptr
+= le32_to_cpu(fninfo
->NextEntryOffset
);
3780 d_info
->name
= fninfo
->FileName
;
3781 d_info
->name_len
= le32_to_cpu(fninfo
->FileNameLength
);
3784 case FILEID_FULL_DIRECTORY_INFORMATION
:
3786 struct file_id_full_dir_info
*dinfo
;
3788 dinfo
= (struct file_id_full_dir_info
*)d_info
->rptr
;
3789 d_info
->rptr
+= le32_to_cpu(dinfo
->NextEntryOffset
);
3790 d_info
->name
= dinfo
->FileName
;
3791 d_info
->name_len
= le32_to_cpu(dinfo
->FileNameLength
);
3794 case FILEID_BOTH_DIRECTORY_INFORMATION
:
3796 struct file_id_both_directory_info
*fibdinfo
;
3798 fibdinfo
= (struct file_id_both_directory_info
*)d_info
->rptr
;
3799 d_info
->rptr
+= le32_to_cpu(fibdinfo
->NextEntryOffset
);
3800 d_info
->name
= fibdinfo
->FileName
;
3801 d_info
->name_len
= le32_to_cpu(fibdinfo
->FileNameLength
);
3804 case SMB_FIND_FILE_POSIX_INFO
:
3806 struct smb2_posix_info
*posix_info
;
3808 posix_info
= (struct smb2_posix_info
*)d_info
->rptr
;
3809 d_info
->rptr
+= le32_to_cpu(posix_info
->NextEntryOffset
);
3810 d_info
->name
= posix_info
->name
;
3811 d_info
->name_len
= le32_to_cpu(posix_info
->name_len
);
3820 * smb2_populate_readdir_entry() - encode directory entry in smb2 response
3822 * @conn: connection instance
3823 * @info_level: smb information level
3824 * @d_info: structure included variables for query dir
3825 * @ksmbd_kstat: ksmbd wrapper of dirent stat information
3827 * if directory has many entries, find first can't read it fully.
3828 * find next might be called multiple times to read remaining dir entries
3830 * Return: 0 on success, otherwise error
3832 static int smb2_populate_readdir_entry(struct ksmbd_conn
*conn
, int info_level
,
3833 struct ksmbd_dir_info
*d_info
,
3834 struct ksmbd_kstat
*ksmbd_kstat
)
3836 int next_entry_offset
= 0;
3840 int struct_sz
, rc
= 0;
3842 conv_name
= ksmbd_convert_dir_info_name(d_info
,
3848 /* Somehow the name has only terminating NULL bytes */
3851 goto free_conv_name
;
3854 struct_sz
= readdir_info_level_struct_sz(info_level
) + conv_len
;
3855 next_entry_offset
= ALIGN(struct_sz
, KSMBD_DIR_INFO_ALIGNMENT
);
3856 d_info
->last_entry_off_align
= next_entry_offset
- struct_sz
;
3858 if (next_entry_offset
> d_info
->out_buf_len
) {
3859 d_info
->out_buf_len
= 0;
3861 goto free_conv_name
;
3864 kstat
= d_info
->wptr
;
3865 if (info_level
!= FILE_NAMES_INFORMATION
)
3866 kstat
= ksmbd_vfs_init_kstat(&d_info
->wptr
, ksmbd_kstat
);
3868 switch (info_level
) {
3869 case FILE_FULL_DIRECTORY_INFORMATION
:
3871 struct file_full_directory_info
*ffdinfo
;
3873 ffdinfo
= (struct file_full_directory_info
*)kstat
;
3874 ffdinfo
->FileNameLength
= cpu_to_le32(conv_len
);
3876 smb2_get_reparse_tag_special_file(ksmbd_kstat
->kstat
->mode
);
3877 if (ffdinfo
->EaSize
)
3878 ffdinfo
->ExtFileAttributes
= FILE_ATTRIBUTE_REPARSE_POINT_LE
;
3879 if (d_info
->hide_dot_file
&& d_info
->name
[0] == '.')
3880 ffdinfo
->ExtFileAttributes
|= FILE_ATTRIBUTE_HIDDEN_LE
;
3881 memcpy(ffdinfo
->FileName
, conv_name
, conv_len
);
3882 ffdinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
3885 case FILE_BOTH_DIRECTORY_INFORMATION
:
3887 struct file_both_directory_info
*fbdinfo
;
3889 fbdinfo
= (struct file_both_directory_info
*)kstat
;
3890 fbdinfo
->FileNameLength
= cpu_to_le32(conv_len
);
3892 smb2_get_reparse_tag_special_file(ksmbd_kstat
->kstat
->mode
);
3893 if (fbdinfo
->EaSize
)
3894 fbdinfo
->ExtFileAttributes
= FILE_ATTRIBUTE_REPARSE_POINT_LE
;
3895 fbdinfo
->ShortNameLength
= 0;
3896 fbdinfo
->Reserved
= 0;
3897 if (d_info
->hide_dot_file
&& d_info
->name
[0] == '.')
3898 fbdinfo
->ExtFileAttributes
|= FILE_ATTRIBUTE_HIDDEN_LE
;
3899 memcpy(fbdinfo
->FileName
, conv_name
, conv_len
);
3900 fbdinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
3903 case FILE_DIRECTORY_INFORMATION
:
3905 struct file_directory_info
*fdinfo
;
3907 fdinfo
= (struct file_directory_info
*)kstat
;
3908 fdinfo
->FileNameLength
= cpu_to_le32(conv_len
);
3909 if (d_info
->hide_dot_file
&& d_info
->name
[0] == '.')
3910 fdinfo
->ExtFileAttributes
|= FILE_ATTRIBUTE_HIDDEN_LE
;
3911 memcpy(fdinfo
->FileName
, conv_name
, conv_len
);
3912 fdinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
3915 case FILE_NAMES_INFORMATION
:
3917 struct file_names_info
*fninfo
;
3919 fninfo
= (struct file_names_info
*)kstat
;
3920 fninfo
->FileNameLength
= cpu_to_le32(conv_len
);
3921 memcpy(fninfo
->FileName
, conv_name
, conv_len
);
3922 fninfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
3925 case FILEID_FULL_DIRECTORY_INFORMATION
:
3927 struct file_id_full_dir_info
*dinfo
;
3929 dinfo
= (struct file_id_full_dir_info
*)kstat
;
3930 dinfo
->FileNameLength
= cpu_to_le32(conv_len
);
3932 smb2_get_reparse_tag_special_file(ksmbd_kstat
->kstat
->mode
);
3934 dinfo
->ExtFileAttributes
= FILE_ATTRIBUTE_REPARSE_POINT_LE
;
3935 dinfo
->Reserved
= 0;
3936 dinfo
->UniqueId
= cpu_to_le64(ksmbd_kstat
->kstat
->ino
);
3937 if (d_info
->hide_dot_file
&& d_info
->name
[0] == '.')
3938 dinfo
->ExtFileAttributes
|= FILE_ATTRIBUTE_HIDDEN_LE
;
3939 memcpy(dinfo
->FileName
, conv_name
, conv_len
);
3940 dinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
3943 case FILEID_BOTH_DIRECTORY_INFORMATION
:
3945 struct file_id_both_directory_info
*fibdinfo
;
3947 fibdinfo
= (struct file_id_both_directory_info
*)kstat
;
3948 fibdinfo
->FileNameLength
= cpu_to_le32(conv_len
);
3950 smb2_get_reparse_tag_special_file(ksmbd_kstat
->kstat
->mode
);
3951 if (fibdinfo
->EaSize
)
3952 fibdinfo
->ExtFileAttributes
= FILE_ATTRIBUTE_REPARSE_POINT_LE
;
3953 fibdinfo
->UniqueId
= cpu_to_le64(ksmbd_kstat
->kstat
->ino
);
3954 fibdinfo
->ShortNameLength
= 0;
3955 fibdinfo
->Reserved
= 0;
3956 fibdinfo
->Reserved2
= cpu_to_le16(0);
3957 if (d_info
->hide_dot_file
&& d_info
->name
[0] == '.')
3958 fibdinfo
->ExtFileAttributes
|= FILE_ATTRIBUTE_HIDDEN_LE
;
3959 memcpy(fibdinfo
->FileName
, conv_name
, conv_len
);
3960 fibdinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
3963 case SMB_FIND_FILE_POSIX_INFO
:
3965 struct smb2_posix_info
*posix_info
;
3968 posix_info
= (struct smb2_posix_info
*)kstat
;
3969 posix_info
->Ignored
= 0;
3970 posix_info
->CreationTime
= cpu_to_le64(ksmbd_kstat
->create_time
);
3971 time
= ksmbd_UnixTimeToNT(ksmbd_kstat
->kstat
->ctime
);
3972 posix_info
->ChangeTime
= cpu_to_le64(time
);
3973 time
= ksmbd_UnixTimeToNT(ksmbd_kstat
->kstat
->atime
);
3974 posix_info
->LastAccessTime
= cpu_to_le64(time
);
3975 time
= ksmbd_UnixTimeToNT(ksmbd_kstat
->kstat
->mtime
);
3976 posix_info
->LastWriteTime
= cpu_to_le64(time
);
3977 posix_info
->EndOfFile
= cpu_to_le64(ksmbd_kstat
->kstat
->size
);
3978 posix_info
->AllocationSize
= cpu_to_le64(ksmbd_kstat
->kstat
->blocks
<< 9);
3979 posix_info
->DeviceId
= cpu_to_le32(ksmbd_kstat
->kstat
->rdev
);
3980 posix_info
->HardLinks
= cpu_to_le32(ksmbd_kstat
->kstat
->nlink
);
3981 posix_info
->Mode
= cpu_to_le32(ksmbd_kstat
->kstat
->mode
& 0777);
3982 posix_info
->Inode
= cpu_to_le64(ksmbd_kstat
->kstat
->ino
);
3983 posix_info
->DosAttributes
=
3984 S_ISDIR(ksmbd_kstat
->kstat
->mode
) ?
3985 FILE_ATTRIBUTE_DIRECTORY_LE
: FILE_ATTRIBUTE_ARCHIVE_LE
;
3986 if (d_info
->hide_dot_file
&& d_info
->name
[0] == '.')
3987 posix_info
->DosAttributes
|= FILE_ATTRIBUTE_HIDDEN_LE
;
3989 * SidBuffer(32) contain two sids(Domain sid(16), UNIX group sid(16)).
3990 * UNIX sid(16) = revision(1) + num_subauth(1) + authority(6) +
3991 * sub_auth(4 * 1(num_subauth)) + RID(4).
3993 id_to_sid(from_kuid_munged(&init_user_ns
, ksmbd_kstat
->kstat
->uid
),
3994 SIDUNIX_USER
, (struct smb_sid
*)&posix_info
->SidBuffer
[0]);
3995 id_to_sid(from_kgid_munged(&init_user_ns
, ksmbd_kstat
->kstat
->gid
),
3996 SIDUNIX_GROUP
, (struct smb_sid
*)&posix_info
->SidBuffer
[16]);
3997 memcpy(posix_info
->name
, conv_name
, conv_len
);
3998 posix_info
->name_len
= cpu_to_le32(conv_len
);
3999 posix_info
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
4003 } /* switch (info_level) */
4005 d_info
->last_entry_offset
= d_info
->data_count
;
4006 d_info
->data_count
+= next_entry_offset
;
4007 d_info
->out_buf_len
-= next_entry_offset
;
4008 d_info
->wptr
+= next_entry_offset
;
4011 "info_level : %d, buf_len :%d, next_offset : %d, data_count : %d\n",
4012 info_level
, d_info
->out_buf_len
,
4013 next_entry_offset
, d_info
->data_count
);
4020 struct smb2_query_dir_private
{
4021 struct ksmbd_work
*work
;
4022 char *search_pattern
;
4023 struct ksmbd_file
*dir_fp
;
4025 struct ksmbd_dir_info
*d_info
;
4029 static void lock_dir(struct ksmbd_file
*dir_fp
)
4031 struct dentry
*dir
= dir_fp
->filp
->f_path
.dentry
;
4033 inode_lock_nested(d_inode(dir
), I_MUTEX_PARENT
);
4036 static void unlock_dir(struct ksmbd_file
*dir_fp
)
4038 struct dentry
*dir
= dir_fp
->filp
->f_path
.dentry
;
4040 inode_unlock(d_inode(dir
));
4043 static int process_query_dir_entries(struct smb2_query_dir_private
*priv
)
4045 struct mnt_idmap
*idmap
= file_mnt_idmap(priv
->dir_fp
->filp
);
4047 struct ksmbd_kstat ksmbd_kstat
;
4051 for (i
= 0; i
< priv
->d_info
->num_entry
; i
++) {
4052 struct dentry
*dent
;
4054 if (dentry_name(priv
->d_info
, priv
->info_level
))
4057 lock_dir(priv
->dir_fp
);
4058 dent
= lookup_one(idmap
, priv
->d_info
->name
,
4059 priv
->dir_fp
->filp
->f_path
.dentry
,
4060 priv
->d_info
->name_len
);
4061 unlock_dir(priv
->dir_fp
);
4064 ksmbd_debug(SMB
, "Cannot lookup `%s' [%ld]\n",
4069 if (unlikely(d_is_negative(dent
))) {
4071 ksmbd_debug(SMB
, "Negative dentry `%s'\n",
4072 priv
->d_info
->name
);
4076 ksmbd_kstat
.kstat
= &kstat
;
4077 if (priv
->info_level
!= FILE_NAMES_INFORMATION
) {
4078 rc
= ksmbd_vfs_fill_dentry_attrs(priv
->work
,
4088 rc
= smb2_populate_readdir_entry(priv
->work
->conn
,
4099 static int reserve_populate_dentry(struct ksmbd_dir_info
*d_info
,
4104 int next_entry_offset
;
4106 struct_sz
= readdir_info_level_struct_sz(info_level
);
4107 if (struct_sz
== -EOPNOTSUPP
)
4110 conv_len
= (d_info
->name_len
+ 1) * 2;
4111 next_entry_offset
= ALIGN(struct_sz
+ conv_len
,
4112 KSMBD_DIR_INFO_ALIGNMENT
);
4114 if (next_entry_offset
> d_info
->out_buf_len
) {
4115 d_info
->out_buf_len
= 0;
4119 switch (info_level
) {
4120 case FILE_FULL_DIRECTORY_INFORMATION
:
4122 struct file_full_directory_info
*ffdinfo
;
4124 ffdinfo
= (struct file_full_directory_info
*)d_info
->wptr
;
4125 memcpy(ffdinfo
->FileName
, d_info
->name
, d_info
->name_len
);
4126 ffdinfo
->FileName
[d_info
->name_len
] = 0x00;
4127 ffdinfo
->FileNameLength
= cpu_to_le32(d_info
->name_len
);
4128 ffdinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
4131 case FILE_BOTH_DIRECTORY_INFORMATION
:
4133 struct file_both_directory_info
*fbdinfo
;
4135 fbdinfo
= (struct file_both_directory_info
*)d_info
->wptr
;
4136 memcpy(fbdinfo
->FileName
, d_info
->name
, d_info
->name_len
);
4137 fbdinfo
->FileName
[d_info
->name_len
] = 0x00;
4138 fbdinfo
->FileNameLength
= cpu_to_le32(d_info
->name_len
);
4139 fbdinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
4142 case FILE_DIRECTORY_INFORMATION
:
4144 struct file_directory_info
*fdinfo
;
4146 fdinfo
= (struct file_directory_info
*)d_info
->wptr
;
4147 memcpy(fdinfo
->FileName
, d_info
->name
, d_info
->name_len
);
4148 fdinfo
->FileName
[d_info
->name_len
] = 0x00;
4149 fdinfo
->FileNameLength
= cpu_to_le32(d_info
->name_len
);
4150 fdinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
4153 case FILE_NAMES_INFORMATION
:
4155 struct file_names_info
*fninfo
;
4157 fninfo
= (struct file_names_info
*)d_info
->wptr
;
4158 memcpy(fninfo
->FileName
, d_info
->name
, d_info
->name_len
);
4159 fninfo
->FileName
[d_info
->name_len
] = 0x00;
4160 fninfo
->FileNameLength
= cpu_to_le32(d_info
->name_len
);
4161 fninfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
4164 case FILEID_FULL_DIRECTORY_INFORMATION
:
4166 struct file_id_full_dir_info
*dinfo
;
4168 dinfo
= (struct file_id_full_dir_info
*)d_info
->wptr
;
4169 memcpy(dinfo
->FileName
, d_info
->name
, d_info
->name_len
);
4170 dinfo
->FileName
[d_info
->name_len
] = 0x00;
4171 dinfo
->FileNameLength
= cpu_to_le32(d_info
->name_len
);
4172 dinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
4175 case FILEID_BOTH_DIRECTORY_INFORMATION
:
4177 struct file_id_both_directory_info
*fibdinfo
;
4179 fibdinfo
= (struct file_id_both_directory_info
*)d_info
->wptr
;
4180 memcpy(fibdinfo
->FileName
, d_info
->name
, d_info
->name_len
);
4181 fibdinfo
->FileName
[d_info
->name_len
] = 0x00;
4182 fibdinfo
->FileNameLength
= cpu_to_le32(d_info
->name_len
);
4183 fibdinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
4186 case SMB_FIND_FILE_POSIX_INFO
:
4188 struct smb2_posix_info
*posix_info
;
4190 posix_info
= (struct smb2_posix_info
*)d_info
->wptr
;
4191 memcpy(posix_info
->name
, d_info
->name
, d_info
->name_len
);
4192 posix_info
->name
[d_info
->name_len
] = 0x00;
4193 posix_info
->name_len
= cpu_to_le32(d_info
->name_len
);
4194 posix_info
->NextEntryOffset
=
4195 cpu_to_le32(next_entry_offset
);
4198 } /* switch (info_level) */
4200 d_info
->num_entry
++;
4201 d_info
->out_buf_len
-= next_entry_offset
;
4202 d_info
->wptr
+= next_entry_offset
;
4206 static bool __query_dir(struct dir_context
*ctx
, const char *name
, int namlen
,
4207 loff_t offset
, u64 ino
, unsigned int d_type
)
4209 struct ksmbd_readdir_data
*buf
;
4210 struct smb2_query_dir_private
*priv
;
4211 struct ksmbd_dir_info
*d_info
;
4214 buf
= container_of(ctx
, struct ksmbd_readdir_data
, ctx
);
4215 priv
= buf
->private;
4216 d_info
= priv
->d_info
;
4218 /* dot and dotdot entries are already reserved */
4219 if (!strcmp(".", name
) || !strcmp("..", name
))
4221 if (ksmbd_share_veto_filename(priv
->work
->tcon
->share_conf
, name
))
4223 if (!match_pattern(name
, namlen
, priv
->search_pattern
))
4226 d_info
->name
= name
;
4227 d_info
->name_len
= namlen
;
4228 rc
= reserve_populate_dentry(d_info
, priv
->info_level
);
4231 if (d_info
->flags
& SMB2_RETURN_SINGLE_ENTRY
)
4232 d_info
->out_buf_len
= 0;
4236 static int verify_info_level(int info_level
)
4238 switch (info_level
) {
4239 case FILE_FULL_DIRECTORY_INFORMATION
:
4240 case FILE_BOTH_DIRECTORY_INFORMATION
:
4241 case FILE_DIRECTORY_INFORMATION
:
4242 case FILE_NAMES_INFORMATION
:
4243 case FILEID_FULL_DIRECTORY_INFORMATION
:
4244 case FILEID_BOTH_DIRECTORY_INFORMATION
:
4245 case SMB_FIND_FILE_POSIX_INFO
:
4254 static int smb2_resp_buf_len(struct ksmbd_work
*work
, unsigned short hdr2_len
)
4258 free_len
= (int)(work
->response_sz
-
4259 (get_rfc1002_len(work
->response_buf
) + 4)) - hdr2_len
;
4263 static int smb2_calc_max_out_buf_len(struct ksmbd_work
*work
,
4264 unsigned short hdr2_len
,
4265 unsigned int out_buf_len
)
4269 if (out_buf_len
> work
->conn
->vals
->max_trans_size
)
4272 free_len
= smb2_resp_buf_len(work
, hdr2_len
);
4276 return min_t(int, out_buf_len
, free_len
);
4279 int smb2_query_dir(struct ksmbd_work
*work
)
4281 struct ksmbd_conn
*conn
= work
->conn
;
4282 struct smb2_query_directory_req
*req
;
4283 struct smb2_query_directory_rsp
*rsp
;
4284 struct ksmbd_share_config
*share
= work
->tcon
->share_conf
;
4285 struct ksmbd_file
*dir_fp
= NULL
;
4286 struct ksmbd_dir_info d_info
;
4288 char *srch_ptr
= NULL
;
4289 unsigned char srch_flag
;
4291 struct smb2_query_dir_private query_dir_private
= {NULL
, };
4293 WORK_BUFFERS(work
, req
, rsp
);
4295 if (ksmbd_override_fsids(work
)) {
4296 rsp
->hdr
.Status
= STATUS_NO_MEMORY
;
4297 smb2_set_err_rsp(work
);
4301 rc
= verify_info_level(req
->FileInformationClass
);
4307 dir_fp
= ksmbd_lookup_fd_slow(work
, req
->VolatileFileId
, req
->PersistentFileId
);
4313 if (!(dir_fp
->daccess
& FILE_LIST_DIRECTORY_LE
) ||
4314 inode_permission(file_mnt_idmap(dir_fp
->filp
),
4315 file_inode(dir_fp
->filp
),
4316 MAY_READ
| MAY_EXEC
)) {
4317 pr_err("no right to enumerate directory (%pD)\n", dir_fp
->filp
);
4322 if (!S_ISDIR(file_inode(dir_fp
->filp
)->i_mode
)) {
4323 pr_err("can't do query dir for a file\n");
4328 srch_flag
= req
->Flags
;
4329 srch_ptr
= smb_strndup_from_utf16((char *)req
+ le16_to_cpu(req
->FileNameOffset
),
4330 le16_to_cpu(req
->FileNameLength
), 1,
4332 if (IS_ERR(srch_ptr
)) {
4333 ksmbd_debug(SMB
, "Search Pattern not found\n");
4337 ksmbd_debug(SMB
, "Search pattern is %s\n", srch_ptr
);
4340 if (srch_flag
& SMB2_REOPEN
|| srch_flag
& SMB2_RESTART_SCANS
) {
4341 ksmbd_debug(SMB
, "Restart directory scan\n");
4342 generic_file_llseek(dir_fp
->filp
, 0, SEEK_SET
);
4345 memset(&d_info
, 0, sizeof(struct ksmbd_dir_info
));
4346 d_info
.wptr
= (char *)rsp
->Buffer
;
4347 d_info
.rptr
= (char *)rsp
->Buffer
;
4348 d_info
.out_buf_len
=
4349 smb2_calc_max_out_buf_len(work
, 8,
4350 le32_to_cpu(req
->OutputBufferLength
));
4351 if (d_info
.out_buf_len
< 0) {
4355 d_info
.flags
= srch_flag
;
4358 * reserve dot and dotdot entries in head of buffer
4361 rc
= ksmbd_populate_dot_dotdot_entries(work
, req
->FileInformationClass
,
4362 dir_fp
, &d_info
, srch_ptr
,
4363 smb2_populate_readdir_entry
);
4369 if (test_share_config_flag(share
, KSMBD_SHARE_FLAG_HIDE_DOT_FILES
))
4370 d_info
.hide_dot_file
= true;
4372 buffer_sz
= d_info
.out_buf_len
;
4373 d_info
.rptr
= d_info
.wptr
;
4374 query_dir_private
.work
= work
;
4375 query_dir_private
.search_pattern
= srch_ptr
;
4376 query_dir_private
.dir_fp
= dir_fp
;
4377 query_dir_private
.d_info
= &d_info
;
4378 query_dir_private
.info_level
= req
->FileInformationClass
;
4379 dir_fp
->readdir_data
.private = &query_dir_private
;
4380 set_ctx_actor(&dir_fp
->readdir_data
.ctx
, __query_dir
);
4382 rc
= iterate_dir(dir_fp
->filp
, &dir_fp
->readdir_data
.ctx
);
4384 * req->OutputBufferLength is too small to contain even one entry.
4385 * In this case, it immediately returns OutputBufferLength 0 to client.
4387 if (!d_info
.out_buf_len
&& !d_info
.num_entry
)
4389 if (rc
> 0 || rc
== -ENOSPC
)
4394 d_info
.wptr
= d_info
.rptr
;
4395 d_info
.out_buf_len
= buffer_sz
;
4396 rc
= process_query_dir_entries(&query_dir_private
);
4400 if (!d_info
.data_count
&& d_info
.out_buf_len
>= 0) {
4401 if (srch_flag
& SMB2_RETURN_SINGLE_ENTRY
&& !is_asterisk(srch_ptr
)) {
4402 rsp
->hdr
.Status
= STATUS_NO_SUCH_FILE
;
4404 dir_fp
->dot_dotdot
[0] = dir_fp
->dot_dotdot
[1] = 0;
4405 rsp
->hdr
.Status
= STATUS_NO_MORE_FILES
;
4407 rsp
->StructureSize
= cpu_to_le16(9);
4408 rsp
->OutputBufferOffset
= cpu_to_le16(0);
4409 rsp
->OutputBufferLength
= cpu_to_le32(0);
4411 rc
= ksmbd_iov_pin_rsp(work
, (void *)rsp
,
4412 offsetof(struct smb2_query_directory_rsp
, Buffer
)
4418 ((struct file_directory_info
*)
4419 ((char *)rsp
->Buffer
+ d_info
.last_entry_offset
))
4420 ->NextEntryOffset
= 0;
4421 if (d_info
.data_count
>= d_info
.last_entry_off_align
)
4422 d_info
.data_count
-= d_info
.last_entry_off_align
;
4424 rsp
->StructureSize
= cpu_to_le16(9);
4425 rsp
->OutputBufferOffset
= cpu_to_le16(72);
4426 rsp
->OutputBufferLength
= cpu_to_le32(d_info
.data_count
);
4427 rc
= ksmbd_iov_pin_rsp(work
, (void *)rsp
,
4428 offsetof(struct smb2_query_directory_rsp
, Buffer
) +
4435 ksmbd_fd_put(work
, dir_fp
);
4436 ksmbd_revert_fsids(work
);
4440 pr_err("error while processing smb2 query dir rc = %d\n", rc
);
4445 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
4446 else if (rc
== -EACCES
)
4447 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
4448 else if (rc
== -ENOENT
)
4449 rsp
->hdr
.Status
= STATUS_NO_SUCH_FILE
;
4450 else if (rc
== -EBADF
)
4451 rsp
->hdr
.Status
= STATUS_FILE_CLOSED
;
4452 else if (rc
== -ENOMEM
)
4453 rsp
->hdr
.Status
= STATUS_NO_MEMORY
;
4454 else if (rc
== -EFAULT
)
4455 rsp
->hdr
.Status
= STATUS_INVALID_INFO_CLASS
;
4456 else if (rc
== -EIO
)
4457 rsp
->hdr
.Status
= STATUS_FILE_CORRUPT_ERROR
;
4458 if (!rsp
->hdr
.Status
)
4459 rsp
->hdr
.Status
= STATUS_UNEXPECTED_IO_ERROR
;
4461 smb2_set_err_rsp(work
);
4462 ksmbd_fd_put(work
, dir_fp
);
4463 ksmbd_revert_fsids(work
);
4468 * buffer_check_err() - helper function to check buffer errors
4469 * @reqOutputBufferLength: max buffer length expected in command response
4470 * @rsp: query info response buffer contains output buffer length
4471 * @rsp_org: base response buffer pointer in case of chained response
4473 * Return: 0 on success, otherwise error
4475 static int buffer_check_err(int reqOutputBufferLength
,
4476 struct smb2_query_info_rsp
*rsp
,
4479 if (reqOutputBufferLength
< le32_to_cpu(rsp
->OutputBufferLength
)) {
4480 pr_err("Invalid Buffer Size Requested\n");
4481 rsp
->hdr
.Status
= STATUS_INFO_LENGTH_MISMATCH
;
4482 *(__be32
*)rsp_org
= cpu_to_be32(sizeof(struct smb2_hdr
));
4488 static void get_standard_info_pipe(struct smb2_query_info_rsp
*rsp
,
4491 struct smb2_file_standard_info
*sinfo
;
4493 sinfo
= (struct smb2_file_standard_info
*)rsp
->Buffer
;
4495 sinfo
->AllocationSize
= cpu_to_le64(4096);
4496 sinfo
->EndOfFile
= cpu_to_le64(0);
4497 sinfo
->NumberOfLinks
= cpu_to_le32(1);
4498 sinfo
->DeletePending
= 1;
4499 sinfo
->Directory
= 0;
4500 rsp
->OutputBufferLength
=
4501 cpu_to_le32(sizeof(struct smb2_file_standard_info
));
4504 static void get_internal_info_pipe(struct smb2_query_info_rsp
*rsp
, u64 num
,
4507 struct smb2_file_internal_info
*file_info
;
4509 file_info
= (struct smb2_file_internal_info
*)rsp
->Buffer
;
4511 /* any unique number */
4512 file_info
->IndexNumber
= cpu_to_le64(num
| (1ULL << 63));
4513 rsp
->OutputBufferLength
=
4514 cpu_to_le32(sizeof(struct smb2_file_internal_info
));
4517 static int smb2_get_info_file_pipe(struct ksmbd_session
*sess
,
4518 struct smb2_query_info_req
*req
,
4519 struct smb2_query_info_rsp
*rsp
,
4526 * Windows can sometime send query file info request on
4527 * pipe without opening it, checking error condition here
4529 id
= req
->VolatileFileId
;
4530 if (!ksmbd_session_rpc_method(sess
, id
))
4533 ksmbd_debug(SMB
, "FileInfoClass %u, FileId 0x%llx\n",
4534 req
->FileInfoClass
, req
->VolatileFileId
);
4536 switch (req
->FileInfoClass
) {
4537 case FILE_STANDARD_INFORMATION
:
4538 get_standard_info_pipe(rsp
, rsp_org
);
4539 rc
= buffer_check_err(le32_to_cpu(req
->OutputBufferLength
),
4542 case FILE_INTERNAL_INFORMATION
:
4543 get_internal_info_pipe(rsp
, id
, rsp_org
);
4544 rc
= buffer_check_err(le32_to_cpu(req
->OutputBufferLength
),
4548 ksmbd_debug(SMB
, "smb2_info_file_pipe for %u not supported\n",
4549 req
->FileInfoClass
);
4556 * smb2_get_ea() - handler for smb2 get extended attribute command
4557 * @work: smb work containing query info command buffer
4558 * @fp: ksmbd_file pointer
4559 * @req: get extended attribute request
4560 * @rsp: response buffer pointer
4561 * @rsp_org: base response buffer pointer in case of chained response
4563 * Return: 0 on success, otherwise error
4565 static int smb2_get_ea(struct ksmbd_work
*work
, struct ksmbd_file
*fp
,
4566 struct smb2_query_info_req
*req
,
4567 struct smb2_query_info_rsp
*rsp
, void *rsp_org
)
4569 struct smb2_ea_info
*eainfo
, *prev_eainfo
;
4570 char *name
, *ptr
, *xattr_list
= NULL
, *buf
;
4571 int rc
, name_len
, value_len
, xattr_list_len
, idx
;
4572 ssize_t buf_free_len
, alignment_bytes
, next_offset
, rsp_data_cnt
= 0;
4573 struct smb2_ea_info_req
*ea_req
= NULL
;
4574 const struct path
*path
;
4575 struct mnt_idmap
*idmap
= file_mnt_idmap(fp
->filp
);
4577 if (!(fp
->daccess
& FILE_READ_EA_LE
)) {
4578 pr_err("Not permitted to read ext attr : 0x%x\n",
4583 path
= &fp
->filp
->f_path
;
4584 /* single EA entry is requested with given user.* name */
4585 if (req
->InputBufferLength
) {
4586 if (le32_to_cpu(req
->InputBufferLength
) <=
4587 sizeof(struct smb2_ea_info_req
))
4590 ea_req
= (struct smb2_ea_info_req
*)((char *)req
+
4591 le16_to_cpu(req
->InputBufferOffset
));
4593 /* need to send all EAs, if no specific EA is requested*/
4594 if (le32_to_cpu(req
->Flags
) & SL_RETURN_SINGLE_ENTRY
)
4596 "All EAs are requested but need to send single EA entry in rsp flags 0x%x\n",
4597 le32_to_cpu(req
->Flags
));
4601 smb2_calc_max_out_buf_len(work
, 8,
4602 le32_to_cpu(req
->OutputBufferLength
));
4603 if (buf_free_len
< 0)
4606 rc
= ksmbd_vfs_listxattr(path
->dentry
, &xattr_list
);
4608 rsp
->hdr
.Status
= STATUS_INVALID_HANDLE
;
4610 } else if (!rc
) { /* there is no EA in the file */
4611 ksmbd_debug(SMB
, "no ea data in the file\n");
4614 xattr_list_len
= rc
;
4616 ptr
= (char *)rsp
->Buffer
;
4617 eainfo
= (struct smb2_ea_info
*)ptr
;
4618 prev_eainfo
= eainfo
;
4621 while (idx
< xattr_list_len
) {
4622 name
= xattr_list
+ idx
;
4623 name_len
= strlen(name
);
4625 ksmbd_debug(SMB
, "%s, len %d\n", name
, name_len
);
4626 idx
+= name_len
+ 1;
4629 * CIFS does not support EA other than user.* namespace,
4630 * still keep the framework generic, to list other attrs
4633 if (strncmp(name
, XATTR_USER_PREFIX
, XATTR_USER_PREFIX_LEN
))
4636 if (!strncmp(&name
[XATTR_USER_PREFIX_LEN
], STREAM_PREFIX
,
4640 if (req
->InputBufferLength
&&
4641 strncmp(&name
[XATTR_USER_PREFIX_LEN
], ea_req
->name
,
4642 ea_req
->EaNameLength
))
4645 if (!strncmp(&name
[XATTR_USER_PREFIX_LEN
],
4646 DOS_ATTRIBUTE_PREFIX
, DOS_ATTRIBUTE_PREFIX_LEN
))
4649 if (!strncmp(name
, XATTR_USER_PREFIX
, XATTR_USER_PREFIX_LEN
))
4650 name_len
-= XATTR_USER_PREFIX_LEN
;
4652 ptr
= eainfo
->name
+ name_len
+ 1;
4653 buf_free_len
-= (offsetof(struct smb2_ea_info
, name
) +
4655 /* bailout if xattr can't fit in buf_free_len */
4656 value_len
= ksmbd_vfs_getxattr(idmap
, path
->dentry
,
4658 if (value_len
<= 0) {
4660 rsp
->hdr
.Status
= STATUS_INVALID_HANDLE
;
4664 buf_free_len
-= value_len
;
4665 if (buf_free_len
< 0) {
4670 memcpy(ptr
, buf
, value_len
);
4675 eainfo
->EaNameLength
= name_len
;
4677 if (!strncmp(name
, XATTR_USER_PREFIX
, XATTR_USER_PREFIX_LEN
))
4678 memcpy(eainfo
->name
, &name
[XATTR_USER_PREFIX_LEN
],
4681 memcpy(eainfo
->name
, name
, name_len
);
4683 eainfo
->name
[name_len
] = '\0';
4684 eainfo
->EaValueLength
= cpu_to_le16(value_len
);
4685 next_offset
= offsetof(struct smb2_ea_info
, name
) +
4686 name_len
+ 1 + value_len
;
4688 /* align next xattr entry at 4 byte bundary */
4689 alignment_bytes
= ((next_offset
+ 3) & ~3) - next_offset
;
4690 if (alignment_bytes
) {
4691 memset(ptr
, '\0', alignment_bytes
);
4692 ptr
+= alignment_bytes
;
4693 next_offset
+= alignment_bytes
;
4694 buf_free_len
-= alignment_bytes
;
4696 eainfo
->NextEntryOffset
= cpu_to_le32(next_offset
);
4697 prev_eainfo
= eainfo
;
4698 eainfo
= (struct smb2_ea_info
*)ptr
;
4699 rsp_data_cnt
+= next_offset
;
4701 if (req
->InputBufferLength
) {
4702 ksmbd_debug(SMB
, "single entry requested\n");
4707 /* no more ea entries */
4708 prev_eainfo
->NextEntryOffset
= 0;
4711 if (rsp_data_cnt
== 0)
4712 rsp
->hdr
.Status
= STATUS_NO_EAS_ON_FILE
;
4713 rsp
->OutputBufferLength
= cpu_to_le32(rsp_data_cnt
);
4719 static void get_file_access_info(struct smb2_query_info_rsp
*rsp
,
4720 struct ksmbd_file
*fp
, void *rsp_org
)
4722 struct smb2_file_access_info
*file_info
;
4724 file_info
= (struct smb2_file_access_info
*)rsp
->Buffer
;
4725 file_info
->AccessFlags
= fp
->daccess
;
4726 rsp
->OutputBufferLength
=
4727 cpu_to_le32(sizeof(struct smb2_file_access_info
));
4730 static int get_file_basic_info(struct smb2_query_info_rsp
*rsp
,
4731 struct ksmbd_file
*fp
, void *rsp_org
)
4733 struct smb2_file_basic_info
*basic_info
;
4738 if (!(fp
->daccess
& FILE_READ_ATTRIBUTES_LE
)) {
4739 pr_err("no right to read the attributes : 0x%x\n",
4744 ret
= vfs_getattr(&fp
->filp
->f_path
, &stat
, STATX_BASIC_STATS
,
4745 AT_STATX_SYNC_AS_STAT
);
4749 basic_info
= (struct smb2_file_basic_info
*)rsp
->Buffer
;
4750 basic_info
->CreationTime
= cpu_to_le64(fp
->create_time
);
4751 time
= ksmbd_UnixTimeToNT(stat
.atime
);
4752 basic_info
->LastAccessTime
= cpu_to_le64(time
);
4753 time
= ksmbd_UnixTimeToNT(stat
.mtime
);
4754 basic_info
->LastWriteTime
= cpu_to_le64(time
);
4755 time
= ksmbd_UnixTimeToNT(stat
.ctime
);
4756 basic_info
->ChangeTime
= cpu_to_le64(time
);
4757 basic_info
->Attributes
= fp
->f_ci
->m_fattr
;
4758 basic_info
->Pad1
= 0;
4759 rsp
->OutputBufferLength
=
4760 cpu_to_le32(sizeof(struct smb2_file_basic_info
));
4764 static int get_file_standard_info(struct smb2_query_info_rsp
*rsp
,
4765 struct ksmbd_file
*fp
, void *rsp_org
)
4767 struct smb2_file_standard_info
*sinfo
;
4768 unsigned int delete_pending
;
4772 ret
= vfs_getattr(&fp
->filp
->f_path
, &stat
, STATX_BASIC_STATS
,
4773 AT_STATX_SYNC_AS_STAT
);
4777 sinfo
= (struct smb2_file_standard_info
*)rsp
->Buffer
;
4778 delete_pending
= ksmbd_inode_pending_delete(fp
);
4780 sinfo
->AllocationSize
= cpu_to_le64(stat
.blocks
<< 9);
4781 sinfo
->EndOfFile
= S_ISDIR(stat
.mode
) ? 0 : cpu_to_le64(stat
.size
);
4782 sinfo
->NumberOfLinks
= cpu_to_le32(get_nlink(&stat
) - delete_pending
);
4783 sinfo
->DeletePending
= delete_pending
;
4784 sinfo
->Directory
= S_ISDIR(stat
.mode
) ? 1 : 0;
4785 rsp
->OutputBufferLength
=
4786 cpu_to_le32(sizeof(struct smb2_file_standard_info
));
4791 static void get_file_alignment_info(struct smb2_query_info_rsp
*rsp
,
4794 struct smb2_file_alignment_info
*file_info
;
4796 file_info
= (struct smb2_file_alignment_info
*)rsp
->Buffer
;
4797 file_info
->AlignmentRequirement
= 0;
4798 rsp
->OutputBufferLength
=
4799 cpu_to_le32(sizeof(struct smb2_file_alignment_info
));
4802 static int get_file_all_info(struct ksmbd_work
*work
,
4803 struct smb2_query_info_rsp
*rsp
,
4804 struct ksmbd_file
*fp
,
4807 struct ksmbd_conn
*conn
= work
->conn
;
4808 struct smb2_file_all_info
*file_info
;
4809 unsigned int delete_pending
;
4816 if (!(fp
->daccess
& FILE_READ_ATTRIBUTES_LE
)) {
4817 ksmbd_debug(SMB
, "no right to read the attributes : 0x%x\n",
4822 filename
= convert_to_nt_pathname(work
->tcon
->share_conf
, &fp
->filp
->f_path
);
4823 if (IS_ERR(filename
))
4824 return PTR_ERR(filename
);
4826 ret
= vfs_getattr(&fp
->filp
->f_path
, &stat
, STATX_BASIC_STATS
,
4827 AT_STATX_SYNC_AS_STAT
);
4831 ksmbd_debug(SMB
, "filename = %s\n", filename
);
4832 delete_pending
= ksmbd_inode_pending_delete(fp
);
4833 file_info
= (struct smb2_file_all_info
*)rsp
->Buffer
;
4835 file_info
->CreationTime
= cpu_to_le64(fp
->create_time
);
4836 time
= ksmbd_UnixTimeToNT(stat
.atime
);
4837 file_info
->LastAccessTime
= cpu_to_le64(time
);
4838 time
= ksmbd_UnixTimeToNT(stat
.mtime
);
4839 file_info
->LastWriteTime
= cpu_to_le64(time
);
4840 time
= ksmbd_UnixTimeToNT(stat
.ctime
);
4841 file_info
->ChangeTime
= cpu_to_le64(time
);
4842 file_info
->Attributes
= fp
->f_ci
->m_fattr
;
4843 file_info
->Pad1
= 0;
4844 file_info
->AllocationSize
=
4845 cpu_to_le64(stat
.blocks
<< 9);
4846 file_info
->EndOfFile
= S_ISDIR(stat
.mode
) ? 0 : cpu_to_le64(stat
.size
);
4847 file_info
->NumberOfLinks
=
4848 cpu_to_le32(get_nlink(&stat
) - delete_pending
);
4849 file_info
->DeletePending
= delete_pending
;
4850 file_info
->Directory
= S_ISDIR(stat
.mode
) ? 1 : 0;
4851 file_info
->Pad2
= 0;
4852 file_info
->IndexNumber
= cpu_to_le64(stat
.ino
);
4853 file_info
->EASize
= 0;
4854 file_info
->AccessFlags
= fp
->daccess
;
4855 file_info
->CurrentByteOffset
= cpu_to_le64(fp
->filp
->f_pos
);
4856 file_info
->Mode
= fp
->coption
;
4857 file_info
->AlignmentRequirement
= 0;
4858 conv_len
= smbConvertToUTF16((__le16
*)file_info
->FileName
, filename
,
4859 PATH_MAX
, conn
->local_nls
, 0);
4861 file_info
->FileNameLength
= cpu_to_le32(conv_len
);
4862 rsp
->OutputBufferLength
=
4863 cpu_to_le32(sizeof(struct smb2_file_all_info
) + conv_len
- 1);
4868 static void get_file_alternate_info(struct ksmbd_work
*work
,
4869 struct smb2_query_info_rsp
*rsp
,
4870 struct ksmbd_file
*fp
,
4873 struct ksmbd_conn
*conn
= work
->conn
;
4874 struct smb2_file_alt_name_info
*file_info
;
4875 struct dentry
*dentry
= fp
->filp
->f_path
.dentry
;
4878 spin_lock(&dentry
->d_lock
);
4879 file_info
= (struct smb2_file_alt_name_info
*)rsp
->Buffer
;
4880 conv_len
= ksmbd_extract_shortname(conn
,
4881 dentry
->d_name
.name
,
4882 file_info
->FileName
);
4883 spin_unlock(&dentry
->d_lock
);
4884 file_info
->FileNameLength
= cpu_to_le32(conv_len
);
4885 rsp
->OutputBufferLength
=
4886 cpu_to_le32(sizeof(struct smb2_file_alt_name_info
) + conv_len
);
4889 static int get_file_stream_info(struct ksmbd_work
*work
,
4890 struct smb2_query_info_rsp
*rsp
,
4891 struct ksmbd_file
*fp
,
4894 struct ksmbd_conn
*conn
= work
->conn
;
4895 struct smb2_file_stream_info
*file_info
;
4896 char *stream_name
, *xattr_list
= NULL
, *stream_buf
;
4898 const struct path
*path
= &fp
->filp
->f_path
;
4899 ssize_t xattr_list_len
;
4900 int nbytes
= 0, streamlen
, stream_name_len
, next
, idx
= 0;
4902 struct smb2_query_info_req
*req
= ksmbd_req_buf_next(work
);
4905 ret
= vfs_getattr(&fp
->filp
->f_path
, &stat
, STATX_BASIC_STATS
,
4906 AT_STATX_SYNC_AS_STAT
);
4910 file_info
= (struct smb2_file_stream_info
*)rsp
->Buffer
;
4913 smb2_calc_max_out_buf_len(work
, 8,
4914 le32_to_cpu(req
->OutputBufferLength
));
4915 if (buf_free_len
< 0)
4918 xattr_list_len
= ksmbd_vfs_listxattr(path
->dentry
, &xattr_list
);
4919 if (xattr_list_len
< 0) {
4921 } else if (!xattr_list_len
) {
4922 ksmbd_debug(SMB
, "empty xattr in the file\n");
4926 while (idx
< xattr_list_len
) {
4927 stream_name
= xattr_list
+ idx
;
4928 streamlen
= strlen(stream_name
);
4929 idx
+= streamlen
+ 1;
4931 ksmbd_debug(SMB
, "%s, len %d\n", stream_name
, streamlen
);
4933 if (strncmp(&stream_name
[XATTR_USER_PREFIX_LEN
],
4934 STREAM_PREFIX
, STREAM_PREFIX_LEN
))
4937 stream_name_len
= streamlen
- (XATTR_USER_PREFIX_LEN
+
4939 streamlen
= stream_name_len
;
4943 stream_buf
= kmalloc(streamlen
+ 1, GFP_KERNEL
);
4947 streamlen
= snprintf(stream_buf
, streamlen
+ 1,
4948 ":%s", &stream_name
[XATTR_NAME_STREAM_LEN
]);
4950 next
= sizeof(struct smb2_file_stream_info
) + streamlen
* 2;
4951 if (next
> buf_free_len
) {
4956 file_info
= (struct smb2_file_stream_info
*)&rsp
->Buffer
[nbytes
];
4957 streamlen
= smbConvertToUTF16((__le16
*)file_info
->StreamName
,
4958 stream_buf
, streamlen
,
4959 conn
->local_nls
, 0);
4962 file_info
->StreamNameLength
= cpu_to_le32(streamlen
);
4963 file_info
->StreamSize
= cpu_to_le64(stream_name_len
);
4964 file_info
->StreamAllocationSize
= cpu_to_le64(stream_name_len
);
4967 buf_free_len
-= next
;
4968 file_info
->NextEntryOffset
= cpu_to_le32(next
);
4972 if (!S_ISDIR(stat
.mode
) &&
4973 buf_free_len
>= sizeof(struct smb2_file_stream_info
) + 7 * 2) {
4974 file_info
= (struct smb2_file_stream_info
*)
4975 &rsp
->Buffer
[nbytes
];
4976 streamlen
= smbConvertToUTF16((__le16
*)file_info
->StreamName
,
4977 "::$DATA", 7, conn
->local_nls
, 0);
4979 file_info
->StreamNameLength
= cpu_to_le32(streamlen
);
4980 file_info
->StreamSize
= cpu_to_le64(stat
.size
);
4981 file_info
->StreamAllocationSize
= cpu_to_le64(stat
.blocks
<< 9);
4982 nbytes
+= sizeof(struct smb2_file_stream_info
) + streamlen
;
4985 /* last entry offset should be 0 */
4986 file_info
->NextEntryOffset
= 0;
4989 rsp
->OutputBufferLength
= cpu_to_le32(nbytes
);
4994 static int get_file_internal_info(struct smb2_query_info_rsp
*rsp
,
4995 struct ksmbd_file
*fp
, void *rsp_org
)
4997 struct smb2_file_internal_info
*file_info
;
5001 ret
= vfs_getattr(&fp
->filp
->f_path
, &stat
, STATX_BASIC_STATS
,
5002 AT_STATX_SYNC_AS_STAT
);
5006 file_info
= (struct smb2_file_internal_info
*)rsp
->Buffer
;
5007 file_info
->IndexNumber
= cpu_to_le64(stat
.ino
);
5008 rsp
->OutputBufferLength
=
5009 cpu_to_le32(sizeof(struct smb2_file_internal_info
));
5014 static int get_file_network_open_info(struct smb2_query_info_rsp
*rsp
,
5015 struct ksmbd_file
*fp
, void *rsp_org
)
5017 struct smb2_file_ntwrk_info
*file_info
;
5022 if (!(fp
->daccess
& FILE_READ_ATTRIBUTES_LE
)) {
5023 pr_err("no right to read the attributes : 0x%x\n",
5028 ret
= vfs_getattr(&fp
->filp
->f_path
, &stat
, STATX_BASIC_STATS
,
5029 AT_STATX_SYNC_AS_STAT
);
5033 file_info
= (struct smb2_file_ntwrk_info
*)rsp
->Buffer
;
5035 file_info
->CreationTime
= cpu_to_le64(fp
->create_time
);
5036 time
= ksmbd_UnixTimeToNT(stat
.atime
);
5037 file_info
->LastAccessTime
= cpu_to_le64(time
);
5038 time
= ksmbd_UnixTimeToNT(stat
.mtime
);
5039 file_info
->LastWriteTime
= cpu_to_le64(time
);
5040 time
= ksmbd_UnixTimeToNT(stat
.ctime
);
5041 file_info
->ChangeTime
= cpu_to_le64(time
);
5042 file_info
->Attributes
= fp
->f_ci
->m_fattr
;
5043 file_info
->AllocationSize
= cpu_to_le64(stat
.blocks
<< 9);
5044 file_info
->EndOfFile
= S_ISDIR(stat
.mode
) ? 0 : cpu_to_le64(stat
.size
);
5045 file_info
->Reserved
= cpu_to_le32(0);
5046 rsp
->OutputBufferLength
=
5047 cpu_to_le32(sizeof(struct smb2_file_ntwrk_info
));
5051 static void get_file_ea_info(struct smb2_query_info_rsp
*rsp
, void *rsp_org
)
5053 struct smb2_file_ea_info
*file_info
;
5055 file_info
= (struct smb2_file_ea_info
*)rsp
->Buffer
;
5056 file_info
->EASize
= 0;
5057 rsp
->OutputBufferLength
=
5058 cpu_to_le32(sizeof(struct smb2_file_ea_info
));
5061 static void get_file_position_info(struct smb2_query_info_rsp
*rsp
,
5062 struct ksmbd_file
*fp
, void *rsp_org
)
5064 struct smb2_file_pos_info
*file_info
;
5066 file_info
= (struct smb2_file_pos_info
*)rsp
->Buffer
;
5067 file_info
->CurrentByteOffset
= cpu_to_le64(fp
->filp
->f_pos
);
5068 rsp
->OutputBufferLength
=
5069 cpu_to_le32(sizeof(struct smb2_file_pos_info
));
5072 static void get_file_mode_info(struct smb2_query_info_rsp
*rsp
,
5073 struct ksmbd_file
*fp
, void *rsp_org
)
5075 struct smb2_file_mode_info
*file_info
;
5077 file_info
= (struct smb2_file_mode_info
*)rsp
->Buffer
;
5078 file_info
->Mode
= fp
->coption
& FILE_MODE_INFO_MASK
;
5079 rsp
->OutputBufferLength
=
5080 cpu_to_le32(sizeof(struct smb2_file_mode_info
));
5083 static int get_file_compression_info(struct smb2_query_info_rsp
*rsp
,
5084 struct ksmbd_file
*fp
, void *rsp_org
)
5086 struct smb2_file_comp_info
*file_info
;
5090 ret
= vfs_getattr(&fp
->filp
->f_path
, &stat
, STATX_BASIC_STATS
,
5091 AT_STATX_SYNC_AS_STAT
);
5095 file_info
= (struct smb2_file_comp_info
*)rsp
->Buffer
;
5096 file_info
->CompressedFileSize
= cpu_to_le64(stat
.blocks
<< 9);
5097 file_info
->CompressionFormat
= COMPRESSION_FORMAT_NONE
;
5098 file_info
->CompressionUnitShift
= 0;
5099 file_info
->ChunkShift
= 0;
5100 file_info
->ClusterShift
= 0;
5101 memset(&file_info
->Reserved
[0], 0, 3);
5103 rsp
->OutputBufferLength
=
5104 cpu_to_le32(sizeof(struct smb2_file_comp_info
));
5109 static int get_file_attribute_tag_info(struct smb2_query_info_rsp
*rsp
,
5110 struct ksmbd_file
*fp
, void *rsp_org
)
5112 struct smb2_file_attr_tag_info
*file_info
;
5114 if (!(fp
->daccess
& FILE_READ_ATTRIBUTES_LE
)) {
5115 pr_err("no right to read the attributes : 0x%x\n",
5120 file_info
= (struct smb2_file_attr_tag_info
*)rsp
->Buffer
;
5121 file_info
->FileAttributes
= fp
->f_ci
->m_fattr
;
5122 file_info
->ReparseTag
= 0;
5123 rsp
->OutputBufferLength
=
5124 cpu_to_le32(sizeof(struct smb2_file_attr_tag_info
));
5128 static int find_file_posix_info(struct smb2_query_info_rsp
*rsp
,
5129 struct ksmbd_file
*fp
, void *rsp_org
)
5131 struct smb311_posix_qinfo
*file_info
;
5132 struct inode
*inode
= file_inode(fp
->filp
);
5133 struct mnt_idmap
*idmap
= file_mnt_idmap(fp
->filp
);
5134 vfsuid_t vfsuid
= i_uid_into_vfsuid(idmap
, inode
);
5135 vfsgid_t vfsgid
= i_gid_into_vfsgid(idmap
, inode
);
5138 int out_buf_len
= sizeof(struct smb311_posix_qinfo
) + 32;
5141 ret
= vfs_getattr(&fp
->filp
->f_path
, &stat
, STATX_BASIC_STATS
,
5142 AT_STATX_SYNC_AS_STAT
);
5146 file_info
= (struct smb311_posix_qinfo
*)rsp
->Buffer
;
5147 file_info
->CreationTime
= cpu_to_le64(fp
->create_time
);
5148 time
= ksmbd_UnixTimeToNT(stat
.atime
);
5149 file_info
->LastAccessTime
= cpu_to_le64(time
);
5150 time
= ksmbd_UnixTimeToNT(stat
.mtime
);
5151 file_info
->LastWriteTime
= cpu_to_le64(time
);
5152 time
= ksmbd_UnixTimeToNT(stat
.ctime
);
5153 file_info
->ChangeTime
= cpu_to_le64(time
);
5154 file_info
->DosAttributes
= fp
->f_ci
->m_fattr
;
5155 file_info
->Inode
= cpu_to_le64(stat
.ino
);
5156 file_info
->EndOfFile
= cpu_to_le64(stat
.size
);
5157 file_info
->AllocationSize
= cpu_to_le64(stat
.blocks
<< 9);
5158 file_info
->HardLinks
= cpu_to_le32(stat
.nlink
);
5159 file_info
->Mode
= cpu_to_le32(stat
.mode
& 0777);
5160 file_info
->DeviceId
= cpu_to_le32(stat
.rdev
);
5163 * Sids(32) contain two sids(Domain sid(16), UNIX group sid(16)).
5164 * UNIX sid(16) = revision(1) + num_subauth(1) + authority(6) +
5165 * sub_auth(4 * 1(num_subauth)) + RID(4).
5167 id_to_sid(from_kuid_munged(&init_user_ns
, vfsuid_into_kuid(vfsuid
)),
5168 SIDUNIX_USER
, (struct smb_sid
*)&file_info
->Sids
[0]);
5169 id_to_sid(from_kgid_munged(&init_user_ns
, vfsgid_into_kgid(vfsgid
)),
5170 SIDUNIX_GROUP
, (struct smb_sid
*)&file_info
->Sids
[16]);
5172 rsp
->OutputBufferLength
= cpu_to_le32(out_buf_len
);
5177 static int smb2_get_info_file(struct ksmbd_work
*work
,
5178 struct smb2_query_info_req
*req
,
5179 struct smb2_query_info_rsp
*rsp
)
5181 struct ksmbd_file
*fp
;
5182 int fileinfoclass
= 0;
5184 unsigned int id
= KSMBD_NO_FID
, pid
= KSMBD_NO_FID
;
5186 if (test_share_config_flag(work
->tcon
->share_conf
,
5187 KSMBD_SHARE_FLAG_PIPE
)) {
5188 /* smb2 info file called for pipe */
5189 return smb2_get_info_file_pipe(work
->sess
, req
, rsp
,
5190 work
->response_buf
);
5193 if (work
->next_smb2_rcv_hdr_off
) {
5194 if (!has_file_id(req
->VolatileFileId
)) {
5195 ksmbd_debug(SMB
, "Compound request set FID = %llu\n",
5196 work
->compound_fid
);
5197 id
= work
->compound_fid
;
5198 pid
= work
->compound_pfid
;
5202 if (!has_file_id(id
)) {
5203 id
= req
->VolatileFileId
;
5204 pid
= req
->PersistentFileId
;
5207 fp
= ksmbd_lookup_fd_slow(work
, id
, pid
);
5211 fileinfoclass
= req
->FileInfoClass
;
5213 switch (fileinfoclass
) {
5214 case FILE_ACCESS_INFORMATION
:
5215 get_file_access_info(rsp
, fp
, work
->response_buf
);
5218 case FILE_BASIC_INFORMATION
:
5219 rc
= get_file_basic_info(rsp
, fp
, work
->response_buf
);
5222 case FILE_STANDARD_INFORMATION
:
5223 rc
= get_file_standard_info(rsp
, fp
, work
->response_buf
);
5226 case FILE_ALIGNMENT_INFORMATION
:
5227 get_file_alignment_info(rsp
, work
->response_buf
);
5230 case FILE_ALL_INFORMATION
:
5231 rc
= get_file_all_info(work
, rsp
, fp
, work
->response_buf
);
5234 case FILE_ALTERNATE_NAME_INFORMATION
:
5235 get_file_alternate_info(work
, rsp
, fp
, work
->response_buf
);
5238 case FILE_STREAM_INFORMATION
:
5239 rc
= get_file_stream_info(work
, rsp
, fp
, work
->response_buf
);
5242 case FILE_INTERNAL_INFORMATION
:
5243 rc
= get_file_internal_info(rsp
, fp
, work
->response_buf
);
5246 case FILE_NETWORK_OPEN_INFORMATION
:
5247 rc
= get_file_network_open_info(rsp
, fp
, work
->response_buf
);
5250 case FILE_EA_INFORMATION
:
5251 get_file_ea_info(rsp
, work
->response_buf
);
5254 case FILE_FULL_EA_INFORMATION
:
5255 rc
= smb2_get_ea(work
, fp
, req
, rsp
, work
->response_buf
);
5258 case FILE_POSITION_INFORMATION
:
5259 get_file_position_info(rsp
, fp
, work
->response_buf
);
5262 case FILE_MODE_INFORMATION
:
5263 get_file_mode_info(rsp
, fp
, work
->response_buf
);
5266 case FILE_COMPRESSION_INFORMATION
:
5267 rc
= get_file_compression_info(rsp
, fp
, work
->response_buf
);
5270 case FILE_ATTRIBUTE_TAG_INFORMATION
:
5271 rc
= get_file_attribute_tag_info(rsp
, fp
, work
->response_buf
);
5273 case SMB_FIND_FILE_POSIX_INFO
:
5274 if (!work
->tcon
->posix_extensions
) {
5275 pr_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n");
5278 rc
= find_file_posix_info(rsp
, fp
, work
->response_buf
);
5282 ksmbd_debug(SMB
, "fileinfoclass %d not supported yet\n",
5287 rc
= buffer_check_err(le32_to_cpu(req
->OutputBufferLength
),
5288 rsp
, work
->response_buf
);
5289 ksmbd_fd_put(work
, fp
);
5293 static int smb2_get_info_filesystem(struct ksmbd_work
*work
,
5294 struct smb2_query_info_req
*req
,
5295 struct smb2_query_info_rsp
*rsp
)
5297 struct ksmbd_session
*sess
= work
->sess
;
5298 struct ksmbd_conn
*conn
= work
->conn
;
5299 struct ksmbd_share_config
*share
= work
->tcon
->share_conf
;
5300 int fsinfoclass
= 0;
5301 struct kstatfs stfs
;
5308 rc
= kern_path(share
->path
, LOOKUP_NO_SYMLINKS
, &path
);
5310 pr_err("cannot create vfs path\n");
5314 rc
= vfs_statfs(&path
, &stfs
);
5316 pr_err("cannot do stat of path %s\n", share
->path
);
5321 fsinfoclass
= req
->FileInfoClass
;
5323 switch (fsinfoclass
) {
5324 case FS_DEVICE_INFORMATION
:
5326 struct filesystem_device_info
*info
;
5328 info
= (struct filesystem_device_info
*)rsp
->Buffer
;
5330 info
->DeviceType
= cpu_to_le32(FILE_DEVICE_DISK
);
5331 info
->DeviceCharacteristics
=
5332 cpu_to_le32(FILE_DEVICE_IS_MOUNTED
);
5333 if (!test_tree_conn_flag(work
->tcon
,
5334 KSMBD_TREE_CONN_FLAG_WRITABLE
))
5335 info
->DeviceCharacteristics
|=
5336 cpu_to_le32(FILE_READ_ONLY_DEVICE
);
5337 rsp
->OutputBufferLength
= cpu_to_le32(8);
5340 case FS_ATTRIBUTE_INFORMATION
:
5342 struct filesystem_attribute_info
*info
;
5345 info
= (struct filesystem_attribute_info
*)rsp
->Buffer
;
5346 info
->Attributes
= cpu_to_le32(FILE_SUPPORTS_OBJECT_IDS
|
5347 FILE_PERSISTENT_ACLS
|
5348 FILE_UNICODE_ON_DISK
|
5349 FILE_CASE_PRESERVED_NAMES
|
5350 FILE_CASE_SENSITIVE_SEARCH
|
5351 FILE_SUPPORTS_BLOCK_REFCOUNTING
);
5353 info
->Attributes
|= cpu_to_le32(server_conf
.share_fake_fscaps
);
5355 if (test_share_config_flag(work
->tcon
->share_conf
,
5356 KSMBD_SHARE_FLAG_STREAMS
))
5357 info
->Attributes
|= cpu_to_le32(FILE_NAMED_STREAMS
);
5359 info
->MaxPathNameComponentLength
= cpu_to_le32(stfs
.f_namelen
);
5360 len
= smbConvertToUTF16((__le16
*)info
->FileSystemName
,
5361 "NTFS", PATH_MAX
, conn
->local_nls
, 0);
5363 info
->FileSystemNameLen
= cpu_to_le32(len
);
5364 sz
= sizeof(struct filesystem_attribute_info
) + len
;
5365 rsp
->OutputBufferLength
= cpu_to_le32(sz
);
5368 case FS_VOLUME_INFORMATION
:
5370 struct filesystem_vol_info
*info
;
5372 unsigned int serial_crc
= 0;
5374 info
= (struct filesystem_vol_info
*)(rsp
->Buffer
);
5375 info
->VolumeCreationTime
= 0;
5376 serial_crc
= crc32_le(serial_crc
, share
->name
,
5377 strlen(share
->name
));
5378 serial_crc
= crc32_le(serial_crc
, share
->path
,
5379 strlen(share
->path
));
5380 serial_crc
= crc32_le(serial_crc
, ksmbd_netbios_name(),
5381 strlen(ksmbd_netbios_name()));
5382 /* Taking dummy value of serial number*/
5383 info
->SerialNumber
= cpu_to_le32(serial_crc
);
5384 len
= smbConvertToUTF16((__le16
*)info
->VolumeLabel
,
5385 share
->name
, PATH_MAX
,
5386 conn
->local_nls
, 0);
5388 info
->VolumeLabelSize
= cpu_to_le32(len
);
5390 sz
= sizeof(struct filesystem_vol_info
) + len
;
5391 rsp
->OutputBufferLength
= cpu_to_le32(sz
);
5394 case FS_SIZE_INFORMATION
:
5396 struct filesystem_info
*info
;
5398 info
= (struct filesystem_info
*)(rsp
->Buffer
);
5399 info
->TotalAllocationUnits
= cpu_to_le64(stfs
.f_blocks
);
5400 info
->FreeAllocationUnits
= cpu_to_le64(stfs
.f_bfree
);
5401 info
->SectorsPerAllocationUnit
= cpu_to_le32(1);
5402 info
->BytesPerSector
= cpu_to_le32(stfs
.f_bsize
);
5403 rsp
->OutputBufferLength
= cpu_to_le32(24);
5406 case FS_FULL_SIZE_INFORMATION
:
5408 struct smb2_fs_full_size_info
*info
;
5410 info
= (struct smb2_fs_full_size_info
*)(rsp
->Buffer
);
5411 info
->TotalAllocationUnits
= cpu_to_le64(stfs
.f_blocks
);
5412 info
->CallerAvailableAllocationUnits
=
5413 cpu_to_le64(stfs
.f_bavail
);
5414 info
->ActualAvailableAllocationUnits
=
5415 cpu_to_le64(stfs
.f_bfree
);
5416 info
->SectorsPerAllocationUnit
= cpu_to_le32(1);
5417 info
->BytesPerSector
= cpu_to_le32(stfs
.f_bsize
);
5418 rsp
->OutputBufferLength
= cpu_to_le32(32);
5421 case FS_OBJECT_ID_INFORMATION
:
5423 struct object_id_info
*info
;
5425 info
= (struct object_id_info
*)(rsp
->Buffer
);
5427 if (!user_guest(sess
->user
))
5428 memcpy(info
->objid
, user_passkey(sess
->user
), 16);
5430 memset(info
->objid
, 0, 16);
5432 info
->extended_info
.magic
= cpu_to_le32(EXTENDED_INFO_MAGIC
);
5433 info
->extended_info
.version
= cpu_to_le32(1);
5434 info
->extended_info
.release
= cpu_to_le32(1);
5435 info
->extended_info
.rel_date
= 0;
5436 memcpy(info
->extended_info
.version_string
, "1.1.0", strlen("1.1.0"));
5437 rsp
->OutputBufferLength
= cpu_to_le32(64);
5440 case FS_SECTOR_SIZE_INFORMATION
:
5442 struct smb3_fs_ss_info
*info
;
5443 unsigned int sector_size
=
5444 min_t(unsigned int, path
.mnt
->mnt_sb
->s_blocksize
, 4096);
5446 info
= (struct smb3_fs_ss_info
*)(rsp
->Buffer
);
5448 info
->LogicalBytesPerSector
= cpu_to_le32(sector_size
);
5449 info
->PhysicalBytesPerSectorForAtomicity
=
5450 cpu_to_le32(sector_size
);
5451 info
->PhysicalBytesPerSectorForPerf
= cpu_to_le32(sector_size
);
5452 info
->FSEffPhysicalBytesPerSectorForAtomicity
=
5453 cpu_to_le32(sector_size
);
5454 info
->Flags
= cpu_to_le32(SSINFO_FLAGS_ALIGNED_DEVICE
|
5455 SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE
);
5456 info
->ByteOffsetForSectorAlignment
= 0;
5457 info
->ByteOffsetForPartitionAlignment
= 0;
5458 rsp
->OutputBufferLength
= cpu_to_le32(28);
5461 case FS_CONTROL_INFORMATION
:
5464 * TODO : The current implementation is based on
5465 * test result with win7(NTFS) server. It's need to
5466 * modify this to get valid Quota values
5469 struct smb2_fs_control_info
*info
;
5471 info
= (struct smb2_fs_control_info
*)(rsp
->Buffer
);
5472 info
->FreeSpaceStartFiltering
= 0;
5473 info
->FreeSpaceThreshold
= 0;
5474 info
->FreeSpaceStopFiltering
= 0;
5475 info
->DefaultQuotaThreshold
= cpu_to_le64(SMB2_NO_FID
);
5476 info
->DefaultQuotaLimit
= cpu_to_le64(SMB2_NO_FID
);
5478 rsp
->OutputBufferLength
= cpu_to_le32(48);
5481 case FS_POSIX_INFORMATION
:
5483 struct filesystem_posix_info
*info
;
5485 if (!work
->tcon
->posix_extensions
) {
5486 pr_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n");
5489 info
= (struct filesystem_posix_info
*)(rsp
->Buffer
);
5490 info
->OptimalTransferSize
= cpu_to_le32(stfs
.f_bsize
);
5491 info
->BlockSize
= cpu_to_le32(stfs
.f_bsize
);
5492 info
->TotalBlocks
= cpu_to_le64(stfs
.f_blocks
);
5493 info
->BlocksAvail
= cpu_to_le64(stfs
.f_bfree
);
5494 info
->UserBlocksAvail
= cpu_to_le64(stfs
.f_bavail
);
5495 info
->TotalFileNodes
= cpu_to_le64(stfs
.f_files
);
5496 info
->FreeFileNodes
= cpu_to_le64(stfs
.f_ffree
);
5497 rsp
->OutputBufferLength
= cpu_to_le32(56);
5505 rc
= buffer_check_err(le32_to_cpu(req
->OutputBufferLength
),
5506 rsp
, work
->response_buf
);
5511 static int smb2_get_info_sec(struct ksmbd_work
*work
,
5512 struct smb2_query_info_req
*req
,
5513 struct smb2_query_info_rsp
*rsp
)
5515 struct ksmbd_file
*fp
;
5516 struct mnt_idmap
*idmap
;
5517 struct smb_ntsd
*pntsd
= (struct smb_ntsd
*)rsp
->Buffer
, *ppntsd
= NULL
;
5518 struct smb_fattr fattr
= {{0}};
5519 struct inode
*inode
;
5520 __u32 secdesclen
= 0;
5521 unsigned int id
= KSMBD_NO_FID
, pid
= KSMBD_NO_FID
;
5522 int addition_info
= le32_to_cpu(req
->AdditionalInformation
);
5523 int rc
= 0, ppntsd_size
= 0;
5525 if (addition_info
& ~(OWNER_SECINFO
| GROUP_SECINFO
| DACL_SECINFO
|
5526 PROTECTED_DACL_SECINFO
|
5527 UNPROTECTED_DACL_SECINFO
)) {
5528 ksmbd_debug(SMB
, "Unsupported addition info: 0x%x)\n",
5531 pntsd
->revision
= cpu_to_le16(1);
5532 pntsd
->type
= cpu_to_le16(SELF_RELATIVE
| DACL_PROTECTED
);
5533 pntsd
->osidoffset
= 0;
5534 pntsd
->gsidoffset
= 0;
5535 pntsd
->sacloffset
= 0;
5536 pntsd
->dacloffset
= 0;
5538 secdesclen
= sizeof(struct smb_ntsd
);
5539 rsp
->OutputBufferLength
= cpu_to_le32(secdesclen
);
5544 if (work
->next_smb2_rcv_hdr_off
) {
5545 if (!has_file_id(req
->VolatileFileId
)) {
5546 ksmbd_debug(SMB
, "Compound request set FID = %llu\n",
5547 work
->compound_fid
);
5548 id
= work
->compound_fid
;
5549 pid
= work
->compound_pfid
;
5553 if (!has_file_id(id
)) {
5554 id
= req
->VolatileFileId
;
5555 pid
= req
->PersistentFileId
;
5558 fp
= ksmbd_lookup_fd_slow(work
, id
, pid
);
5562 idmap
= file_mnt_idmap(fp
->filp
);
5563 inode
= file_inode(fp
->filp
);
5564 ksmbd_acls_fattr(&fattr
, idmap
, inode
);
5566 if (test_share_config_flag(work
->tcon
->share_conf
,
5567 KSMBD_SHARE_FLAG_ACL_XATTR
))
5568 ppntsd_size
= ksmbd_vfs_get_sd_xattr(work
->conn
, idmap
,
5569 fp
->filp
->f_path
.dentry
,
5572 /* Check if sd buffer size exceeds response buffer size */
5573 if (smb2_resp_buf_len(work
, 8) > ppntsd_size
)
5574 rc
= build_sec_desc(idmap
, pntsd
, ppntsd
, ppntsd_size
,
5575 addition_info
, &secdesclen
, &fattr
);
5576 posix_acl_release(fattr
.cf_acls
);
5577 posix_acl_release(fattr
.cf_dacls
);
5579 ksmbd_fd_put(work
, fp
);
5583 rsp
->OutputBufferLength
= cpu_to_le32(secdesclen
);
5588 * smb2_query_info() - handler for smb2 query info command
5589 * @work: smb work containing query info request buffer
5591 * Return: 0 on success, otherwise error
5593 int smb2_query_info(struct ksmbd_work
*work
)
5595 struct smb2_query_info_req
*req
;
5596 struct smb2_query_info_rsp
*rsp
;
5599 WORK_BUFFERS(work
, req
, rsp
);
5601 ksmbd_debug(SMB
, "GOT query info request\n");
5603 if (ksmbd_override_fsids(work
)) {
5608 switch (req
->InfoType
) {
5609 case SMB2_O_INFO_FILE
:
5610 ksmbd_debug(SMB
, "GOT SMB2_O_INFO_FILE\n");
5611 rc
= smb2_get_info_file(work
, req
, rsp
);
5613 case SMB2_O_INFO_FILESYSTEM
:
5614 ksmbd_debug(SMB
, "GOT SMB2_O_INFO_FILESYSTEM\n");
5615 rc
= smb2_get_info_filesystem(work
, req
, rsp
);
5617 case SMB2_O_INFO_SECURITY
:
5618 ksmbd_debug(SMB
, "GOT SMB2_O_INFO_SECURITY\n");
5619 rc
= smb2_get_info_sec(work
, req
, rsp
);
5622 ksmbd_debug(SMB
, "InfoType %d not supported yet\n",
5626 ksmbd_revert_fsids(work
);
5629 rsp
->StructureSize
= cpu_to_le16(9);
5630 rsp
->OutputBufferOffset
= cpu_to_le16(72);
5631 rc
= ksmbd_iov_pin_rsp(work
, (void *)rsp
,
5632 offsetof(struct smb2_query_info_rsp
, Buffer
) +
5633 le32_to_cpu(rsp
->OutputBufferLength
));
5639 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
5640 else if (rc
== -ENOENT
)
5641 rsp
->hdr
.Status
= STATUS_FILE_CLOSED
;
5642 else if (rc
== -EIO
)
5643 rsp
->hdr
.Status
= STATUS_UNEXPECTED_IO_ERROR
;
5644 else if (rc
== -ENOMEM
)
5645 rsp
->hdr
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
5646 else if (rc
== -EOPNOTSUPP
|| rsp
->hdr
.Status
== 0)
5647 rsp
->hdr
.Status
= STATUS_INVALID_INFO_CLASS
;
5648 smb2_set_err_rsp(work
);
5650 ksmbd_debug(SMB
, "error while processing smb2 query rc = %d\n",
5658 * smb2_close_pipe() - handler for closing IPC pipe
5659 * @work: smb work containing close request buffer
5663 static noinline
int smb2_close_pipe(struct ksmbd_work
*work
)
5666 struct smb2_close_req
*req
;
5667 struct smb2_close_rsp
*rsp
;
5669 WORK_BUFFERS(work
, req
, rsp
);
5671 id
= req
->VolatileFileId
;
5672 ksmbd_session_rpc_close(work
->sess
, id
);
5674 rsp
->StructureSize
= cpu_to_le16(60);
5677 rsp
->CreationTime
= 0;
5678 rsp
->LastAccessTime
= 0;
5679 rsp
->LastWriteTime
= 0;
5680 rsp
->ChangeTime
= 0;
5681 rsp
->AllocationSize
= 0;
5683 rsp
->Attributes
= 0;
5685 return ksmbd_iov_pin_rsp(work
, (void *)rsp
,
5686 sizeof(struct smb2_close_rsp
));
5690 * smb2_close() - handler for smb2 close file command
5691 * @work: smb work containing close request buffer
5695 int smb2_close(struct ksmbd_work
*work
)
5697 u64 volatile_id
= KSMBD_NO_FID
;
5699 struct smb2_close_req
*req
;
5700 struct smb2_close_rsp
*rsp
;
5701 struct ksmbd_conn
*conn
= work
->conn
;
5702 struct ksmbd_file
*fp
;
5706 WORK_BUFFERS(work
, req
, rsp
);
5708 if (test_share_config_flag(work
->tcon
->share_conf
,
5709 KSMBD_SHARE_FLAG_PIPE
)) {
5710 ksmbd_debug(SMB
, "IPC pipe close request\n");
5711 return smb2_close_pipe(work
);
5714 sess_id
= le64_to_cpu(req
->hdr
.SessionId
);
5715 if (req
->hdr
.Flags
& SMB2_FLAGS_RELATED_OPERATIONS
)
5716 sess_id
= work
->compound_sid
;
5718 work
->compound_sid
= 0;
5719 if (check_session_id(conn
, sess_id
)) {
5720 work
->compound_sid
= sess_id
;
5722 rsp
->hdr
.Status
= STATUS_USER_SESSION_DELETED
;
5723 if (req
->hdr
.Flags
& SMB2_FLAGS_RELATED_OPERATIONS
)
5724 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
5729 if (work
->next_smb2_rcv_hdr_off
&&
5730 !has_file_id(req
->VolatileFileId
)) {
5731 if (!has_file_id(work
->compound_fid
)) {
5732 /* file already closed, return FILE_CLOSED */
5733 ksmbd_debug(SMB
, "file already closed\n");
5734 rsp
->hdr
.Status
= STATUS_FILE_CLOSED
;
5739 "Compound request set FID = %llu:%llu\n",
5741 work
->compound_pfid
);
5742 volatile_id
= work
->compound_fid
;
5744 /* file closed, stored id is not valid anymore */
5745 work
->compound_fid
= KSMBD_NO_FID
;
5746 work
->compound_pfid
= KSMBD_NO_FID
;
5749 volatile_id
= req
->VolatileFileId
;
5751 ksmbd_debug(SMB
, "volatile_id = %llu\n", volatile_id
);
5753 rsp
->StructureSize
= cpu_to_le16(60);
5756 if (req
->Flags
== SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB
) {
5760 fp
= ksmbd_lookup_fd_fast(work
, volatile_id
);
5766 ret
= vfs_getattr(&fp
->filp
->f_path
, &stat
, STATX_BASIC_STATS
,
5767 AT_STATX_SYNC_AS_STAT
);
5769 ksmbd_fd_put(work
, fp
);
5773 rsp
->Flags
= SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB
;
5774 rsp
->AllocationSize
= S_ISDIR(stat
.mode
) ? 0 :
5775 cpu_to_le64(stat
.blocks
<< 9);
5776 rsp
->EndOfFile
= cpu_to_le64(stat
.size
);
5777 rsp
->Attributes
= fp
->f_ci
->m_fattr
;
5778 rsp
->CreationTime
= cpu_to_le64(fp
->create_time
);
5779 time
= ksmbd_UnixTimeToNT(stat
.atime
);
5780 rsp
->LastAccessTime
= cpu_to_le64(time
);
5781 time
= ksmbd_UnixTimeToNT(stat
.mtime
);
5782 rsp
->LastWriteTime
= cpu_to_le64(time
);
5783 time
= ksmbd_UnixTimeToNT(stat
.ctime
);
5784 rsp
->ChangeTime
= cpu_to_le64(time
);
5785 ksmbd_fd_put(work
, fp
);
5788 rsp
->AllocationSize
= 0;
5790 rsp
->Attributes
= 0;
5791 rsp
->CreationTime
= 0;
5792 rsp
->LastAccessTime
= 0;
5793 rsp
->LastWriteTime
= 0;
5794 rsp
->ChangeTime
= 0;
5797 err
= ksmbd_close_fd(work
, volatile_id
);
5800 err
= ksmbd_iov_pin_rsp(work
, (void *)rsp
,
5801 sizeof(struct smb2_close_rsp
));
5804 if (rsp
->hdr
.Status
== 0)
5805 rsp
->hdr
.Status
= STATUS_FILE_CLOSED
;
5806 smb2_set_err_rsp(work
);
5813 * smb2_echo() - handler for smb2 echo(ping) command
5814 * @work: smb work containing echo request buffer
5818 int smb2_echo(struct ksmbd_work
*work
)
5820 struct smb2_echo_rsp
*rsp
= smb2_get_msg(work
->response_buf
);
5822 if (work
->next_smb2_rcv_hdr_off
)
5823 rsp
= ksmbd_resp_buf_next(work
);
5825 rsp
->StructureSize
= cpu_to_le16(4);
5827 return ksmbd_iov_pin_rsp(work
, rsp
, sizeof(struct smb2_echo_rsp
));
5830 static int smb2_rename(struct ksmbd_work
*work
,
5831 struct ksmbd_file
*fp
,
5832 struct smb2_file_rename_info
*file_info
,
5833 struct nls_table
*local_nls
)
5835 struct ksmbd_share_config
*share
= fp
->tcon
->share_conf
;
5836 char *new_name
= NULL
;
5839 ksmbd_debug(SMB
, "setting FILE_RENAME_INFO\n");
5840 new_name
= smb2_get_name(file_info
->FileName
,
5841 le32_to_cpu(file_info
->FileNameLength
),
5843 if (IS_ERR(new_name
))
5844 return PTR_ERR(new_name
);
5846 if (strchr(new_name
, ':')) {
5848 char *xattr_stream_name
, *stream_name
= NULL
;
5849 size_t xattr_stream_size
;
5852 rc
= parse_stream_name(new_name
, &stream_name
, &s_type
);
5856 len
= strlen(new_name
);
5857 if (len
> 0 && new_name
[len
- 1] != '/') {
5858 pr_err("not allow base filename in rename\n");
5863 rc
= ksmbd_vfs_xattr_stream_name(stream_name
,
5870 rc
= ksmbd_vfs_setxattr(file_mnt_idmap(fp
->filp
),
5875 pr_err("failed to store stream name in xattr: %d\n",
5884 ksmbd_debug(SMB
, "new name %s\n", new_name
);
5885 if (ksmbd_share_veto_filename(share
, new_name
)) {
5887 ksmbd_debug(SMB
, "Can't rename vetoed file: %s\n", new_name
);
5891 if (!file_info
->ReplaceIfExists
)
5892 flags
= RENAME_NOREPLACE
;
5894 rc
= ksmbd_vfs_rename(work
, &fp
->filp
->f_path
, new_name
, flags
);
5896 smb_break_all_levII_oplock(work
, fp
, 0);
5902 static int smb2_create_link(struct ksmbd_work
*work
,
5903 struct ksmbd_share_config
*share
,
5904 struct smb2_file_link_info
*file_info
,
5905 unsigned int buf_len
, struct file
*filp
,
5906 struct nls_table
*local_nls
)
5908 char *link_name
= NULL
, *target_name
= NULL
, *pathname
= NULL
;
5909 struct path path
, parent_path
;
5910 bool file_present
= false;
5913 if (buf_len
< (u64
)sizeof(struct smb2_file_link_info
) +
5914 le32_to_cpu(file_info
->FileNameLength
))
5917 ksmbd_debug(SMB
, "setting FILE_LINK_INFORMATION\n");
5918 pathname
= kmalloc(PATH_MAX
, GFP_KERNEL
);
5922 link_name
= smb2_get_name(file_info
->FileName
,
5923 le32_to_cpu(file_info
->FileNameLength
),
5925 if (IS_ERR(link_name
) || S_ISDIR(file_inode(filp
)->i_mode
)) {
5930 ksmbd_debug(SMB
, "link name is %s\n", link_name
);
5931 target_name
= file_path(filp
, pathname
, PATH_MAX
);
5932 if (IS_ERR(target_name
)) {
5937 ksmbd_debug(SMB
, "target name is %s\n", target_name
);
5938 rc
= ksmbd_vfs_kern_path_locked(work
, link_name
, LOOKUP_NO_SYMLINKS
,
5939 &parent_path
, &path
, 0);
5944 file_present
= true;
5946 if (file_info
->ReplaceIfExists
) {
5948 rc
= ksmbd_vfs_remove_file(work
, &path
);
5951 ksmbd_debug(SMB
, "cannot delete %s\n",
5959 ksmbd_debug(SMB
, "link already exists\n");
5964 rc
= ksmbd_vfs_link(work
, target_name
, link_name
);
5969 ksmbd_vfs_kern_path_unlock(&parent_path
, &path
);
5971 if (!IS_ERR(link_name
))
5977 static int set_file_basic_info(struct ksmbd_file
*fp
,
5978 struct smb2_file_basic_info
*file_info
,
5979 struct ksmbd_share_config
*share
)
5983 struct inode
*inode
;
5984 struct mnt_idmap
*idmap
;
5987 if (!(fp
->daccess
& FILE_WRITE_ATTRIBUTES_LE
))
5992 inode
= file_inode(filp
);
5993 idmap
= file_mnt_idmap(filp
);
5995 if (file_info
->CreationTime
)
5996 fp
->create_time
= le64_to_cpu(file_info
->CreationTime
);
5998 if (file_info
->LastAccessTime
) {
5999 attrs
.ia_atime
= ksmbd_NTtimeToUnix(file_info
->LastAccessTime
);
6000 attrs
.ia_valid
|= (ATTR_ATIME
| ATTR_ATIME_SET
);
6003 attrs
.ia_valid
|= ATTR_CTIME
;
6004 if (file_info
->ChangeTime
)
6005 attrs
.ia_ctime
= ksmbd_NTtimeToUnix(file_info
->ChangeTime
);
6007 attrs
.ia_ctime
= inode_get_ctime(inode
);
6009 if (file_info
->LastWriteTime
) {
6010 attrs
.ia_mtime
= ksmbd_NTtimeToUnix(file_info
->LastWriteTime
);
6011 attrs
.ia_valid
|= (ATTR_MTIME
| ATTR_MTIME_SET
);
6014 if (file_info
->Attributes
) {
6015 if (!S_ISDIR(inode
->i_mode
) &&
6016 file_info
->Attributes
& FILE_ATTRIBUTE_DIRECTORY_LE
) {
6017 pr_err("can't change a file to a directory\n");
6021 if (!(S_ISDIR(inode
->i_mode
) && file_info
->Attributes
== FILE_ATTRIBUTE_NORMAL_LE
))
6022 fp
->f_ci
->m_fattr
= file_info
->Attributes
|
6023 (fp
->f_ci
->m_fattr
& FILE_ATTRIBUTE_DIRECTORY_LE
);
6026 if (test_share_config_flag(share
, KSMBD_SHARE_FLAG_STORE_DOS_ATTRS
) &&
6027 (file_info
->CreationTime
|| file_info
->Attributes
)) {
6028 struct xattr_dos_attrib da
= {0};
6031 da
.itime
= fp
->itime
;
6032 da
.create_time
= fp
->create_time
;
6033 da
.attr
= le32_to_cpu(fp
->f_ci
->m_fattr
);
6034 da
.flags
= XATTR_DOSINFO_ATTRIB
| XATTR_DOSINFO_CREATE_TIME
|
6035 XATTR_DOSINFO_ITIME
;
6037 rc
= ksmbd_vfs_set_dos_attrib_xattr(idmap
, &filp
->f_path
, &da
,
6041 "failed to restore file attribute in EA\n");
6045 if (attrs
.ia_valid
) {
6046 struct dentry
*dentry
= filp
->f_path
.dentry
;
6047 struct inode
*inode
= d_inode(dentry
);
6049 if (IS_IMMUTABLE(inode
) || IS_APPEND(inode
))
6053 inode_set_ctime_to_ts(inode
, attrs
.ia_ctime
);
6054 attrs
.ia_valid
&= ~ATTR_CTIME
;
6055 rc
= notify_change(idmap
, dentry
, &attrs
, NULL
);
6056 inode_unlock(inode
);
6061 static int set_file_allocation_info(struct ksmbd_work
*work
,
6062 struct ksmbd_file
*fp
,
6063 struct smb2_file_alloc_info
*file_alloc_info
)
6066 * TODO : It's working fine only when store dos attributes
6067 * is not yes. need to implement a logic which works
6068 * properly with any smb.conf option
6072 struct inode
*inode
;
6076 if (!(fp
->daccess
& FILE_WRITE_DATA_LE
))
6079 rc
= vfs_getattr(&fp
->filp
->f_path
, &stat
, STATX_BASIC_STATS
,
6080 AT_STATX_SYNC_AS_STAT
);
6084 alloc_blks
= (le64_to_cpu(file_alloc_info
->AllocationSize
) + 511) >> 9;
6085 inode
= file_inode(fp
->filp
);
6087 if (alloc_blks
> stat
.blocks
) {
6088 smb_break_all_levII_oplock(work
, fp
, 1);
6089 rc
= vfs_fallocate(fp
->filp
, FALLOC_FL_KEEP_SIZE
, 0,
6091 if (rc
&& rc
!= -EOPNOTSUPP
) {
6092 pr_err("vfs_fallocate is failed : %d\n", rc
);
6095 } else if (alloc_blks
< stat
.blocks
) {
6099 * Allocation size could be smaller than original one
6100 * which means allocated blocks in file should be
6101 * deallocated. use truncate to cut out it, but inode
6102 * size is also updated with truncate offset.
6103 * inode size is retained by backup inode size.
6105 size
= i_size_read(inode
);
6106 rc
= ksmbd_vfs_truncate(work
, fp
, alloc_blks
* 512);
6108 pr_err("truncate failed!, err %d\n", rc
);
6111 if (size
< alloc_blks
* 512)
6112 i_size_write(inode
, size
);
6117 static int set_end_of_file_info(struct ksmbd_work
*work
, struct ksmbd_file
*fp
,
6118 struct smb2_file_eof_info
*file_eof_info
)
6121 struct inode
*inode
;
6124 if (!(fp
->daccess
& FILE_WRITE_DATA_LE
))
6127 newsize
= le64_to_cpu(file_eof_info
->EndOfFile
);
6128 inode
= file_inode(fp
->filp
);
6131 * If FILE_END_OF_FILE_INFORMATION of set_info_file is called
6132 * on FAT32 shared device, truncate execution time is too long
6133 * and network error could cause from windows client. because
6134 * truncate of some filesystem like FAT32 fill zero data in
6137 if (inode
->i_sb
->s_magic
!= MSDOS_SUPER_MAGIC
) {
6138 ksmbd_debug(SMB
, "truncated to newsize %lld\n", newsize
);
6139 rc
= ksmbd_vfs_truncate(work
, fp
, newsize
);
6141 ksmbd_debug(SMB
, "truncate failed!, err %d\n", rc
);
6150 static int set_rename_info(struct ksmbd_work
*work
, struct ksmbd_file
*fp
,
6151 struct smb2_file_rename_info
*rename_info
,
6152 unsigned int buf_len
)
6154 if (!(fp
->daccess
& FILE_DELETE_LE
)) {
6155 pr_err("no right to delete : 0x%x\n", fp
->daccess
);
6159 if (buf_len
< (u64
)sizeof(struct smb2_file_rename_info
) +
6160 le32_to_cpu(rename_info
->FileNameLength
))
6163 if (!le32_to_cpu(rename_info
->FileNameLength
))
6166 return smb2_rename(work
, fp
, rename_info
, work
->conn
->local_nls
);
6169 static int set_file_disposition_info(struct ksmbd_file
*fp
,
6170 struct smb2_file_disposition_info
*file_info
)
6172 struct inode
*inode
;
6174 if (!(fp
->daccess
& FILE_DELETE_LE
)) {
6175 pr_err("no right to delete : 0x%x\n", fp
->daccess
);
6179 inode
= file_inode(fp
->filp
);
6180 if (file_info
->DeletePending
) {
6181 if (S_ISDIR(inode
->i_mode
) &&
6182 ksmbd_vfs_empty_dir(fp
) == -ENOTEMPTY
)
6184 ksmbd_set_inode_pending_delete(fp
);
6186 ksmbd_clear_inode_pending_delete(fp
);
6191 static int set_file_position_info(struct ksmbd_file
*fp
,
6192 struct smb2_file_pos_info
*file_info
)
6194 loff_t current_byte_offset
;
6195 unsigned long sector_size
;
6196 struct inode
*inode
;
6198 inode
= file_inode(fp
->filp
);
6199 current_byte_offset
= le64_to_cpu(file_info
->CurrentByteOffset
);
6200 sector_size
= inode
->i_sb
->s_blocksize
;
6202 if (current_byte_offset
< 0 ||
6203 (fp
->coption
== FILE_NO_INTERMEDIATE_BUFFERING_LE
&&
6204 current_byte_offset
& (sector_size
- 1))) {
6205 pr_err("CurrentByteOffset is not valid : %llu\n",
6206 current_byte_offset
);
6210 fp
->filp
->f_pos
= current_byte_offset
;
6214 static int set_file_mode_info(struct ksmbd_file
*fp
,
6215 struct smb2_file_mode_info
*file_info
)
6219 mode
= file_info
->Mode
;
6221 if ((mode
& ~FILE_MODE_INFO_MASK
)) {
6222 pr_err("Mode is not valid : 0x%x\n", le32_to_cpu(mode
));
6227 * TODO : need to implement consideration for
6228 * FILE_SYNCHRONOUS_IO_ALERT and FILE_SYNCHRONOUS_IO_NONALERT
6230 ksmbd_vfs_set_fadvise(fp
->filp
, mode
);
6236 * smb2_set_info_file() - handler for smb2 set info command
6237 * @work: smb work containing set info command buffer
6238 * @fp: ksmbd_file pointer
6239 * @req: request buffer pointer
6240 * @share: ksmbd_share_config pointer
6242 * Return: 0 on success, otherwise error
6243 * TODO: need to implement an error handling for STATUS_INFO_LENGTH_MISMATCH
6245 static int smb2_set_info_file(struct ksmbd_work
*work
, struct ksmbd_file
*fp
,
6246 struct smb2_set_info_req
*req
,
6247 struct ksmbd_share_config
*share
)
6249 unsigned int buf_len
= le32_to_cpu(req
->BufferLength
);
6250 char *buffer
= (char *)req
+ le16_to_cpu(req
->BufferOffset
);
6252 switch (req
->FileInfoClass
) {
6253 case FILE_BASIC_INFORMATION
:
6255 if (buf_len
< sizeof(struct smb2_file_basic_info
))
6258 return set_file_basic_info(fp
, (struct smb2_file_basic_info
*)buffer
, share
);
6260 case FILE_ALLOCATION_INFORMATION
:
6262 if (buf_len
< sizeof(struct smb2_file_alloc_info
))
6265 return set_file_allocation_info(work
, fp
,
6266 (struct smb2_file_alloc_info
*)buffer
);
6268 case FILE_END_OF_FILE_INFORMATION
:
6270 if (buf_len
< sizeof(struct smb2_file_eof_info
))
6273 return set_end_of_file_info(work
, fp
,
6274 (struct smb2_file_eof_info
*)buffer
);
6276 case FILE_RENAME_INFORMATION
:
6278 if (buf_len
< sizeof(struct smb2_file_rename_info
))
6281 return set_rename_info(work
, fp
,
6282 (struct smb2_file_rename_info
*)buffer
,
6285 case FILE_LINK_INFORMATION
:
6287 if (buf_len
< sizeof(struct smb2_file_link_info
))
6290 return smb2_create_link(work
, work
->tcon
->share_conf
,
6291 (struct smb2_file_link_info
*)buffer
,
6293 work
->conn
->local_nls
);
6295 case FILE_DISPOSITION_INFORMATION
:
6297 if (buf_len
< sizeof(struct smb2_file_disposition_info
))
6300 return set_file_disposition_info(fp
,
6301 (struct smb2_file_disposition_info
*)buffer
);
6303 case FILE_FULL_EA_INFORMATION
:
6305 if (!(fp
->daccess
& FILE_WRITE_EA_LE
)) {
6306 pr_err("Not permitted to write ext attr: 0x%x\n",
6311 if (buf_len
< sizeof(struct smb2_ea_info
))
6314 return smb2_set_ea((struct smb2_ea_info
*)buffer
,
6315 buf_len
, &fp
->filp
->f_path
, true);
6317 case FILE_POSITION_INFORMATION
:
6319 if (buf_len
< sizeof(struct smb2_file_pos_info
))
6322 return set_file_position_info(fp
, (struct smb2_file_pos_info
*)buffer
);
6324 case FILE_MODE_INFORMATION
:
6326 if (buf_len
< sizeof(struct smb2_file_mode_info
))
6329 return set_file_mode_info(fp
, (struct smb2_file_mode_info
*)buffer
);
6333 pr_err("Unimplemented Fileinfoclass :%d\n", req
->FileInfoClass
);
6337 static int smb2_set_info_sec(struct ksmbd_file
*fp
, int addition_info
,
6338 char *buffer
, int buf_len
)
6340 struct smb_ntsd
*pntsd
= (struct smb_ntsd
*)buffer
;
6342 fp
->saccess
|= FILE_SHARE_DELETE_LE
;
6344 return set_info_sec(fp
->conn
, fp
->tcon
, &fp
->filp
->f_path
, pntsd
,
6345 buf_len
, false, true);
6349 * smb2_set_info() - handler for smb2 set info command handler
6350 * @work: smb work containing set info request buffer
6352 * Return: 0 on success, otherwise error
6354 int smb2_set_info(struct ksmbd_work
*work
)
6356 struct smb2_set_info_req
*req
;
6357 struct smb2_set_info_rsp
*rsp
;
6358 struct ksmbd_file
*fp
= NULL
;
6360 unsigned int id
= KSMBD_NO_FID
, pid
= KSMBD_NO_FID
;
6362 ksmbd_debug(SMB
, "Received set info request\n");
6364 if (work
->next_smb2_rcv_hdr_off
) {
6365 req
= ksmbd_req_buf_next(work
);
6366 rsp
= ksmbd_resp_buf_next(work
);
6367 if (!has_file_id(req
->VolatileFileId
)) {
6368 ksmbd_debug(SMB
, "Compound request set FID = %llu\n",
6369 work
->compound_fid
);
6370 id
= work
->compound_fid
;
6371 pid
= work
->compound_pfid
;
6374 req
= smb2_get_msg(work
->request_buf
);
6375 rsp
= smb2_get_msg(work
->response_buf
);
6378 if (!test_tree_conn_flag(work
->tcon
, KSMBD_TREE_CONN_FLAG_WRITABLE
)) {
6379 ksmbd_debug(SMB
, "User does not have write permission\n");
6380 pr_err("User does not have write permission\n");
6385 if (!has_file_id(id
)) {
6386 id
= req
->VolatileFileId
;
6387 pid
= req
->PersistentFileId
;
6390 fp
= ksmbd_lookup_fd_slow(work
, id
, pid
);
6392 ksmbd_debug(SMB
, "Invalid id for close: %u\n", id
);
6397 switch (req
->InfoType
) {
6398 case SMB2_O_INFO_FILE
:
6399 ksmbd_debug(SMB
, "GOT SMB2_O_INFO_FILE\n");
6400 rc
= smb2_set_info_file(work
, fp
, req
, work
->tcon
->share_conf
);
6402 case SMB2_O_INFO_SECURITY
:
6403 ksmbd_debug(SMB
, "GOT SMB2_O_INFO_SECURITY\n");
6404 if (ksmbd_override_fsids(work
)) {
6408 rc
= smb2_set_info_sec(fp
,
6409 le32_to_cpu(req
->AdditionalInformation
),
6410 (char *)req
+ le16_to_cpu(req
->BufferOffset
),
6411 le32_to_cpu(req
->BufferLength
));
6412 ksmbd_revert_fsids(work
);
6421 rsp
->StructureSize
= cpu_to_le16(2);
6422 rc
= ksmbd_iov_pin_rsp(work
, (void *)rsp
,
6423 sizeof(struct smb2_set_info_rsp
));
6426 ksmbd_fd_put(work
, fp
);
6430 if (rc
== -EACCES
|| rc
== -EPERM
|| rc
== -EXDEV
)
6431 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
6432 else if (rc
== -EINVAL
)
6433 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
6434 else if (rc
== -ESHARE
)
6435 rsp
->hdr
.Status
= STATUS_SHARING_VIOLATION
;
6436 else if (rc
== -ENOENT
)
6437 rsp
->hdr
.Status
= STATUS_OBJECT_NAME_INVALID
;
6438 else if (rc
== -EBUSY
|| rc
== -ENOTEMPTY
)
6439 rsp
->hdr
.Status
= STATUS_DIRECTORY_NOT_EMPTY
;
6440 else if (rc
== -EAGAIN
)
6441 rsp
->hdr
.Status
= STATUS_FILE_LOCK_CONFLICT
;
6442 else if (rc
== -EBADF
|| rc
== -ESTALE
)
6443 rsp
->hdr
.Status
= STATUS_INVALID_HANDLE
;
6444 else if (rc
== -EEXIST
)
6445 rsp
->hdr
.Status
= STATUS_OBJECT_NAME_COLLISION
;
6446 else if (rsp
->hdr
.Status
== 0 || rc
== -EOPNOTSUPP
)
6447 rsp
->hdr
.Status
= STATUS_INVALID_INFO_CLASS
;
6448 smb2_set_err_rsp(work
);
6449 ksmbd_fd_put(work
, fp
);
6450 ksmbd_debug(SMB
, "error while processing smb2 query rc = %d\n", rc
);
6455 * smb2_read_pipe() - handler for smb2 read from IPC pipe
6456 * @work: smb work containing read IPC pipe command buffer
6458 * Return: 0 on success, otherwise error
6460 static noinline
int smb2_read_pipe(struct ksmbd_work
*work
)
6462 int nbytes
= 0, err
;
6464 struct ksmbd_rpc_command
*rpc_resp
;
6465 struct smb2_read_req
*req
;
6466 struct smb2_read_rsp
*rsp
;
6468 WORK_BUFFERS(work
, req
, rsp
);
6470 id
= req
->VolatileFileId
;
6472 rpc_resp
= ksmbd_rpc_read(work
->sess
, id
);
6474 void *aux_payload_buf
;
6476 if (rpc_resp
->flags
!= KSMBD_RPC_OK
) {
6482 kvmalloc(rpc_resp
->payload_sz
, GFP_KERNEL
);
6483 if (!aux_payload_buf
) {
6488 memcpy(aux_payload_buf
, rpc_resp
->payload
, rpc_resp
->payload_sz
);
6490 nbytes
= rpc_resp
->payload_sz
;
6491 err
= ksmbd_iov_pin_rsp_read(work
, (void *)rsp
,
6492 offsetof(struct smb2_read_rsp
, Buffer
),
6493 aux_payload_buf
, nbytes
);
6495 kvfree(aux_payload_buf
);
6500 err
= ksmbd_iov_pin_rsp(work
, (void *)rsp
,
6501 offsetof(struct smb2_read_rsp
, Buffer
));
6506 rsp
->StructureSize
= cpu_to_le16(17);
6507 rsp
->DataOffset
= 80;
6509 rsp
->DataLength
= cpu_to_le32(nbytes
);
6510 rsp
->DataRemaining
= 0;
6515 rsp
->hdr
.Status
= STATUS_UNEXPECTED_IO_ERROR
;
6516 smb2_set_err_rsp(work
);
6521 static int smb2_set_remote_key_for_rdma(struct ksmbd_work
*work
,
6522 struct smb2_buffer_desc_v1
*desc
,
6524 __le16 ChannelInfoLength
)
6526 unsigned int i
, ch_count
;
6528 if (work
->conn
->dialect
== SMB30_PROT_ID
&&
6529 Channel
!= SMB2_CHANNEL_RDMA_V1
)
6532 ch_count
= le16_to_cpu(ChannelInfoLength
) / sizeof(*desc
);
6533 if (ksmbd_debug_types
& KSMBD_DEBUG_RDMA
) {
6534 for (i
= 0; i
< ch_count
; i
++) {
6535 pr_info("RDMA r/w request %#x: token %#x, length %#x\n",
6537 le32_to_cpu(desc
[i
].token
),
6538 le32_to_cpu(desc
[i
].length
));
6544 work
->need_invalidate_rkey
=
6545 (Channel
== SMB2_CHANNEL_RDMA_V1_INVALIDATE
);
6546 if (Channel
== SMB2_CHANNEL_RDMA_V1_INVALIDATE
)
6547 work
->remote_key
= le32_to_cpu(desc
->token
);
6551 static ssize_t
smb2_read_rdma_channel(struct ksmbd_work
*work
,
6552 struct smb2_read_req
*req
, void *data_buf
,
6557 err
= ksmbd_conn_rdma_write(work
->conn
, data_buf
, length
,
6558 (struct smb2_buffer_desc_v1
*)
6559 ((char *)req
+ le16_to_cpu(req
->ReadChannelInfoOffset
)),
6560 le16_to_cpu(req
->ReadChannelInfoLength
));
6568 * smb2_read() - handler for smb2 read from file
6569 * @work: smb work containing read command buffer
6571 * Return: 0 on success, otherwise error
6573 int smb2_read(struct ksmbd_work
*work
)
6575 struct ksmbd_conn
*conn
= work
->conn
;
6576 struct smb2_read_req
*req
;
6577 struct smb2_read_rsp
*rsp
;
6578 struct ksmbd_file
*fp
= NULL
;
6580 size_t length
, mincount
;
6581 ssize_t nbytes
= 0, remain_bytes
= 0;
6583 bool is_rdma_channel
= false;
6584 unsigned int max_read_size
= conn
->vals
->max_read_size
;
6585 unsigned int id
= KSMBD_NO_FID
, pid
= KSMBD_NO_FID
;
6586 void *aux_payload_buf
;
6588 if (test_share_config_flag(work
->tcon
->share_conf
,
6589 KSMBD_SHARE_FLAG_PIPE
)) {
6590 ksmbd_debug(SMB
, "IPC pipe read request\n");
6591 return smb2_read_pipe(work
);
6594 if (work
->next_smb2_rcv_hdr_off
) {
6595 req
= ksmbd_req_buf_next(work
);
6596 rsp
= ksmbd_resp_buf_next(work
);
6597 if (!has_file_id(req
->VolatileFileId
)) {
6598 ksmbd_debug(SMB
, "Compound request set FID = %llu\n",
6599 work
->compound_fid
);
6600 id
= work
->compound_fid
;
6601 pid
= work
->compound_pfid
;
6604 req
= smb2_get_msg(work
->request_buf
);
6605 rsp
= smb2_get_msg(work
->response_buf
);
6608 if (!has_file_id(id
)) {
6609 id
= req
->VolatileFileId
;
6610 pid
= req
->PersistentFileId
;
6613 if (req
->Channel
== SMB2_CHANNEL_RDMA_V1_INVALIDATE
||
6614 req
->Channel
== SMB2_CHANNEL_RDMA_V1
) {
6615 is_rdma_channel
= true;
6616 max_read_size
= get_smbd_max_read_write_size();
6619 if (is_rdma_channel
== true) {
6620 unsigned int ch_offset
= le16_to_cpu(req
->ReadChannelInfoOffset
);
6622 if (ch_offset
< offsetof(struct smb2_read_req
, Buffer
)) {
6626 err
= smb2_set_remote_key_for_rdma(work
,
6627 (struct smb2_buffer_desc_v1
*)
6628 ((char *)req
+ ch_offset
),
6630 req
->ReadChannelInfoLength
);
6635 fp
= ksmbd_lookup_fd_slow(work
, id
, pid
);
6641 if (!(fp
->daccess
& (FILE_READ_DATA_LE
| FILE_READ_ATTRIBUTES_LE
))) {
6642 pr_err("Not permitted to read : 0x%x\n", fp
->daccess
);
6647 offset
= le64_to_cpu(req
->Offset
);
6648 length
= le32_to_cpu(req
->Length
);
6649 mincount
= le32_to_cpu(req
->MinimumCount
);
6651 if (length
> max_read_size
) {
6652 ksmbd_debug(SMB
, "limiting read size to max size(%u)\n",
6658 ksmbd_debug(SMB
, "filename %pD, offset %lld, len %zu\n",
6659 fp
->filp
, offset
, length
);
6661 aux_payload_buf
= kvzalloc(length
, GFP_KERNEL
);
6662 if (!aux_payload_buf
) {
6667 nbytes
= ksmbd_vfs_read(work
, fp
, length
, &offset
, aux_payload_buf
);
6673 if ((nbytes
== 0 && length
!= 0) || nbytes
< mincount
) {
6674 kvfree(aux_payload_buf
);
6675 rsp
->hdr
.Status
= STATUS_END_OF_FILE
;
6676 smb2_set_err_rsp(work
);
6677 ksmbd_fd_put(work
, fp
);
6681 ksmbd_debug(SMB
, "nbytes %zu, offset %lld mincount %zu\n",
6682 nbytes
, offset
, mincount
);
6684 if (is_rdma_channel
== true) {
6685 /* write data to the client using rdma channel */
6686 remain_bytes
= smb2_read_rdma_channel(work
, req
,
6689 kvfree(aux_payload_buf
);
6690 aux_payload_buf
= NULL
;
6692 if (remain_bytes
< 0) {
6693 err
= (int)remain_bytes
;
6698 rsp
->StructureSize
= cpu_to_le16(17);
6699 rsp
->DataOffset
= 80;
6701 rsp
->DataLength
= cpu_to_le32(nbytes
);
6702 rsp
->DataRemaining
= cpu_to_le32(remain_bytes
);
6704 err
= ksmbd_iov_pin_rsp_read(work
, (void *)rsp
,
6705 offsetof(struct smb2_read_rsp
, Buffer
),
6706 aux_payload_buf
, nbytes
);
6708 kvfree(aux_payload_buf
);
6711 ksmbd_fd_put(work
, fp
);
6717 rsp
->hdr
.Status
= STATUS_INVALID_DEVICE_REQUEST
;
6718 else if (err
== -EAGAIN
)
6719 rsp
->hdr
.Status
= STATUS_FILE_LOCK_CONFLICT
;
6720 else if (err
== -ENOENT
)
6721 rsp
->hdr
.Status
= STATUS_FILE_CLOSED
;
6722 else if (err
== -EACCES
)
6723 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
6724 else if (err
== -ESHARE
)
6725 rsp
->hdr
.Status
= STATUS_SHARING_VIOLATION
;
6726 else if (err
== -EINVAL
)
6727 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
6729 rsp
->hdr
.Status
= STATUS_INVALID_HANDLE
;
6731 smb2_set_err_rsp(work
);
6733 ksmbd_fd_put(work
, fp
);
6738 * smb2_write_pipe() - handler for smb2 write on IPC pipe
6739 * @work: smb work containing write IPC pipe command buffer
6741 * Return: 0 on success, otherwise error
6743 static noinline
int smb2_write_pipe(struct ksmbd_work
*work
)
6745 struct smb2_write_req
*req
;
6746 struct smb2_write_rsp
*rsp
;
6747 struct ksmbd_rpc_command
*rpc_resp
;
6749 int err
= 0, ret
= 0;
6753 WORK_BUFFERS(work
, req
, rsp
);
6755 length
= le32_to_cpu(req
->Length
);
6756 id
= req
->VolatileFileId
;
6758 if ((u64
)le16_to_cpu(req
->DataOffset
) + length
>
6759 get_rfc1002_len(work
->request_buf
)) {
6760 pr_err("invalid write data offset %u, smb_len %u\n",
6761 le16_to_cpu(req
->DataOffset
),
6762 get_rfc1002_len(work
->request_buf
));
6767 data_buf
= (char *)(((char *)&req
->hdr
.ProtocolId
) +
6768 le16_to_cpu(req
->DataOffset
));
6770 rpc_resp
= ksmbd_rpc_write(work
->sess
, id
, data_buf
, length
);
6772 if (rpc_resp
->flags
== KSMBD_RPC_ENOTIMPLEMENTED
) {
6773 rsp
->hdr
.Status
= STATUS_NOT_SUPPORTED
;
6775 smb2_set_err_rsp(work
);
6778 if (rpc_resp
->flags
!= KSMBD_RPC_OK
) {
6779 rsp
->hdr
.Status
= STATUS_INVALID_HANDLE
;
6780 smb2_set_err_rsp(work
);
6787 rsp
->StructureSize
= cpu_to_le16(17);
6788 rsp
->DataOffset
= 0;
6790 rsp
->DataLength
= cpu_to_le32(length
);
6791 rsp
->DataRemaining
= 0;
6793 err
= ksmbd_iov_pin_rsp(work
, (void *)rsp
,
6794 offsetof(struct smb2_write_rsp
, Buffer
));
6797 rsp
->hdr
.Status
= STATUS_INVALID_HANDLE
;
6798 smb2_set_err_rsp(work
);
6804 static ssize_t
smb2_write_rdma_channel(struct ksmbd_work
*work
,
6805 struct smb2_write_req
*req
,
6806 struct ksmbd_file
*fp
,
6807 loff_t offset
, size_t length
, bool sync
)
6813 data_buf
= kvzalloc(length
, GFP_KERNEL
);
6817 ret
= ksmbd_conn_rdma_read(work
->conn
, data_buf
, length
,
6818 (struct smb2_buffer_desc_v1
*)
6819 ((char *)req
+ le16_to_cpu(req
->WriteChannelInfoOffset
)),
6820 le16_to_cpu(req
->WriteChannelInfoLength
));
6826 ret
= ksmbd_vfs_write(work
, fp
, data_buf
, length
, &offset
, sync
, &nbytes
);
6835 * smb2_write() - handler for smb2 write from file
6836 * @work: smb work containing write command buffer
6838 * Return: 0 on success, otherwise error
6840 int smb2_write(struct ksmbd_work
*work
)
6842 struct smb2_write_req
*req
;
6843 struct smb2_write_rsp
*rsp
;
6844 struct ksmbd_file
*fp
= NULL
;
6849 bool writethrough
= false, is_rdma_channel
= false;
6851 unsigned int max_write_size
= work
->conn
->vals
->max_write_size
;
6853 WORK_BUFFERS(work
, req
, rsp
);
6855 if (test_share_config_flag(work
->tcon
->share_conf
, KSMBD_SHARE_FLAG_PIPE
)) {
6856 ksmbd_debug(SMB
, "IPC pipe write request\n");
6857 return smb2_write_pipe(work
);
6860 offset
= le64_to_cpu(req
->Offset
);
6861 length
= le32_to_cpu(req
->Length
);
6863 if (req
->Channel
== SMB2_CHANNEL_RDMA_V1
||
6864 req
->Channel
== SMB2_CHANNEL_RDMA_V1_INVALIDATE
) {
6865 is_rdma_channel
= true;
6866 max_write_size
= get_smbd_max_read_write_size();
6867 length
= le32_to_cpu(req
->RemainingBytes
);
6870 if (is_rdma_channel
== true) {
6871 unsigned int ch_offset
= le16_to_cpu(req
->WriteChannelInfoOffset
);
6873 if (req
->Length
!= 0 || req
->DataOffset
!= 0 ||
6874 ch_offset
< offsetof(struct smb2_write_req
, Buffer
)) {
6878 err
= smb2_set_remote_key_for_rdma(work
,
6879 (struct smb2_buffer_desc_v1
*)
6880 ((char *)req
+ ch_offset
),
6882 req
->WriteChannelInfoLength
);
6887 if (!test_tree_conn_flag(work
->tcon
, KSMBD_TREE_CONN_FLAG_WRITABLE
)) {
6888 ksmbd_debug(SMB
, "User does not have write permission\n");
6893 fp
= ksmbd_lookup_fd_slow(work
, req
->VolatileFileId
, req
->PersistentFileId
);
6899 if (!(fp
->daccess
& (FILE_WRITE_DATA_LE
| FILE_READ_ATTRIBUTES_LE
))) {
6900 pr_err("Not permitted to write : 0x%x\n", fp
->daccess
);
6905 if (length
> max_write_size
) {
6906 ksmbd_debug(SMB
, "limiting write size to max size(%u)\n",
6912 ksmbd_debug(SMB
, "flags %u\n", le32_to_cpu(req
->Flags
));
6913 if (le32_to_cpu(req
->Flags
) & SMB2_WRITEFLAG_WRITE_THROUGH
)
6914 writethrough
= true;
6916 if (is_rdma_channel
== false) {
6917 if (le16_to_cpu(req
->DataOffset
) <
6918 offsetof(struct smb2_write_req
, Buffer
)) {
6923 data_buf
= (char *)(((char *)&req
->hdr
.ProtocolId
) +
6924 le16_to_cpu(req
->DataOffset
));
6926 ksmbd_debug(SMB
, "filename %pD, offset %lld, len %zu\n",
6927 fp
->filp
, offset
, length
);
6928 err
= ksmbd_vfs_write(work
, fp
, data_buf
, length
, &offset
,
6929 writethrough
, &nbytes
);
6933 /* read data from the client using rdma channel, and
6936 nbytes
= smb2_write_rdma_channel(work
, req
, fp
, offset
, length
,
6944 rsp
->StructureSize
= cpu_to_le16(17);
6945 rsp
->DataOffset
= 0;
6947 rsp
->DataLength
= cpu_to_le32(nbytes
);
6948 rsp
->DataRemaining
= 0;
6950 err
= ksmbd_iov_pin_rsp(work
, rsp
, offsetof(struct smb2_write_rsp
, Buffer
));
6953 ksmbd_fd_put(work
, fp
);
6958 rsp
->hdr
.Status
= STATUS_FILE_LOCK_CONFLICT
;
6959 else if (err
== -ENOSPC
|| err
== -EFBIG
)
6960 rsp
->hdr
.Status
= STATUS_DISK_FULL
;
6961 else if (err
== -ENOENT
)
6962 rsp
->hdr
.Status
= STATUS_FILE_CLOSED
;
6963 else if (err
== -EACCES
)
6964 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
6965 else if (err
== -ESHARE
)
6966 rsp
->hdr
.Status
= STATUS_SHARING_VIOLATION
;
6967 else if (err
== -EINVAL
)
6968 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
6970 rsp
->hdr
.Status
= STATUS_INVALID_HANDLE
;
6972 smb2_set_err_rsp(work
);
6973 ksmbd_fd_put(work
, fp
);
6978 * smb2_flush() - handler for smb2 flush file - fsync
6979 * @work: smb work containing flush command buffer
6981 * Return: 0 on success, otherwise error
6983 int smb2_flush(struct ksmbd_work
*work
)
6985 struct smb2_flush_req
*req
;
6986 struct smb2_flush_rsp
*rsp
;
6989 WORK_BUFFERS(work
, req
, rsp
);
6991 ksmbd_debug(SMB
, "SMB2_FLUSH called for fid %llu\n", req
->VolatileFileId
);
6993 err
= ksmbd_vfs_fsync(work
, req
->VolatileFileId
, req
->PersistentFileId
);
6997 rsp
->StructureSize
= cpu_to_le16(4);
6999 return ksmbd_iov_pin_rsp(work
, rsp
, sizeof(struct smb2_flush_rsp
));
7002 rsp
->hdr
.Status
= STATUS_INVALID_HANDLE
;
7003 smb2_set_err_rsp(work
);
7008 * smb2_cancel() - handler for smb2 cancel command
7009 * @work: smb work containing cancel command buffer
7011 * Return: 0 on success, otherwise error
7013 int smb2_cancel(struct ksmbd_work
*work
)
7015 struct ksmbd_conn
*conn
= work
->conn
;
7016 struct smb2_hdr
*hdr
= smb2_get_msg(work
->request_buf
);
7017 struct smb2_hdr
*chdr
;
7018 struct ksmbd_work
*iter
;
7019 struct list_head
*command_list
;
7021 if (work
->next_smb2_rcv_hdr_off
)
7022 hdr
= ksmbd_resp_buf_next(work
);
7024 ksmbd_debug(SMB
, "smb2 cancel called on mid %llu, async flags 0x%x\n",
7025 hdr
->MessageId
, hdr
->Flags
);
7027 if (hdr
->Flags
& SMB2_FLAGS_ASYNC_COMMAND
) {
7028 command_list
= &conn
->async_requests
;
7030 spin_lock(&conn
->request_lock
);
7031 list_for_each_entry(iter
, command_list
,
7032 async_request_entry
) {
7033 chdr
= smb2_get_msg(iter
->request_buf
);
7035 if (iter
->async_id
!=
7036 le64_to_cpu(hdr
->Id
.AsyncId
))
7040 "smb2 with AsyncId %llu cancelled command = 0x%x\n",
7041 le64_to_cpu(hdr
->Id
.AsyncId
),
7042 le16_to_cpu(chdr
->Command
));
7043 iter
->state
= KSMBD_WORK_CANCELLED
;
7044 if (iter
->cancel_fn
)
7045 iter
->cancel_fn(iter
->cancel_argv
);
7048 spin_unlock(&conn
->request_lock
);
7050 command_list
= &conn
->requests
;
7052 spin_lock(&conn
->request_lock
);
7053 list_for_each_entry(iter
, command_list
, request_entry
) {
7054 chdr
= smb2_get_msg(iter
->request_buf
);
7056 if (chdr
->MessageId
!= hdr
->MessageId
||
7061 "smb2 with mid %llu cancelled command = 0x%x\n",
7062 le64_to_cpu(hdr
->MessageId
),
7063 le16_to_cpu(chdr
->Command
));
7064 iter
->state
= KSMBD_WORK_CANCELLED
;
7067 spin_unlock(&conn
->request_lock
);
7070 /* For SMB2_CANCEL command itself send no response*/
7071 work
->send_no_response
= 1;
7075 struct file_lock
*smb_flock_init(struct file
*f
)
7077 struct file_lock
*fl
;
7079 fl
= locks_alloc_lock();
7083 locks_init_lock(fl
);
7085 fl
->c
.flc_owner
= f
;
7086 fl
->c
.flc_pid
= current
->tgid
;
7088 fl
->c
.flc_flags
= FL_POSIX
;
7090 fl
->fl_lmops
= NULL
;
7096 static int smb2_set_flock_flags(struct file_lock
*flock
, int flags
)
7100 /* Checking for wrong flag combination during lock request*/
7102 case SMB2_LOCKFLAG_SHARED
:
7103 ksmbd_debug(SMB
, "received shared request\n");
7105 flock
->c
.flc_type
= F_RDLCK
;
7106 flock
->c
.flc_flags
|= FL_SLEEP
;
7108 case SMB2_LOCKFLAG_EXCLUSIVE
:
7109 ksmbd_debug(SMB
, "received exclusive request\n");
7111 flock
->c
.flc_type
= F_WRLCK
;
7112 flock
->c
.flc_flags
|= FL_SLEEP
;
7114 case SMB2_LOCKFLAG_SHARED
| SMB2_LOCKFLAG_FAIL_IMMEDIATELY
:
7116 "received shared & fail immediately request\n");
7118 flock
->c
.flc_type
= F_RDLCK
;
7120 case SMB2_LOCKFLAG_EXCLUSIVE
| SMB2_LOCKFLAG_FAIL_IMMEDIATELY
:
7122 "received exclusive & fail immediately request\n");
7124 flock
->c
.flc_type
= F_WRLCK
;
7126 case SMB2_LOCKFLAG_UNLOCK
:
7127 ksmbd_debug(SMB
, "received unlock request\n");
7128 flock
->c
.flc_type
= F_UNLCK
;
7136 static struct ksmbd_lock
*smb2_lock_init(struct file_lock
*flock
,
7137 unsigned int cmd
, int flags
,
7138 struct list_head
*lock_list
)
7140 struct ksmbd_lock
*lock
;
7142 lock
= kzalloc(sizeof(struct ksmbd_lock
), GFP_KERNEL
);
7148 lock
->start
= flock
->fl_start
;
7149 lock
->end
= flock
->fl_end
;
7150 lock
->flags
= flags
;
7151 if (lock
->start
== lock
->end
)
7153 INIT_LIST_HEAD(&lock
->clist
);
7154 INIT_LIST_HEAD(&lock
->flist
);
7155 INIT_LIST_HEAD(&lock
->llist
);
7156 list_add_tail(&lock
->llist
, lock_list
);
7161 static void smb2_remove_blocked_lock(void **argv
)
7163 struct file_lock
*flock
= (struct file_lock
*)argv
[0];
7165 ksmbd_vfs_posix_lock_unblock(flock
);
7166 locks_wake_up(flock
);
7169 static inline bool lock_defer_pending(struct file_lock
*fl
)
7171 /* check pending lock waiters */
7172 return waitqueue_active(&fl
->c
.flc_wait
);
7176 * smb2_lock() - handler for smb2 file lock command
7177 * @work: smb work containing lock command buffer
7179 * Return: 0 on success, otherwise error
7181 int smb2_lock(struct ksmbd_work
*work
)
7183 struct smb2_lock_req
*req
;
7184 struct smb2_lock_rsp
*rsp
;
7185 struct smb2_lock_element
*lock_ele
;
7186 struct ksmbd_file
*fp
= NULL
;
7187 struct file_lock
*flock
= NULL
;
7188 struct file
*filp
= NULL
;
7192 int err
= -EIO
, i
, rc
= 0;
7193 u64 lock_start
, lock_length
;
7194 struct ksmbd_lock
*smb_lock
= NULL
, *cmp_lock
, *tmp
, *tmp2
;
7195 struct ksmbd_conn
*conn
;
7197 LIST_HEAD(lock_list
);
7198 LIST_HEAD(rollback_list
);
7201 WORK_BUFFERS(work
, req
, rsp
);
7203 ksmbd_debug(SMB
, "Received lock request\n");
7204 fp
= ksmbd_lookup_fd_slow(work
, req
->VolatileFileId
, req
->PersistentFileId
);
7206 ksmbd_debug(SMB
, "Invalid file id for lock : %llu\n", req
->VolatileFileId
);
7212 lock_count
= le16_to_cpu(req
->LockCount
);
7213 lock_ele
= req
->locks
;
7215 ksmbd_debug(SMB
, "lock count is %d\n", lock_count
);
7221 for (i
= 0; i
< lock_count
; i
++) {
7222 flags
= le32_to_cpu(lock_ele
[i
].Flags
);
7224 flock
= smb_flock_init(filp
);
7228 cmd
= smb2_set_flock_flags(flock
, flags
);
7230 lock_start
= le64_to_cpu(lock_ele
[i
].Offset
);
7231 lock_length
= le64_to_cpu(lock_ele
[i
].Length
);
7232 if (lock_start
> U64_MAX
- lock_length
) {
7233 pr_err("Invalid lock range requested\n");
7234 rsp
->hdr
.Status
= STATUS_INVALID_LOCK_RANGE
;
7235 locks_free_lock(flock
);
7239 if (lock_start
> OFFSET_MAX
)
7240 flock
->fl_start
= OFFSET_MAX
;
7242 flock
->fl_start
= lock_start
;
7244 lock_length
= le64_to_cpu(lock_ele
[i
].Length
);
7245 if (lock_length
> OFFSET_MAX
- flock
->fl_start
)
7246 lock_length
= OFFSET_MAX
- flock
->fl_start
;
7248 flock
->fl_end
= flock
->fl_start
+ lock_length
;
7250 if (flock
->fl_end
< flock
->fl_start
) {
7252 "the end offset(%llx) is smaller than the start offset(%llx)\n",
7253 flock
->fl_end
, flock
->fl_start
);
7254 rsp
->hdr
.Status
= STATUS_INVALID_LOCK_RANGE
;
7255 locks_free_lock(flock
);
7259 /* Check conflict locks in one request */
7260 list_for_each_entry(cmp_lock
, &lock_list
, llist
) {
7261 if (cmp_lock
->fl
->fl_start
<= flock
->fl_start
&&
7262 cmp_lock
->fl
->fl_end
>= flock
->fl_end
) {
7263 if (cmp_lock
->fl
->c
.flc_type
!= F_UNLCK
&&
7264 flock
->c
.flc_type
!= F_UNLCK
) {
7265 pr_err("conflict two locks in one request\n");
7267 locks_free_lock(flock
);
7273 smb_lock
= smb2_lock_init(flock
, cmd
, flags
, &lock_list
);
7276 locks_free_lock(flock
);
7281 list_for_each_entry_safe(smb_lock
, tmp
, &lock_list
, llist
) {
7282 if (smb_lock
->cmd
< 0) {
7287 if (!(smb_lock
->flags
& SMB2_LOCKFLAG_MASK
)) {
7292 if ((prior_lock
& (SMB2_LOCKFLAG_EXCLUSIVE
| SMB2_LOCKFLAG_SHARED
) &&
7293 smb_lock
->flags
& SMB2_LOCKFLAG_UNLOCK
) ||
7294 (prior_lock
== SMB2_LOCKFLAG_UNLOCK
&&
7295 !(smb_lock
->flags
& SMB2_LOCKFLAG_UNLOCK
))) {
7300 prior_lock
= smb_lock
->flags
;
7302 if (!(smb_lock
->flags
& SMB2_LOCKFLAG_UNLOCK
) &&
7303 !(smb_lock
->flags
& SMB2_LOCKFLAG_FAIL_IMMEDIATELY
))
7307 /* check locks in connection list */
7308 down_read(&conn_list_lock
);
7309 list_for_each_entry(conn
, &conn_list
, conns_list
) {
7310 spin_lock(&conn
->llist_lock
);
7311 list_for_each_entry_safe(cmp_lock
, tmp2
, &conn
->lock_list
, clist
) {
7312 if (file_inode(cmp_lock
->fl
->c
.flc_file
) !=
7313 file_inode(smb_lock
->fl
->c
.flc_file
))
7316 if (lock_is_unlock(smb_lock
->fl
)) {
7317 if (cmp_lock
->fl
->c
.flc_file
== smb_lock
->fl
->c
.flc_file
&&
7318 cmp_lock
->start
== smb_lock
->start
&&
7319 cmp_lock
->end
== smb_lock
->end
&&
7320 !lock_defer_pending(cmp_lock
->fl
)) {
7322 list_del(&cmp_lock
->flist
);
7323 list_del(&cmp_lock
->clist
);
7324 spin_unlock(&conn
->llist_lock
);
7325 up_read(&conn_list_lock
);
7327 locks_free_lock(cmp_lock
->fl
);
7334 if (cmp_lock
->fl
->c
.flc_file
== smb_lock
->fl
->c
.flc_file
) {
7335 if (smb_lock
->flags
& SMB2_LOCKFLAG_SHARED
)
7338 if (cmp_lock
->flags
& SMB2_LOCKFLAG_SHARED
)
7342 /* check zero byte lock range */
7343 if (cmp_lock
->zero_len
&& !smb_lock
->zero_len
&&
7344 cmp_lock
->start
> smb_lock
->start
&&
7345 cmp_lock
->start
< smb_lock
->end
) {
7346 spin_unlock(&conn
->llist_lock
);
7347 up_read(&conn_list_lock
);
7348 pr_err("previous lock conflict with zero byte lock range\n");
7352 if (smb_lock
->zero_len
&& !cmp_lock
->zero_len
&&
7353 smb_lock
->start
> cmp_lock
->start
&&
7354 smb_lock
->start
< cmp_lock
->end
) {
7355 spin_unlock(&conn
->llist_lock
);
7356 up_read(&conn_list_lock
);
7357 pr_err("current lock conflict with zero byte lock range\n");
7361 if (((cmp_lock
->start
<= smb_lock
->start
&&
7362 cmp_lock
->end
> smb_lock
->start
) ||
7363 (cmp_lock
->start
< smb_lock
->end
&&
7364 cmp_lock
->end
>= smb_lock
->end
)) &&
7365 !cmp_lock
->zero_len
&& !smb_lock
->zero_len
) {
7366 spin_unlock(&conn
->llist_lock
);
7367 up_read(&conn_list_lock
);
7368 pr_err("Not allow lock operation on exclusive lock range\n");
7372 spin_unlock(&conn
->llist_lock
);
7374 up_read(&conn_list_lock
);
7376 if (lock_is_unlock(smb_lock
->fl
) && nolock
) {
7377 pr_err("Try to unlock nolocked range\n");
7378 rsp
->hdr
.Status
= STATUS_RANGE_NOT_LOCKED
;
7383 if (smb_lock
->zero_len
) {
7388 flock
= smb_lock
->fl
;
7389 list_del(&smb_lock
->llist
);
7391 rc
= vfs_lock_file(filp
, smb_lock
->cmd
, flock
, NULL
);
7393 if (flags
& SMB2_LOCKFLAG_UNLOCK
) {
7395 ksmbd_debug(SMB
, "File unlocked\n");
7396 } else if (rc
== -ENOENT
) {
7397 rsp
->hdr
.Status
= STATUS_NOT_LOCKED
;
7400 locks_free_lock(flock
);
7403 if (rc
== FILE_LOCK_DEFERRED
) {
7407 "would have to wait for getting lock\n");
7408 list_add(&smb_lock
->llist
, &rollback_list
);
7410 argv
= kmalloc(sizeof(void *), GFP_KERNEL
);
7417 rc
= setup_async_work(work
,
7418 smb2_remove_blocked_lock
,
7425 spin_lock(&fp
->f_lock
);
7426 list_add(&work
->fp_entry
, &fp
->blocked_works
);
7427 spin_unlock(&fp
->f_lock
);
7429 smb2_send_interim_resp(work
, STATUS_PENDING
);
7431 ksmbd_vfs_posix_lock_wait(flock
);
7433 spin_lock(&fp
->f_lock
);
7434 list_del(&work
->fp_entry
);
7435 spin_unlock(&fp
->f_lock
);
7437 if (work
->state
!= KSMBD_WORK_ACTIVE
) {
7438 list_del(&smb_lock
->llist
);
7439 locks_free_lock(flock
);
7441 if (work
->state
== KSMBD_WORK_CANCELLED
) {
7445 smb2_send_interim_resp(work
,
7447 work
->send_no_response
= 1;
7452 STATUS_RANGE_NOT_LOCKED
;
7457 list_del(&smb_lock
->llist
);
7458 release_async_work(work
);
7461 list_add(&smb_lock
->llist
, &rollback_list
);
7462 spin_lock(&work
->conn
->llist_lock
);
7463 list_add_tail(&smb_lock
->clist
,
7464 &work
->conn
->lock_list
);
7465 list_add_tail(&smb_lock
->flist
,
7467 spin_unlock(&work
->conn
->llist_lock
);
7468 ksmbd_debug(SMB
, "successful in taking lock\n");
7475 if (atomic_read(&fp
->f_ci
->op_count
) > 1)
7476 smb_break_all_oplock(work
, fp
);
7478 rsp
->StructureSize
= cpu_to_le16(4);
7479 ksmbd_debug(SMB
, "successful in taking lock\n");
7480 rsp
->hdr
.Status
= STATUS_SUCCESS
;
7482 err
= ksmbd_iov_pin_rsp(work
, rsp
, sizeof(struct smb2_lock_rsp
));
7486 ksmbd_fd_put(work
, fp
);
7490 list_for_each_entry_safe(smb_lock
, tmp
, &lock_list
, llist
) {
7491 locks_free_lock(smb_lock
->fl
);
7492 list_del(&smb_lock
->llist
);
7496 list_for_each_entry_safe(smb_lock
, tmp
, &rollback_list
, llist
) {
7497 struct file_lock
*rlock
= NULL
;
7499 rlock
= smb_flock_init(filp
);
7500 rlock
->c
.flc_type
= F_UNLCK
;
7501 rlock
->fl_start
= smb_lock
->start
;
7502 rlock
->fl_end
= smb_lock
->end
;
7504 rc
= vfs_lock_file(filp
, F_SETLK
, rlock
, NULL
);
7506 pr_err("rollback unlock fail : %d\n", rc
);
7508 list_del(&smb_lock
->llist
);
7509 spin_lock(&work
->conn
->llist_lock
);
7510 if (!list_empty(&smb_lock
->flist
))
7511 list_del(&smb_lock
->flist
);
7512 list_del(&smb_lock
->clist
);
7513 spin_unlock(&work
->conn
->llist_lock
);
7515 locks_free_lock(smb_lock
->fl
);
7516 locks_free_lock(rlock
);
7520 ksmbd_debug(SMB
, "failed in taking lock(flags : %x), err : %d\n", flags
, err
);
7522 if (!rsp
->hdr
.Status
) {
7524 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
7525 else if (err
== -ENOMEM
)
7526 rsp
->hdr
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
7527 else if (err
== -ENOENT
)
7528 rsp
->hdr
.Status
= STATUS_FILE_CLOSED
;
7530 rsp
->hdr
.Status
= STATUS_LOCK_NOT_GRANTED
;
7533 smb2_set_err_rsp(work
);
7534 ksmbd_fd_put(work
, fp
);
7538 static int fsctl_copychunk(struct ksmbd_work
*work
,
7539 struct copychunk_ioctl_req
*ci_req
,
7540 unsigned int cnt_code
,
7541 unsigned int input_count
,
7542 unsigned long long volatile_id
,
7543 unsigned long long persistent_id
,
7544 struct smb2_ioctl_rsp
*rsp
)
7546 struct copychunk_ioctl_rsp
*ci_rsp
;
7547 struct ksmbd_file
*src_fp
= NULL
, *dst_fp
= NULL
;
7548 struct srv_copychunk
*chunks
;
7549 unsigned int i
, chunk_count
, chunk_count_written
= 0;
7550 unsigned int chunk_size_written
= 0;
7551 loff_t total_size_written
= 0;
7554 ci_rsp
= (struct copychunk_ioctl_rsp
*)&rsp
->Buffer
[0];
7556 rsp
->VolatileFileId
= volatile_id
;
7557 rsp
->PersistentFileId
= persistent_id
;
7558 ci_rsp
->ChunksWritten
=
7559 cpu_to_le32(ksmbd_server_side_copy_max_chunk_count());
7560 ci_rsp
->ChunkBytesWritten
=
7561 cpu_to_le32(ksmbd_server_side_copy_max_chunk_size());
7562 ci_rsp
->TotalBytesWritten
=
7563 cpu_to_le32(ksmbd_server_side_copy_max_total_size());
7565 chunks
= (struct srv_copychunk
*)&ci_req
->Chunks
[0];
7566 chunk_count
= le32_to_cpu(ci_req
->ChunkCount
);
7567 if (chunk_count
== 0)
7569 total_size_written
= 0;
7571 /* verify the SRV_COPYCHUNK_COPY packet */
7572 if (chunk_count
> ksmbd_server_side_copy_max_chunk_count() ||
7573 input_count
< offsetof(struct copychunk_ioctl_req
, Chunks
) +
7574 chunk_count
* sizeof(struct srv_copychunk
)) {
7575 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
7579 for (i
= 0; i
< chunk_count
; i
++) {
7580 if (le32_to_cpu(chunks
[i
].Length
) == 0 ||
7581 le32_to_cpu(chunks
[i
].Length
) > ksmbd_server_side_copy_max_chunk_size())
7583 total_size_written
+= le32_to_cpu(chunks
[i
].Length
);
7586 if (i
< chunk_count
||
7587 total_size_written
> ksmbd_server_side_copy_max_total_size()) {
7588 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
7592 src_fp
= ksmbd_lookup_foreign_fd(work
,
7593 le64_to_cpu(ci_req
->ResumeKey
[0]));
7594 dst_fp
= ksmbd_lookup_fd_slow(work
, volatile_id
, persistent_id
);
7597 src_fp
->persistent_id
!= le64_to_cpu(ci_req
->ResumeKey
[1])) {
7598 rsp
->hdr
.Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
7603 rsp
->hdr
.Status
= STATUS_FILE_CLOSED
;
7608 * FILE_READ_DATA should only be included in
7609 * the FSCTL_COPYCHUNK case
7611 if (cnt_code
== FSCTL_COPYCHUNK
&&
7612 !(dst_fp
->daccess
& (FILE_READ_DATA_LE
| FILE_GENERIC_READ_LE
))) {
7613 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
7617 ret
= ksmbd_vfs_copy_file_ranges(work
, src_fp
, dst_fp
,
7618 chunks
, chunk_count
,
7619 &chunk_count_written
,
7620 &chunk_size_written
,
7621 &total_size_written
);
7624 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
7626 rsp
->hdr
.Status
= STATUS_FILE_LOCK_CONFLICT
;
7627 else if (ret
== -EBADF
)
7628 rsp
->hdr
.Status
= STATUS_INVALID_HANDLE
;
7629 else if (ret
== -EFBIG
|| ret
== -ENOSPC
)
7630 rsp
->hdr
.Status
= STATUS_DISK_FULL
;
7631 else if (ret
== -EINVAL
)
7632 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
7633 else if (ret
== -EISDIR
)
7634 rsp
->hdr
.Status
= STATUS_FILE_IS_A_DIRECTORY
;
7635 else if (ret
== -E2BIG
)
7636 rsp
->hdr
.Status
= STATUS_INVALID_VIEW_SIZE
;
7638 rsp
->hdr
.Status
= STATUS_UNEXPECTED_IO_ERROR
;
7641 ci_rsp
->ChunksWritten
= cpu_to_le32(chunk_count_written
);
7642 ci_rsp
->ChunkBytesWritten
= cpu_to_le32(chunk_size_written
);
7643 ci_rsp
->TotalBytesWritten
= cpu_to_le32(total_size_written
);
7645 ksmbd_fd_put(work
, src_fp
);
7646 ksmbd_fd_put(work
, dst_fp
);
7650 static __be32
idev_ipv4_address(struct in_device
*idev
)
7654 struct in_ifaddr
*ifa
;
7657 in_dev_for_each_ifa_rcu(ifa
, idev
) {
7658 if (ifa
->ifa_flags
& IFA_F_SECONDARY
)
7661 addr
= ifa
->ifa_address
;
7668 static int fsctl_query_iface_info_ioctl(struct ksmbd_conn
*conn
,
7669 struct smb2_ioctl_rsp
*rsp
,
7670 unsigned int out_buf_len
)
7672 struct network_interface_info_ioctl_rsp
*nii_rsp
= NULL
;
7674 struct net_device
*netdev
;
7675 struct sockaddr_storage_rsp
*sockaddr_storage
;
7677 unsigned long long speed
;
7680 for_each_netdev(&init_net
, netdev
) {
7681 bool ipv4_set
= false;
7683 if (netdev
->type
== ARPHRD_LOOPBACK
)
7686 flags
= dev_get_flags(netdev
);
7687 if (!(flags
& IFF_RUNNING
))
7691 nbytes
+ sizeof(struct network_interface_info_ioctl_rsp
)) {
7696 nii_rsp
= (struct network_interface_info_ioctl_rsp
*)
7697 &rsp
->Buffer
[nbytes
];
7698 nii_rsp
->IfIndex
= cpu_to_le32(netdev
->ifindex
);
7700 nii_rsp
->Capability
= 0;
7701 if (netdev
->real_num_tx_queues
> 1)
7702 nii_rsp
->Capability
|= cpu_to_le32(RSS_CAPABLE
);
7703 if (ksmbd_rdma_capable_netdev(netdev
))
7704 nii_rsp
->Capability
|= cpu_to_le32(RDMA_CAPABLE
);
7706 nii_rsp
->Next
= cpu_to_le32(152);
7707 nii_rsp
->Reserved
= 0;
7709 if (netdev
->ethtool_ops
->get_link_ksettings
) {
7710 struct ethtool_link_ksettings cmd
;
7712 netdev
->ethtool_ops
->get_link_ksettings(netdev
, &cmd
);
7713 speed
= cmd
.base
.speed
;
7715 ksmbd_debug(SMB
, "%s %s\n", netdev
->name
,
7716 "speed is unknown, defaulting to 1Gb/sec");
7721 nii_rsp
->LinkSpeed
= cpu_to_le64(speed
);
7723 sockaddr_storage
= (struct sockaddr_storage_rsp
*)
7724 nii_rsp
->SockAddr_Storage
;
7725 memset(sockaddr_storage
, 0, 128);
7728 struct in_device
*idev
;
7730 sockaddr_storage
->Family
= cpu_to_le16(INTERNETWORK
);
7731 sockaddr_storage
->addr4
.Port
= 0;
7733 idev
= __in_dev_get_rtnl(netdev
);
7736 sockaddr_storage
->addr4
.IPv4address
=
7737 idev_ipv4_address(idev
);
7738 nbytes
+= sizeof(struct network_interface_info_ioctl_rsp
);
7742 struct inet6_dev
*idev6
;
7743 struct inet6_ifaddr
*ifa
;
7744 __u8
*ipv6_addr
= sockaddr_storage
->addr6
.IPv6address
;
7746 sockaddr_storage
->Family
= cpu_to_le16(INTERNETWORKV6
);
7747 sockaddr_storage
->addr6
.Port
= 0;
7748 sockaddr_storage
->addr6
.FlowInfo
= 0;
7750 idev6
= __in6_dev_get(netdev
);
7754 list_for_each_entry(ifa
, &idev6
->addr_list
, if_list
) {
7755 if (ifa
->flags
& (IFA_F_TENTATIVE
|
7758 memcpy(ipv6_addr
, ifa
->addr
.s6_addr
, 16);
7761 sockaddr_storage
->addr6
.ScopeId
= 0;
7762 nbytes
+= sizeof(struct network_interface_info_ioctl_rsp
);
7767 /* zero if this is last one */
7771 rsp
->PersistentFileId
= SMB2_NO_FID
;
7772 rsp
->VolatileFileId
= SMB2_NO_FID
;
7776 static int fsctl_validate_negotiate_info(struct ksmbd_conn
*conn
,
7777 struct validate_negotiate_info_req
*neg_req
,
7778 struct validate_negotiate_info_rsp
*neg_rsp
,
7779 unsigned int in_buf_len
)
7784 if (in_buf_len
< offsetof(struct validate_negotiate_info_req
, Dialects
) +
7785 le16_to_cpu(neg_req
->DialectCount
) * sizeof(__le16
))
7788 dialect
= ksmbd_lookup_dialect_by_id(neg_req
->Dialects
,
7789 neg_req
->DialectCount
);
7790 if (dialect
== BAD_PROT_ID
|| dialect
!= conn
->dialect
) {
7795 if (strncmp(neg_req
->Guid
, conn
->ClientGUID
, SMB2_CLIENT_GUID_SIZE
)) {
7800 if (le16_to_cpu(neg_req
->SecurityMode
) != conn
->cli_sec_mode
) {
7805 if (le32_to_cpu(neg_req
->Capabilities
) != conn
->cli_cap
) {
7810 neg_rsp
->Capabilities
= cpu_to_le32(conn
->vals
->capabilities
);
7811 memset(neg_rsp
->Guid
, 0, SMB2_CLIENT_GUID_SIZE
);
7812 neg_rsp
->SecurityMode
= cpu_to_le16(conn
->srv_sec_mode
);
7813 neg_rsp
->Dialect
= cpu_to_le16(conn
->dialect
);
7818 static int fsctl_query_allocated_ranges(struct ksmbd_work
*work
, u64 id
,
7819 struct file_allocated_range_buffer
*qar_req
,
7820 struct file_allocated_range_buffer
*qar_rsp
,
7821 unsigned int in_count
, unsigned int *out_count
)
7823 struct ksmbd_file
*fp
;
7824 loff_t start
, length
;
7831 start
= le64_to_cpu(qar_req
->file_offset
);
7832 length
= le64_to_cpu(qar_req
->length
);
7834 if (start
< 0 || length
< 0)
7837 fp
= ksmbd_lookup_fd_fast(work
, id
);
7841 ret
= ksmbd_vfs_fqar_lseek(fp
, start
, length
,
7842 qar_rsp
, in_count
, out_count
);
7843 if (ret
&& ret
!= -E2BIG
)
7846 ksmbd_fd_put(work
, fp
);
7850 static int fsctl_pipe_transceive(struct ksmbd_work
*work
, u64 id
,
7851 unsigned int out_buf_len
,
7852 struct smb2_ioctl_req
*req
,
7853 struct smb2_ioctl_rsp
*rsp
)
7855 struct ksmbd_rpc_command
*rpc_resp
;
7856 char *data_buf
= (char *)req
+ le32_to_cpu(req
->InputOffset
);
7859 rpc_resp
= ksmbd_rpc_ioctl(work
->sess
, id
, data_buf
,
7860 le32_to_cpu(req
->InputCount
));
7862 if (rpc_resp
->flags
== KSMBD_RPC_SOME_NOT_MAPPED
) {
7864 * set STATUS_SOME_NOT_MAPPED response
7865 * for unknown domain sid.
7867 rsp
->hdr
.Status
= STATUS_SOME_NOT_MAPPED
;
7868 } else if (rpc_resp
->flags
== KSMBD_RPC_ENOTIMPLEMENTED
) {
7869 rsp
->hdr
.Status
= STATUS_NOT_SUPPORTED
;
7871 } else if (rpc_resp
->flags
!= KSMBD_RPC_OK
) {
7872 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
7876 nbytes
= rpc_resp
->payload_sz
;
7877 if (rpc_resp
->payload_sz
> out_buf_len
) {
7878 rsp
->hdr
.Status
= STATUS_BUFFER_OVERFLOW
;
7879 nbytes
= out_buf_len
;
7882 if (!rpc_resp
->payload_sz
) {
7884 STATUS_UNEXPECTED_IO_ERROR
;
7888 memcpy((char *)rsp
->Buffer
, rpc_resp
->payload
, nbytes
);
7895 static inline int fsctl_set_sparse(struct ksmbd_work
*work
, u64 id
,
7896 struct file_sparse
*sparse
)
7898 struct ksmbd_file
*fp
;
7899 struct mnt_idmap
*idmap
;
7903 fp
= ksmbd_lookup_fd_fast(work
, id
);
7906 idmap
= file_mnt_idmap(fp
->filp
);
7908 old_fattr
= fp
->f_ci
->m_fattr
;
7909 if (sparse
->SetSparse
)
7910 fp
->f_ci
->m_fattr
|= FILE_ATTRIBUTE_SPARSE_FILE_LE
;
7912 fp
->f_ci
->m_fattr
&= ~FILE_ATTRIBUTE_SPARSE_FILE_LE
;
7914 if (fp
->f_ci
->m_fattr
!= old_fattr
&&
7915 test_share_config_flag(work
->tcon
->share_conf
,
7916 KSMBD_SHARE_FLAG_STORE_DOS_ATTRS
)) {
7917 struct xattr_dos_attrib da
;
7919 ret
= ksmbd_vfs_get_dos_attrib_xattr(idmap
,
7920 fp
->filp
->f_path
.dentry
, &da
);
7924 da
.attr
= le32_to_cpu(fp
->f_ci
->m_fattr
);
7925 ret
= ksmbd_vfs_set_dos_attrib_xattr(idmap
,
7929 fp
->f_ci
->m_fattr
= old_fattr
;
7933 ksmbd_fd_put(work
, fp
);
7937 static int fsctl_request_resume_key(struct ksmbd_work
*work
,
7938 struct smb2_ioctl_req
*req
,
7939 struct resume_key_ioctl_rsp
*key_rsp
)
7941 struct ksmbd_file
*fp
;
7943 fp
= ksmbd_lookup_fd_slow(work
, req
->VolatileFileId
, req
->PersistentFileId
);
7947 memset(key_rsp
, 0, sizeof(*key_rsp
));
7948 key_rsp
->ResumeKey
[0] = req
->VolatileFileId
;
7949 key_rsp
->ResumeKey
[1] = req
->PersistentFileId
;
7950 ksmbd_fd_put(work
, fp
);
7956 * smb2_ioctl() - handler for smb2 ioctl command
7957 * @work: smb work containing ioctl command buffer
7959 * Return: 0 on success, otherwise error
7961 int smb2_ioctl(struct ksmbd_work
*work
)
7963 struct smb2_ioctl_req
*req
;
7964 struct smb2_ioctl_rsp
*rsp
;
7965 unsigned int cnt_code
, nbytes
= 0, out_buf_len
, in_buf_len
;
7966 u64 id
= KSMBD_NO_FID
;
7967 struct ksmbd_conn
*conn
= work
->conn
;
7971 if (work
->next_smb2_rcv_hdr_off
) {
7972 req
= ksmbd_req_buf_next(work
);
7973 rsp
= ksmbd_resp_buf_next(work
);
7974 if (!has_file_id(req
->VolatileFileId
)) {
7975 ksmbd_debug(SMB
, "Compound request set FID = %llu\n",
7976 work
->compound_fid
);
7977 id
= work
->compound_fid
;
7980 req
= smb2_get_msg(work
->request_buf
);
7981 rsp
= smb2_get_msg(work
->response_buf
);
7984 if (!has_file_id(id
))
7985 id
= req
->VolatileFileId
;
7987 if (req
->Flags
!= cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL
)) {
7988 rsp
->hdr
.Status
= STATUS_NOT_SUPPORTED
;
7992 buffer
= (char *)req
+ le32_to_cpu(req
->InputOffset
);
7994 cnt_code
= le32_to_cpu(req
->CtlCode
);
7995 ret
= smb2_calc_max_out_buf_len(work
, 48,
7996 le32_to_cpu(req
->MaxOutputResponse
));
7998 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
8001 out_buf_len
= (unsigned int)ret
;
8002 in_buf_len
= le32_to_cpu(req
->InputCount
);
8005 case FSCTL_DFS_GET_REFERRALS
:
8006 case FSCTL_DFS_GET_REFERRALS_EX
:
8007 /* Not support DFS yet */
8008 rsp
->hdr
.Status
= STATUS_FS_DRIVER_REQUIRED
;
8010 case FSCTL_CREATE_OR_GET_OBJECT_ID
:
8012 struct file_object_buf_type1_ioctl_rsp
*obj_buf
;
8014 nbytes
= sizeof(struct file_object_buf_type1_ioctl_rsp
);
8015 obj_buf
= (struct file_object_buf_type1_ioctl_rsp
*)
8019 * TODO: This is dummy implementation to pass smbtorture
8020 * Need to check correct response later
8022 memset(obj_buf
->ObjectId
, 0x0, 16);
8023 memset(obj_buf
->BirthVolumeId
, 0x0, 16);
8024 memset(obj_buf
->BirthObjectId
, 0x0, 16);
8025 memset(obj_buf
->DomainId
, 0x0, 16);
8029 case FSCTL_PIPE_TRANSCEIVE
:
8030 out_buf_len
= min_t(u32
, KSMBD_IPC_MAX_PAYLOAD
, out_buf_len
);
8031 nbytes
= fsctl_pipe_transceive(work
, id
, out_buf_len
, req
, rsp
);
8033 case FSCTL_VALIDATE_NEGOTIATE_INFO
:
8034 if (conn
->dialect
< SMB30_PROT_ID
) {
8039 if (in_buf_len
< offsetof(struct validate_negotiate_info_req
,
8045 if (out_buf_len
< sizeof(struct validate_negotiate_info_rsp
)) {
8050 ret
= fsctl_validate_negotiate_info(conn
,
8051 (struct validate_negotiate_info_req
*)buffer
,
8052 (struct validate_negotiate_info_rsp
*)&rsp
->Buffer
[0],
8057 nbytes
= sizeof(struct validate_negotiate_info_rsp
);
8058 rsp
->PersistentFileId
= SMB2_NO_FID
;
8059 rsp
->VolatileFileId
= SMB2_NO_FID
;
8061 case FSCTL_QUERY_NETWORK_INTERFACE_INFO
:
8062 ret
= fsctl_query_iface_info_ioctl(conn
, rsp
, out_buf_len
);
8067 case FSCTL_REQUEST_RESUME_KEY
:
8068 if (out_buf_len
< sizeof(struct resume_key_ioctl_rsp
)) {
8073 ret
= fsctl_request_resume_key(work
, req
,
8074 (struct resume_key_ioctl_rsp
*)&rsp
->Buffer
[0]);
8077 rsp
->PersistentFileId
= req
->PersistentFileId
;
8078 rsp
->VolatileFileId
= req
->VolatileFileId
;
8079 nbytes
= sizeof(struct resume_key_ioctl_rsp
);
8081 case FSCTL_COPYCHUNK
:
8082 case FSCTL_COPYCHUNK_WRITE
:
8083 if (!test_tree_conn_flag(work
->tcon
, KSMBD_TREE_CONN_FLAG_WRITABLE
)) {
8085 "User does not have write permission\n");
8090 if (in_buf_len
<= sizeof(struct copychunk_ioctl_req
)) {
8095 if (out_buf_len
< sizeof(struct copychunk_ioctl_rsp
)) {
8100 nbytes
= sizeof(struct copychunk_ioctl_rsp
);
8101 rsp
->VolatileFileId
= req
->VolatileFileId
;
8102 rsp
->PersistentFileId
= req
->PersistentFileId
;
8103 fsctl_copychunk(work
,
8104 (struct copychunk_ioctl_req
*)buffer
,
8105 le32_to_cpu(req
->CtlCode
),
8106 le32_to_cpu(req
->InputCount
),
8107 req
->VolatileFileId
,
8108 req
->PersistentFileId
,
8111 case FSCTL_SET_SPARSE
:
8112 if (in_buf_len
< sizeof(struct file_sparse
)) {
8117 ret
= fsctl_set_sparse(work
, id
, (struct file_sparse
*)buffer
);
8121 case FSCTL_SET_ZERO_DATA
:
8123 struct file_zero_data_information
*zero_data
;
8124 struct ksmbd_file
*fp
;
8125 loff_t off
, len
, bfz
;
8127 if (!test_tree_conn_flag(work
->tcon
, KSMBD_TREE_CONN_FLAG_WRITABLE
)) {
8129 "User does not have write permission\n");
8134 if (in_buf_len
< sizeof(struct file_zero_data_information
)) {
8140 (struct file_zero_data_information
*)buffer
;
8142 off
= le64_to_cpu(zero_data
->FileOffset
);
8143 bfz
= le64_to_cpu(zero_data
->BeyondFinalZero
);
8144 if (off
< 0 || bfz
< 0 || off
> bfz
) {
8151 fp
= ksmbd_lookup_fd_fast(work
, id
);
8157 ret
= ksmbd_vfs_zero_data(work
, fp
, off
, len
);
8158 ksmbd_fd_put(work
, fp
);
8164 case FSCTL_QUERY_ALLOCATED_RANGES
:
8165 if (in_buf_len
< sizeof(struct file_allocated_range_buffer
)) {
8170 ret
= fsctl_query_allocated_ranges(work
, id
,
8171 (struct file_allocated_range_buffer
*)buffer
,
8172 (struct file_allocated_range_buffer
*)&rsp
->Buffer
[0],
8174 sizeof(struct file_allocated_range_buffer
), &nbytes
);
8175 if (ret
== -E2BIG
) {
8176 rsp
->hdr
.Status
= STATUS_BUFFER_OVERFLOW
;
8177 } else if (ret
< 0) {
8182 nbytes
*= sizeof(struct file_allocated_range_buffer
);
8184 case FSCTL_GET_REPARSE_POINT
:
8186 struct reparse_data_buffer
*reparse_ptr
;
8187 struct ksmbd_file
*fp
;
8189 reparse_ptr
= (struct reparse_data_buffer
*)&rsp
->Buffer
[0];
8190 fp
= ksmbd_lookup_fd_fast(work
, id
);
8192 pr_err("not found fp!!\n");
8197 reparse_ptr
->ReparseTag
=
8198 smb2_get_reparse_tag_special_file(file_inode(fp
->filp
)->i_mode
);
8199 reparse_ptr
->ReparseDataLength
= 0;
8200 ksmbd_fd_put(work
, fp
);
8201 nbytes
= sizeof(struct reparse_data_buffer
);
8204 case FSCTL_DUPLICATE_EXTENTS_TO_FILE
:
8206 struct ksmbd_file
*fp_in
, *fp_out
= NULL
;
8207 struct duplicate_extents_to_file
*dup_ext
;
8208 loff_t src_off
, dst_off
, length
, cloned
;
8210 if (in_buf_len
< sizeof(struct duplicate_extents_to_file
)) {
8215 dup_ext
= (struct duplicate_extents_to_file
*)buffer
;
8217 fp_in
= ksmbd_lookup_fd_slow(work
, dup_ext
->VolatileFileHandle
,
8218 dup_ext
->PersistentFileHandle
);
8220 pr_err("not found file handle in duplicate extent to file\n");
8225 fp_out
= ksmbd_lookup_fd_fast(work
, id
);
8227 pr_err("not found fp\n");
8232 src_off
= le64_to_cpu(dup_ext
->SourceFileOffset
);
8233 dst_off
= le64_to_cpu(dup_ext
->TargetFileOffset
);
8234 length
= le64_to_cpu(dup_ext
->ByteCount
);
8236 * XXX: It is not clear if FSCTL_DUPLICATE_EXTENTS_TO_FILE
8237 * should fall back to vfs_copy_file_range(). This could be
8238 * beneficial when re-exporting nfs/smb mount, but note that
8239 * this can result in partial copy that returns an error status.
8240 * If/when FSCTL_DUPLICATE_EXTENTS_TO_FILE_EX is implemented,
8241 * fall back to vfs_copy_file_range(), should be avoided when
8242 * the flag DUPLICATE_EXTENTS_DATA_EX_SOURCE_ATOMIC is set.
8244 cloned
= vfs_clone_file_range(fp_in
->filp
, src_off
,
8245 fp_out
->filp
, dst_off
, length
, 0);
8246 if (cloned
== -EXDEV
|| cloned
== -EOPNOTSUPP
) {
8249 } else if (cloned
!= length
) {
8250 cloned
= vfs_copy_file_range(fp_in
->filp
, src_off
,
8251 fp_out
->filp
, dst_off
,
8253 if (cloned
!= length
) {
8262 ksmbd_fd_put(work
, fp_in
);
8263 ksmbd_fd_put(work
, fp_out
);
8269 ksmbd_debug(SMB
, "not implemented yet ioctl command 0x%x\n",
8275 rsp
->CtlCode
= cpu_to_le32(cnt_code
);
8276 rsp
->InputCount
= cpu_to_le32(0);
8277 rsp
->InputOffset
= cpu_to_le32(112);
8278 rsp
->OutputOffset
= cpu_to_le32(112);
8279 rsp
->OutputCount
= cpu_to_le32(nbytes
);
8280 rsp
->StructureSize
= cpu_to_le16(49);
8281 rsp
->Reserved
= cpu_to_le16(0);
8282 rsp
->Flags
= cpu_to_le32(0);
8283 rsp
->Reserved2
= cpu_to_le32(0);
8284 ret
= ksmbd_iov_pin_rsp(work
, rsp
, sizeof(struct smb2_ioctl_rsp
) + nbytes
);
8290 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
8291 else if (ret
== -ENOENT
)
8292 rsp
->hdr
.Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
8293 else if (ret
== -EOPNOTSUPP
)
8294 rsp
->hdr
.Status
= STATUS_NOT_SUPPORTED
;
8295 else if (ret
== -ENOSPC
)
8296 rsp
->hdr
.Status
= STATUS_BUFFER_TOO_SMALL
;
8297 else if (ret
< 0 || rsp
->hdr
.Status
== 0)
8298 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
8299 smb2_set_err_rsp(work
);
8304 * smb20_oplock_break_ack() - handler for smb2.0 oplock break command
8305 * @work: smb work containing oplock break command buffer
8309 static void smb20_oplock_break_ack(struct ksmbd_work
*work
)
8311 struct smb2_oplock_break
*req
;
8312 struct smb2_oplock_break
*rsp
;
8313 struct ksmbd_file
*fp
;
8314 struct oplock_info
*opinfo
= NULL
;
8317 u64 volatile_id
, persistent_id
;
8318 char req_oplevel
= 0, rsp_oplevel
= 0;
8319 unsigned int oplock_change_type
;
8321 WORK_BUFFERS(work
, req
, rsp
);
8323 volatile_id
= req
->VolatileFid
;
8324 persistent_id
= req
->PersistentFid
;
8325 req_oplevel
= req
->OplockLevel
;
8326 ksmbd_debug(OPLOCK
, "v_id %llu, p_id %llu request oplock level %d\n",
8327 volatile_id
, persistent_id
, req_oplevel
);
8329 fp
= ksmbd_lookup_fd_slow(work
, volatile_id
, persistent_id
);
8331 rsp
->hdr
.Status
= STATUS_FILE_CLOSED
;
8332 smb2_set_err_rsp(work
);
8336 opinfo
= opinfo_get(fp
);
8338 pr_err("unexpected null oplock_info\n");
8339 rsp
->hdr
.Status
= STATUS_INVALID_OPLOCK_PROTOCOL
;
8340 smb2_set_err_rsp(work
);
8341 ksmbd_fd_put(work
, fp
);
8345 if (opinfo
->level
== SMB2_OPLOCK_LEVEL_NONE
) {
8346 rsp
->hdr
.Status
= STATUS_INVALID_OPLOCK_PROTOCOL
;
8350 if (opinfo
->op_state
== OPLOCK_STATE_NONE
) {
8351 ksmbd_debug(SMB
, "unexpected oplock state 0x%x\n", opinfo
->op_state
);
8352 rsp
->hdr
.Status
= STATUS_UNSUCCESSFUL
;
8356 if ((opinfo
->level
== SMB2_OPLOCK_LEVEL_EXCLUSIVE
||
8357 opinfo
->level
== SMB2_OPLOCK_LEVEL_BATCH
) &&
8358 (req_oplevel
!= SMB2_OPLOCK_LEVEL_II
&&
8359 req_oplevel
!= SMB2_OPLOCK_LEVEL_NONE
)) {
8360 err
= STATUS_INVALID_OPLOCK_PROTOCOL
;
8361 oplock_change_type
= OPLOCK_WRITE_TO_NONE
;
8362 } else if (opinfo
->level
== SMB2_OPLOCK_LEVEL_II
&&
8363 req_oplevel
!= SMB2_OPLOCK_LEVEL_NONE
) {
8364 err
= STATUS_INVALID_OPLOCK_PROTOCOL
;
8365 oplock_change_type
= OPLOCK_READ_TO_NONE
;
8366 } else if (req_oplevel
== SMB2_OPLOCK_LEVEL_II
||
8367 req_oplevel
== SMB2_OPLOCK_LEVEL_NONE
) {
8368 err
= STATUS_INVALID_DEVICE_STATE
;
8369 if ((opinfo
->level
== SMB2_OPLOCK_LEVEL_EXCLUSIVE
||
8370 opinfo
->level
== SMB2_OPLOCK_LEVEL_BATCH
) &&
8371 req_oplevel
== SMB2_OPLOCK_LEVEL_II
) {
8372 oplock_change_type
= OPLOCK_WRITE_TO_READ
;
8373 } else if ((opinfo
->level
== SMB2_OPLOCK_LEVEL_EXCLUSIVE
||
8374 opinfo
->level
== SMB2_OPLOCK_LEVEL_BATCH
) &&
8375 req_oplevel
== SMB2_OPLOCK_LEVEL_NONE
) {
8376 oplock_change_type
= OPLOCK_WRITE_TO_NONE
;
8377 } else if (opinfo
->level
== SMB2_OPLOCK_LEVEL_II
&&
8378 req_oplevel
== SMB2_OPLOCK_LEVEL_NONE
) {
8379 oplock_change_type
= OPLOCK_READ_TO_NONE
;
8381 oplock_change_type
= 0;
8384 oplock_change_type
= 0;
8387 switch (oplock_change_type
) {
8388 case OPLOCK_WRITE_TO_READ
:
8389 ret
= opinfo_write_to_read(opinfo
);
8390 rsp_oplevel
= SMB2_OPLOCK_LEVEL_II
;
8392 case OPLOCK_WRITE_TO_NONE
:
8393 ret
= opinfo_write_to_none(opinfo
);
8394 rsp_oplevel
= SMB2_OPLOCK_LEVEL_NONE
;
8396 case OPLOCK_READ_TO_NONE
:
8397 ret
= opinfo_read_to_none(opinfo
);
8398 rsp_oplevel
= SMB2_OPLOCK_LEVEL_NONE
;
8401 pr_err("unknown oplock change 0x%x -> 0x%x\n",
8402 opinfo
->level
, rsp_oplevel
);
8406 rsp
->hdr
.Status
= err
;
8410 opinfo
->op_state
= OPLOCK_STATE_NONE
;
8411 wake_up_interruptible_all(&opinfo
->oplock_q
);
8413 ksmbd_fd_put(work
, fp
);
8415 rsp
->StructureSize
= cpu_to_le16(24);
8416 rsp
->OplockLevel
= rsp_oplevel
;
8419 rsp
->VolatileFid
= volatile_id
;
8420 rsp
->PersistentFid
= persistent_id
;
8421 ret
= ksmbd_iov_pin_rsp(work
, rsp
, sizeof(struct smb2_oplock_break
));
8426 opinfo
->op_state
= OPLOCK_STATE_NONE
;
8427 wake_up_interruptible_all(&opinfo
->oplock_q
);
8430 ksmbd_fd_put(work
, fp
);
8431 smb2_set_err_rsp(work
);
8434 static int check_lease_state(struct lease
*lease
, __le32 req_state
)
8436 if ((lease
->new_state
==
8437 (SMB2_LEASE_READ_CACHING_LE
| SMB2_LEASE_HANDLE_CACHING_LE
)) &&
8438 !(req_state
& SMB2_LEASE_WRITE_CACHING_LE
)) {
8439 lease
->new_state
= req_state
;
8443 if (lease
->new_state
== req_state
)
8450 * smb21_lease_break_ack() - handler for smb2.1 lease break command
8451 * @work: smb work containing lease break command buffer
8455 static void smb21_lease_break_ack(struct ksmbd_work
*work
)
8457 struct ksmbd_conn
*conn
= work
->conn
;
8458 struct smb2_lease_ack
*req
;
8459 struct smb2_lease_ack
*rsp
;
8460 struct oplock_info
*opinfo
;
8463 unsigned int lease_change_type
;
8465 struct lease
*lease
;
8467 WORK_BUFFERS(work
, req
, rsp
);
8469 ksmbd_debug(OPLOCK
, "smb21 lease break, lease state(0x%x)\n",
8470 le32_to_cpu(req
->LeaseState
));
8471 opinfo
= lookup_lease_in_table(conn
, req
->LeaseKey
);
8473 ksmbd_debug(OPLOCK
, "file not opened\n");
8474 smb2_set_err_rsp(work
);
8475 rsp
->hdr
.Status
= STATUS_UNSUCCESSFUL
;
8478 lease
= opinfo
->o_lease
;
8480 if (opinfo
->op_state
== OPLOCK_STATE_NONE
) {
8481 pr_err("unexpected lease break state 0x%x\n",
8483 rsp
->hdr
.Status
= STATUS_UNSUCCESSFUL
;
8487 if (check_lease_state(lease
, req
->LeaseState
)) {
8488 rsp
->hdr
.Status
= STATUS_REQUEST_NOT_ACCEPTED
;
8490 "req lease state: 0x%x, expected state: 0x%x\n",
8491 req
->LeaseState
, lease
->new_state
);
8495 if (!atomic_read(&opinfo
->breaking_cnt
)) {
8496 rsp
->hdr
.Status
= STATUS_UNSUCCESSFUL
;
8500 /* check for bad lease state */
8501 if (req
->LeaseState
&
8502 (~(SMB2_LEASE_READ_CACHING_LE
| SMB2_LEASE_HANDLE_CACHING_LE
))) {
8503 err
= STATUS_INVALID_OPLOCK_PROTOCOL
;
8504 if (lease
->state
& SMB2_LEASE_WRITE_CACHING_LE
)
8505 lease_change_type
= OPLOCK_WRITE_TO_NONE
;
8507 lease_change_type
= OPLOCK_READ_TO_NONE
;
8508 ksmbd_debug(OPLOCK
, "handle bad lease state 0x%x -> 0x%x\n",
8509 le32_to_cpu(lease
->state
),
8510 le32_to_cpu(req
->LeaseState
));
8511 } else if (lease
->state
== SMB2_LEASE_READ_CACHING_LE
&&
8512 req
->LeaseState
!= SMB2_LEASE_NONE_LE
) {
8513 err
= STATUS_INVALID_OPLOCK_PROTOCOL
;
8514 lease_change_type
= OPLOCK_READ_TO_NONE
;
8515 ksmbd_debug(OPLOCK
, "handle bad lease state 0x%x -> 0x%x\n",
8516 le32_to_cpu(lease
->state
),
8517 le32_to_cpu(req
->LeaseState
));
8519 /* valid lease state changes */
8520 err
= STATUS_INVALID_DEVICE_STATE
;
8521 if (req
->LeaseState
== SMB2_LEASE_NONE_LE
) {
8522 if (lease
->state
& SMB2_LEASE_WRITE_CACHING_LE
)
8523 lease_change_type
= OPLOCK_WRITE_TO_NONE
;
8525 lease_change_type
= OPLOCK_READ_TO_NONE
;
8526 } else if (req
->LeaseState
& SMB2_LEASE_READ_CACHING_LE
) {
8527 if (lease
->state
& SMB2_LEASE_WRITE_CACHING_LE
)
8528 lease_change_type
= OPLOCK_WRITE_TO_READ
;
8530 lease_change_type
= OPLOCK_READ_HANDLE_TO_READ
;
8532 lease_change_type
= 0;
8536 switch (lease_change_type
) {
8537 case OPLOCK_WRITE_TO_READ
:
8538 ret
= opinfo_write_to_read(opinfo
);
8540 case OPLOCK_READ_HANDLE_TO_READ
:
8541 ret
= opinfo_read_handle_to_read(opinfo
);
8543 case OPLOCK_WRITE_TO_NONE
:
8544 ret
= opinfo_write_to_none(opinfo
);
8546 case OPLOCK_READ_TO_NONE
:
8547 ret
= opinfo_read_to_none(opinfo
);
8550 ksmbd_debug(OPLOCK
, "unknown lease change 0x%x -> 0x%x\n",
8551 le32_to_cpu(lease
->state
),
8552 le32_to_cpu(req
->LeaseState
));
8556 rsp
->hdr
.Status
= err
;
8560 lease_state
= lease
->state
;
8561 opinfo
->op_state
= OPLOCK_STATE_NONE
;
8562 wake_up_interruptible_all(&opinfo
->oplock_q
);
8563 atomic_dec(&opinfo
->breaking_cnt
);
8564 wake_up_interruptible_all(&opinfo
->oplock_brk
);
8567 rsp
->StructureSize
= cpu_to_le16(36);
8570 memcpy(rsp
->LeaseKey
, req
->LeaseKey
, 16);
8571 rsp
->LeaseState
= lease_state
;
8572 rsp
->LeaseDuration
= 0;
8573 ret
= ksmbd_iov_pin_rsp(work
, rsp
, sizeof(struct smb2_lease_ack
));
8578 wake_up_interruptible_all(&opinfo
->oplock_q
);
8579 atomic_dec(&opinfo
->breaking_cnt
);
8580 wake_up_interruptible_all(&opinfo
->oplock_brk
);
8583 smb2_set_err_rsp(work
);
8587 * smb2_oplock_break() - dispatcher for smb2.0 and 2.1 oplock/lease break
8588 * @work: smb work containing oplock/lease break command buffer
8592 int smb2_oplock_break(struct ksmbd_work
*work
)
8594 struct smb2_oplock_break
*req
;
8595 struct smb2_oplock_break
*rsp
;
8597 WORK_BUFFERS(work
, req
, rsp
);
8599 switch (le16_to_cpu(req
->StructureSize
)) {
8600 case OP_BREAK_STRUCT_SIZE_20
:
8601 smb20_oplock_break_ack(work
);
8603 case OP_BREAK_STRUCT_SIZE_21
:
8604 smb21_lease_break_ack(work
);
8607 ksmbd_debug(OPLOCK
, "invalid break cmd %d\n",
8608 le16_to_cpu(req
->StructureSize
));
8609 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
8610 smb2_set_err_rsp(work
);
8617 * smb2_notify() - handler for smb2 notify request
8618 * @work: smb work containing notify command buffer
8622 int smb2_notify(struct ksmbd_work
*work
)
8624 struct smb2_change_notify_req
*req
;
8625 struct smb2_change_notify_rsp
*rsp
;
8627 WORK_BUFFERS(work
, req
, rsp
);
8629 if (work
->next_smb2_rcv_hdr_off
&& req
->hdr
.NextCommand
) {
8630 rsp
->hdr
.Status
= STATUS_INTERNAL_ERROR
;
8631 smb2_set_err_rsp(work
);
8635 smb2_set_err_rsp(work
);
8636 rsp
->hdr
.Status
= STATUS_NOT_IMPLEMENTED
;
8641 * smb2_is_sign_req() - handler for checking packet signing status
8642 * @work: smb work containing notify command buffer
8643 * @command: SMB2 command id
8645 * Return: true if packed is signed, false otherwise
8647 bool smb2_is_sign_req(struct ksmbd_work
*work
, unsigned int command
)
8649 struct smb2_hdr
*rcv_hdr2
= smb2_get_msg(work
->request_buf
);
8651 if ((rcv_hdr2
->Flags
& SMB2_FLAGS_SIGNED
) &&
8652 command
!= SMB2_NEGOTIATE_HE
&&
8653 command
!= SMB2_SESSION_SETUP_HE
&&
8654 command
!= SMB2_OPLOCK_BREAK_HE
)
8661 * smb2_check_sign_req() - handler for req packet sign processing
8662 * @work: smb work containing notify command buffer
8664 * Return: 1 on success, 0 otherwise
8666 int smb2_check_sign_req(struct ksmbd_work
*work
)
8668 struct smb2_hdr
*hdr
;
8669 char signature_req
[SMB2_SIGNATURE_SIZE
];
8670 char signature
[SMB2_HMACSHA256_SIZE
];
8674 hdr
= smb2_get_msg(work
->request_buf
);
8675 if (work
->next_smb2_rcv_hdr_off
)
8676 hdr
= ksmbd_req_buf_next(work
);
8678 if (!hdr
->NextCommand
&& !work
->next_smb2_rcv_hdr_off
)
8679 len
= get_rfc1002_len(work
->request_buf
);
8680 else if (hdr
->NextCommand
)
8681 len
= le32_to_cpu(hdr
->NextCommand
);
8683 len
= get_rfc1002_len(work
->request_buf
) -
8684 work
->next_smb2_rcv_hdr_off
;
8686 memcpy(signature_req
, hdr
->Signature
, SMB2_SIGNATURE_SIZE
);
8687 memset(hdr
->Signature
, 0, SMB2_SIGNATURE_SIZE
);
8689 iov
[0].iov_base
= (char *)&hdr
->ProtocolId
;
8690 iov
[0].iov_len
= len
;
8692 if (ksmbd_sign_smb2_pdu(work
->conn
, work
->sess
->sess_key
, iov
, 1,
8696 if (memcmp(signature
, signature_req
, SMB2_SIGNATURE_SIZE
)) {
8697 pr_err("bad smb2 signature\n");
8705 * smb2_set_sign_rsp() - handler for rsp packet sign processing
8706 * @work: smb work containing notify command buffer
8709 void smb2_set_sign_rsp(struct ksmbd_work
*work
)
8711 struct smb2_hdr
*hdr
;
8712 char signature
[SMB2_HMACSHA256_SIZE
];
8716 hdr
= ksmbd_resp_buf_curr(work
);
8717 hdr
->Flags
|= SMB2_FLAGS_SIGNED
;
8718 memset(hdr
->Signature
, 0, SMB2_SIGNATURE_SIZE
);
8720 if (hdr
->Command
== SMB2_READ
) {
8721 iov
= &work
->iov
[work
->iov_idx
- 1];
8724 iov
= &work
->iov
[work
->iov_idx
];
8727 if (!ksmbd_sign_smb2_pdu(work
->conn
, work
->sess
->sess_key
, iov
, n_vec
,
8729 memcpy(hdr
->Signature
, signature
, SMB2_SIGNATURE_SIZE
);
8733 * smb3_check_sign_req() - handler for req packet sign processing
8734 * @work: smb work containing notify command buffer
8736 * Return: 1 on success, 0 otherwise
8738 int smb3_check_sign_req(struct ksmbd_work
*work
)
8740 struct ksmbd_conn
*conn
= work
->conn
;
8742 struct smb2_hdr
*hdr
;
8743 struct channel
*chann
;
8744 char signature_req
[SMB2_SIGNATURE_SIZE
];
8745 char signature
[SMB2_CMACAES_SIZE
];
8749 hdr
= smb2_get_msg(work
->request_buf
);
8750 if (work
->next_smb2_rcv_hdr_off
)
8751 hdr
= ksmbd_req_buf_next(work
);
8753 if (!hdr
->NextCommand
&& !work
->next_smb2_rcv_hdr_off
)
8754 len
= get_rfc1002_len(work
->request_buf
);
8755 else if (hdr
->NextCommand
)
8756 len
= le32_to_cpu(hdr
->NextCommand
);
8758 len
= get_rfc1002_len(work
->request_buf
) -
8759 work
->next_smb2_rcv_hdr_off
;
8761 if (le16_to_cpu(hdr
->Command
) == SMB2_SESSION_SETUP_HE
) {
8762 signing_key
= work
->sess
->smb3signingkey
;
8764 chann
= lookup_chann_list(work
->sess
, conn
);
8768 signing_key
= chann
->smb3signingkey
;
8772 pr_err("SMB3 signing key is not generated\n");
8776 memcpy(signature_req
, hdr
->Signature
, SMB2_SIGNATURE_SIZE
);
8777 memset(hdr
->Signature
, 0, SMB2_SIGNATURE_SIZE
);
8778 iov
[0].iov_base
= (char *)&hdr
->ProtocolId
;
8779 iov
[0].iov_len
= len
;
8781 if (ksmbd_sign_smb3_pdu(conn
, signing_key
, iov
, 1, signature
))
8784 if (memcmp(signature
, signature_req
, SMB2_SIGNATURE_SIZE
)) {
8785 pr_err("bad smb2 signature\n");
8793 * smb3_set_sign_rsp() - handler for rsp packet sign processing
8794 * @work: smb work containing notify command buffer
8797 void smb3_set_sign_rsp(struct ksmbd_work
*work
)
8799 struct ksmbd_conn
*conn
= work
->conn
;
8800 struct smb2_hdr
*hdr
;
8801 struct channel
*chann
;
8802 char signature
[SMB2_CMACAES_SIZE
];
8807 hdr
= ksmbd_resp_buf_curr(work
);
8809 if (conn
->binding
== false &&
8810 le16_to_cpu(hdr
->Command
) == SMB2_SESSION_SETUP_HE
) {
8811 signing_key
= work
->sess
->smb3signingkey
;
8813 chann
= lookup_chann_list(work
->sess
, work
->conn
);
8817 signing_key
= chann
->smb3signingkey
;
8823 hdr
->Flags
|= SMB2_FLAGS_SIGNED
;
8824 memset(hdr
->Signature
, 0, SMB2_SIGNATURE_SIZE
);
8826 if (hdr
->Command
== SMB2_READ
) {
8827 iov
= &work
->iov
[work
->iov_idx
- 1];
8830 iov
= &work
->iov
[work
->iov_idx
];
8833 if (!ksmbd_sign_smb3_pdu(conn
, signing_key
, iov
, n_vec
,
8835 memcpy(hdr
->Signature
, signature
, SMB2_SIGNATURE_SIZE
);
8839 * smb3_preauth_hash_rsp() - handler for computing preauth hash on response
8840 * @work: smb work containing response buffer
8843 void smb3_preauth_hash_rsp(struct ksmbd_work
*work
)
8845 struct ksmbd_conn
*conn
= work
->conn
;
8846 struct ksmbd_session
*sess
= work
->sess
;
8847 struct smb2_hdr
*req
, *rsp
;
8849 if (conn
->dialect
!= SMB311_PROT_ID
)
8852 WORK_BUFFERS(work
, req
, rsp
);
8854 if (le16_to_cpu(req
->Command
) == SMB2_NEGOTIATE_HE
&&
8856 ksmbd_gen_preauth_integrity_hash(conn
, work
->response_buf
,
8857 conn
->preauth_info
->Preauth_HashValue
);
8859 if (le16_to_cpu(rsp
->Command
) == SMB2_SESSION_SETUP_HE
&& sess
) {
8862 if (conn
->binding
) {
8863 struct preauth_session
*preauth_sess
;
8865 preauth_sess
= ksmbd_preauth_session_lookup(conn
, sess
->id
);
8868 hash_value
= preauth_sess
->Preauth_HashValue
;
8870 hash_value
= sess
->Preauth_HashValue
;
8874 ksmbd_gen_preauth_integrity_hash(conn
, work
->response_buf
,
8879 static void fill_transform_hdr(void *tr_buf
, char *old_buf
, __le16 cipher_type
)
8881 struct smb2_transform_hdr
*tr_hdr
= tr_buf
+ 4;
8882 struct smb2_hdr
*hdr
= smb2_get_msg(old_buf
);
8883 unsigned int orig_len
= get_rfc1002_len(old_buf
);
8885 /* tr_buf must be cleared by the caller */
8886 tr_hdr
->ProtocolId
= SMB2_TRANSFORM_PROTO_NUM
;
8887 tr_hdr
->OriginalMessageSize
= cpu_to_le32(orig_len
);
8888 tr_hdr
->Flags
= cpu_to_le16(TRANSFORM_FLAG_ENCRYPTED
);
8889 if (cipher_type
== SMB2_ENCRYPTION_AES128_GCM
||
8890 cipher_type
== SMB2_ENCRYPTION_AES256_GCM
)
8891 get_random_bytes(&tr_hdr
->Nonce
, SMB3_AES_GCM_NONCE
);
8893 get_random_bytes(&tr_hdr
->Nonce
, SMB3_AES_CCM_NONCE
);
8894 memcpy(&tr_hdr
->SessionId
, &hdr
->SessionId
, 8);
8895 inc_rfc1001_len(tr_buf
, sizeof(struct smb2_transform_hdr
));
8896 inc_rfc1001_len(tr_buf
, orig_len
);
8899 int smb3_encrypt_resp(struct ksmbd_work
*work
)
8901 struct kvec
*iov
= work
->iov
;
8905 tr_buf
= kzalloc(sizeof(struct smb2_transform_hdr
) + 4, GFP_KERNEL
);
8909 /* fill transform header */
8910 fill_transform_hdr(tr_buf
, work
->response_buf
, work
->conn
->cipher_type
);
8912 iov
[0].iov_base
= tr_buf
;
8913 iov
[0].iov_len
= sizeof(struct smb2_transform_hdr
) + 4;
8914 work
->tr_buf
= tr_buf
;
8916 return ksmbd_crypt_message(work
, iov
, work
->iov_idx
+ 1, 1);
8919 bool smb3_is_transform_hdr(void *buf
)
8921 struct smb2_transform_hdr
*trhdr
= smb2_get_msg(buf
);
8923 return trhdr
->ProtocolId
== SMB2_TRANSFORM_PROTO_NUM
;
8926 int smb3_decrypt_req(struct ksmbd_work
*work
)
8928 struct ksmbd_session
*sess
;
8929 char *buf
= work
->request_buf
;
8930 unsigned int pdu_length
= get_rfc1002_len(buf
);
8932 int buf_data_size
= pdu_length
- sizeof(struct smb2_transform_hdr
);
8933 struct smb2_transform_hdr
*tr_hdr
= smb2_get_msg(buf
);
8936 if (pdu_length
< sizeof(struct smb2_transform_hdr
) ||
8937 buf_data_size
< sizeof(struct smb2_hdr
)) {
8938 pr_err("Transform message is too small (%u)\n",
8940 return -ECONNABORTED
;
8943 if (buf_data_size
< le32_to_cpu(tr_hdr
->OriginalMessageSize
)) {
8944 pr_err("Transform message is broken\n");
8945 return -ECONNABORTED
;
8948 sess
= ksmbd_session_lookup_all(work
->conn
, le64_to_cpu(tr_hdr
->SessionId
));
8950 pr_err("invalid session id(%llx) in transform header\n",
8951 le64_to_cpu(tr_hdr
->SessionId
));
8952 return -ECONNABORTED
;
8955 iov
[0].iov_base
= buf
;
8956 iov
[0].iov_len
= sizeof(struct smb2_transform_hdr
) + 4;
8957 iov
[1].iov_base
= buf
+ sizeof(struct smb2_transform_hdr
) + 4;
8958 iov
[1].iov_len
= buf_data_size
;
8959 rc
= ksmbd_crypt_message(work
, iov
, 2, 0);
8963 memmove(buf
+ 4, iov
[1].iov_base
, buf_data_size
);
8964 *(__be32
*)buf
= cpu_to_be32(buf_data_size
);
8969 bool smb3_11_final_sess_setup_resp(struct ksmbd_work
*work
)
8971 struct ksmbd_conn
*conn
= work
->conn
;
8972 struct ksmbd_session
*sess
= work
->sess
;
8973 struct smb2_hdr
*rsp
= smb2_get_msg(work
->response_buf
);
8975 if (conn
->dialect
< SMB30_PROT_ID
)
8978 if (work
->next_smb2_rcv_hdr_off
)
8979 rsp
= ksmbd_resp_buf_next(work
);
8981 if (le16_to_cpu(rsp
->Command
) == SMB2_SESSION_SETUP_HE
&&
8982 sess
->user
&& !user_guest(sess
->user
) &&
8983 rsp
->Status
== STATUS_SUCCESS
)