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>
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 "smbstatus.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
= work
->request_buf
;
49 *rsp
= 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 struct channel
*chann
;
80 list_for_each_entry(chann
, &sess
->ksmbd_chann_list
, chann_list
) {
81 if (chann
->conn
== conn
)
89 * smb2_get_ksmbd_tcon() - get tree connection information using a tree id.
92 * Return: 0 if there is a tree connection matched or these are
93 * skipable commands, otherwise error
95 int smb2_get_ksmbd_tcon(struct ksmbd_work
*work
)
97 struct smb2_hdr
*req_hdr
= work
->request_buf
;
101 if (work
->conn
->ops
->get_cmd_val(work
) == SMB2_TREE_CONNECT_HE
||
102 work
->conn
->ops
->get_cmd_val(work
) == SMB2_CANCEL_HE
||
103 work
->conn
->ops
->get_cmd_val(work
) == SMB2_LOGOFF_HE
) {
104 ksmbd_debug(SMB
, "skip to check tree connect request\n");
108 if (xa_empty(&work
->sess
->tree_conns
)) {
109 ksmbd_debug(SMB
, "NO tree connected\n");
113 tree_id
= le32_to_cpu(req_hdr
->Id
.SyncId
.TreeId
);
114 work
->tcon
= ksmbd_tree_conn_lookup(work
->sess
, tree_id
);
116 pr_err("Invalid tid %d\n", tree_id
);
124 * smb2_set_err_rsp() - set error response code on smb response
125 * @work: smb work containing response buffer
127 void smb2_set_err_rsp(struct ksmbd_work
*work
)
129 struct smb2_err_rsp
*err_rsp
;
131 if (work
->next_smb2_rcv_hdr_off
)
132 err_rsp
= ksmbd_resp_buf_next(work
);
134 err_rsp
= work
->response_buf
;
136 if (err_rsp
->hdr
.Status
!= STATUS_STOPPED_ON_SYMLINK
) {
137 err_rsp
->StructureSize
= SMB2_ERROR_STRUCTURE_SIZE2_LE
;
138 err_rsp
->ErrorContextCount
= 0;
139 err_rsp
->Reserved
= 0;
140 err_rsp
->ByteCount
= 0;
141 err_rsp
->ErrorData
[0] = 0;
142 inc_rfc1001_len(work
->response_buf
, SMB2_ERROR_STRUCTURE_SIZE2
);
147 * is_smb2_neg_cmd() - is it smb2 negotiation command
148 * @work: smb work containing smb header
150 * Return: true if smb2 negotiation command, otherwise false
152 bool is_smb2_neg_cmd(struct ksmbd_work
*work
)
154 struct smb2_hdr
*hdr
= work
->request_buf
;
156 /* is it SMB2 header ? */
157 if (hdr
->ProtocolId
!= SMB2_PROTO_NUMBER
)
160 /* make sure it is request not response message */
161 if (hdr
->Flags
& SMB2_FLAGS_SERVER_TO_REDIR
)
164 if (hdr
->Command
!= SMB2_NEGOTIATE
)
171 * is_smb2_rsp() - is it smb2 response
172 * @work: smb work containing smb response buffer
174 * Return: true if smb2 response, otherwise false
176 bool is_smb2_rsp(struct ksmbd_work
*work
)
178 struct smb2_hdr
*hdr
= work
->response_buf
;
180 /* is it SMB2 header ? */
181 if (hdr
->ProtocolId
!= SMB2_PROTO_NUMBER
)
184 /* make sure it is response not request message */
185 if (!(hdr
->Flags
& SMB2_FLAGS_SERVER_TO_REDIR
))
192 * get_smb2_cmd_val() - get smb command code from smb header
193 * @work: smb work containing smb request buffer
195 * Return: smb2 request command value
197 u16
get_smb2_cmd_val(struct ksmbd_work
*work
)
199 struct smb2_hdr
*rcv_hdr
;
201 if (work
->next_smb2_rcv_hdr_off
)
202 rcv_hdr
= ksmbd_req_buf_next(work
);
204 rcv_hdr
= work
->request_buf
;
205 return le16_to_cpu(rcv_hdr
->Command
);
209 * set_smb2_rsp_status() - set error response code on smb2 header
210 * @work: smb work containing response buffer
211 * @err: error response code
213 void set_smb2_rsp_status(struct ksmbd_work
*work
, __le32 err
)
215 struct smb2_hdr
*rsp_hdr
;
217 if (work
->next_smb2_rcv_hdr_off
)
218 rsp_hdr
= ksmbd_resp_buf_next(work
);
220 rsp_hdr
= work
->response_buf
;
221 rsp_hdr
->Status
= err
;
222 smb2_set_err_rsp(work
);
226 * init_smb2_neg_rsp() - initialize smb2 response for negotiate command
227 * @work: smb work containing smb request buffer
229 * smb2 negotiate response is sent in reply of smb1 negotiate command for
230 * dialect auto-negotiation.
232 int init_smb2_neg_rsp(struct ksmbd_work
*work
)
234 struct smb2_hdr
*rsp_hdr
;
235 struct smb2_negotiate_rsp
*rsp
;
236 struct ksmbd_conn
*conn
= work
->conn
;
238 if (conn
->need_neg
== false)
241 rsp_hdr
= work
->response_buf
;
243 memset(rsp_hdr
, 0, sizeof(struct smb2_hdr
) + 2);
245 rsp_hdr
->smb2_buf_length
=
246 cpu_to_be32(smb2_hdr_size_no_buflen(conn
->vals
));
248 rsp_hdr
->ProtocolId
= SMB2_PROTO_NUMBER
;
249 rsp_hdr
->StructureSize
= SMB2_HEADER_STRUCTURE_SIZE
;
250 rsp_hdr
->CreditRequest
= cpu_to_le16(2);
251 rsp_hdr
->Command
= SMB2_NEGOTIATE
;
252 rsp_hdr
->Flags
= (SMB2_FLAGS_SERVER_TO_REDIR
);
253 rsp_hdr
->NextCommand
= 0;
254 rsp_hdr
->MessageId
= 0;
255 rsp_hdr
->Id
.SyncId
.ProcessId
= 0;
256 rsp_hdr
->Id
.SyncId
.TreeId
= 0;
257 rsp_hdr
->SessionId
= 0;
258 memset(rsp_hdr
->Signature
, 0, 16);
260 rsp
= work
->response_buf
;
262 WARN_ON(ksmbd_conn_good(work
));
264 rsp
->StructureSize
= cpu_to_le16(65);
265 ksmbd_debug(SMB
, "conn->dialect 0x%x\n", conn
->dialect
);
266 rsp
->DialectRevision
= cpu_to_le16(conn
->dialect
);
267 /* Not setting conn guid rsp->ServerGUID, as it
268 * not used by client for identifying connection
270 rsp
->Capabilities
= cpu_to_le32(conn
->vals
->capabilities
);
271 /* Default Max Message Size till SMB2.0, 64K*/
272 rsp
->MaxTransactSize
= cpu_to_le32(conn
->vals
->max_trans_size
);
273 rsp
->MaxReadSize
= cpu_to_le32(conn
->vals
->max_read_size
);
274 rsp
->MaxWriteSize
= cpu_to_le32(conn
->vals
->max_write_size
);
276 rsp
->SystemTime
= cpu_to_le64(ksmbd_systime());
277 rsp
->ServerStartTime
= 0;
279 rsp
->SecurityBufferOffset
= cpu_to_le16(128);
280 rsp
->SecurityBufferLength
= cpu_to_le16(AUTH_GSS_LENGTH
);
281 ksmbd_copy_gss_neg_header(((char *)(&rsp
->hdr
) +
282 sizeof(rsp
->hdr
.smb2_buf_length
)) +
283 le16_to_cpu(rsp
->SecurityBufferOffset
));
284 inc_rfc1001_len(rsp
, sizeof(struct smb2_negotiate_rsp
) -
285 sizeof(struct smb2_hdr
) - sizeof(rsp
->Buffer
) +
287 rsp
->SecurityMode
= SMB2_NEGOTIATE_SIGNING_ENABLED_LE
;
288 if (server_conf
.signing
== KSMBD_CONFIG_OPT_MANDATORY
)
289 rsp
->SecurityMode
|= SMB2_NEGOTIATE_SIGNING_REQUIRED_LE
;
290 conn
->use_spnego
= true;
292 ksmbd_conn_set_need_negotiate(work
);
297 * smb2_set_rsp_credits() - set number of credits in response buffer
298 * @work: smb work containing smb response buffer
300 int smb2_set_rsp_credits(struct ksmbd_work
*work
)
302 struct smb2_hdr
*req_hdr
= ksmbd_req_buf_next(work
);
303 struct smb2_hdr
*hdr
= ksmbd_resp_buf_next(work
);
304 struct ksmbd_conn
*conn
= work
->conn
;
305 unsigned short credits_requested
, aux_max
;
306 unsigned short credit_charge
, credits_granted
= 0;
308 if (work
->send_no_response
)
311 hdr
->CreditCharge
= req_hdr
->CreditCharge
;
313 if (conn
->total_credits
> conn
->vals
->max_credits
) {
314 hdr
->CreditRequest
= 0;
315 pr_err("Total credits overflow: %d\n", conn
->total_credits
);
319 credit_charge
= max_t(unsigned short,
320 le16_to_cpu(req_hdr
->CreditCharge
), 1);
321 if (credit_charge
> conn
->total_credits
) {
322 ksmbd_debug(SMB
, "Insufficient credits granted, given: %u, granted: %u\n",
323 credit_charge
, conn
->total_credits
);
327 conn
->total_credits
-= credit_charge
;
328 conn
->outstanding_credits
-= credit_charge
;
329 credits_requested
= max_t(unsigned short,
330 le16_to_cpu(req_hdr
->CreditRequest
), 1);
332 /* according to smb2.credits smbtorture, Windows server
333 * 2016 or later grant up to 8192 credits at once.
335 * TODO: Need to adjuct CreditRequest value according to
338 if (hdr
->Command
== SMB2_NEGOTIATE
)
341 aux_max
= conn
->vals
->max_credits
- credit_charge
;
342 credits_granted
= min_t(unsigned short, credits_requested
, aux_max
);
344 if (conn
->vals
->max_credits
- conn
->total_credits
< credits_granted
)
345 credits_granted
= conn
->vals
->max_credits
-
348 conn
->total_credits
+= credits_granted
;
349 work
->credits_granted
+= credits_granted
;
351 if (!req_hdr
->NextCommand
) {
352 /* Update CreditRequest in last request */
353 hdr
->CreditRequest
= cpu_to_le16(work
->credits_granted
);
356 "credits: requested[%d] granted[%d] total_granted[%d]\n",
357 credits_requested
, credits_granted
,
358 conn
->total_credits
);
363 * init_chained_smb2_rsp() - initialize smb2 chained response
364 * @work: smb work containing smb response buffer
366 static void init_chained_smb2_rsp(struct ksmbd_work
*work
)
368 struct smb2_hdr
*req
= ksmbd_req_buf_next(work
);
369 struct smb2_hdr
*rsp
= ksmbd_resp_buf_next(work
);
370 struct smb2_hdr
*rsp_hdr
;
371 struct smb2_hdr
*rcv_hdr
;
372 int next_hdr_offset
= 0;
375 /* Len of this response = updated RFC len - offset of previous cmd
376 * in the compound rsp
379 /* Storing the current local FID which may be needed by subsequent
380 * command in the compound request
382 if (req
->Command
== SMB2_CREATE
&& rsp
->Status
== STATUS_SUCCESS
) {
384 le64_to_cpu(((struct smb2_create_rsp
*)rsp
)->
386 work
->compound_pfid
=
387 le64_to_cpu(((struct smb2_create_rsp
*)rsp
)->
389 work
->compound_sid
= le64_to_cpu(rsp
->SessionId
);
392 len
= get_rfc1002_len(work
->response_buf
) - work
->next_smb2_rsp_hdr_off
;
393 next_hdr_offset
= le32_to_cpu(req
->NextCommand
);
395 new_len
= ALIGN(len
, 8);
396 inc_rfc1001_len(work
->response_buf
, ((sizeof(struct smb2_hdr
) - 4)
398 rsp
->NextCommand
= cpu_to_le32(new_len
);
400 work
->next_smb2_rcv_hdr_off
+= next_hdr_offset
;
401 work
->next_smb2_rsp_hdr_off
+= new_len
;
403 "Compound req new_len = %d rcv off = %d rsp off = %d\n",
404 new_len
, work
->next_smb2_rcv_hdr_off
,
405 work
->next_smb2_rsp_hdr_off
);
407 rsp_hdr
= ksmbd_resp_buf_next(work
);
408 rcv_hdr
= ksmbd_req_buf_next(work
);
410 if (!(rcv_hdr
->Flags
& SMB2_FLAGS_RELATED_OPERATIONS
)) {
411 ksmbd_debug(SMB
, "related flag should be set\n");
412 work
->compound_fid
= KSMBD_NO_FID
;
413 work
->compound_pfid
= KSMBD_NO_FID
;
415 memset((char *)rsp_hdr
+ 4, 0, sizeof(struct smb2_hdr
) + 2);
416 rsp_hdr
->ProtocolId
= SMB2_PROTO_NUMBER
;
417 rsp_hdr
->StructureSize
= SMB2_HEADER_STRUCTURE_SIZE
;
418 rsp_hdr
->Command
= rcv_hdr
->Command
;
421 * Message is response. We don't grant oplock yet.
423 rsp_hdr
->Flags
= (SMB2_FLAGS_SERVER_TO_REDIR
|
424 SMB2_FLAGS_RELATED_OPERATIONS
);
425 rsp_hdr
->NextCommand
= 0;
426 rsp_hdr
->MessageId
= rcv_hdr
->MessageId
;
427 rsp_hdr
->Id
.SyncId
.ProcessId
= rcv_hdr
->Id
.SyncId
.ProcessId
;
428 rsp_hdr
->Id
.SyncId
.TreeId
= rcv_hdr
->Id
.SyncId
.TreeId
;
429 rsp_hdr
->SessionId
= rcv_hdr
->SessionId
;
430 memcpy(rsp_hdr
->Signature
, rcv_hdr
->Signature
, 16);
434 * is_chained_smb2_message() - check for chained command
435 * @work: smb work containing smb request buffer
437 * Return: true if chained request, otherwise false
439 bool is_chained_smb2_message(struct ksmbd_work
*work
)
441 struct smb2_hdr
*hdr
= work
->request_buf
;
442 unsigned int len
, next_cmd
;
444 if (hdr
->ProtocolId
!= SMB2_PROTO_NUMBER
)
447 hdr
= ksmbd_req_buf_next(work
);
448 next_cmd
= le32_to_cpu(hdr
->NextCommand
);
450 if ((u64
)work
->next_smb2_rcv_hdr_off
+ next_cmd
+
451 __SMB2_HEADER_STRUCTURE_SIZE
>
452 get_rfc1002_len(work
->request_buf
)) {
453 pr_err("next command(%u) offset exceeds smb msg size\n",
458 if ((u64
)get_rfc1002_len(work
->response_buf
) + MAX_CIFS_SMALL_BUFFER_SIZE
>
460 pr_err("next response offset exceeds response buffer size\n");
464 ksmbd_debug(SMB
, "got SMB2 chained command\n");
465 init_chained_smb2_rsp(work
);
467 } else if (work
->next_smb2_rcv_hdr_off
) {
469 * This is last request in chained command,
470 * align response to 8 byte
472 len
= ALIGN(get_rfc1002_len(work
->response_buf
), 8);
473 len
= len
- get_rfc1002_len(work
->response_buf
);
475 ksmbd_debug(SMB
, "padding len %u\n", len
);
476 inc_rfc1001_len(work
->response_buf
, len
);
477 if (work
->aux_payload_sz
)
478 work
->aux_payload_sz
+= len
;
485 * init_smb2_rsp_hdr() - initialize smb2 response
486 * @work: smb work containing smb request buffer
490 int init_smb2_rsp_hdr(struct ksmbd_work
*work
)
492 struct smb2_hdr
*rsp_hdr
= work
->response_buf
;
493 struct smb2_hdr
*rcv_hdr
= work
->request_buf
;
494 struct ksmbd_conn
*conn
= work
->conn
;
496 memset(rsp_hdr
, 0, sizeof(struct smb2_hdr
) + 2);
497 rsp_hdr
->smb2_buf_length
=
498 cpu_to_be32(smb2_hdr_size_no_buflen(conn
->vals
));
499 rsp_hdr
->ProtocolId
= rcv_hdr
->ProtocolId
;
500 rsp_hdr
->StructureSize
= SMB2_HEADER_STRUCTURE_SIZE
;
501 rsp_hdr
->Command
= rcv_hdr
->Command
;
504 * Message is response. We don't grant oplock yet.
506 rsp_hdr
->Flags
= (SMB2_FLAGS_SERVER_TO_REDIR
);
507 rsp_hdr
->NextCommand
= 0;
508 rsp_hdr
->MessageId
= rcv_hdr
->MessageId
;
509 rsp_hdr
->Id
.SyncId
.ProcessId
= rcv_hdr
->Id
.SyncId
.ProcessId
;
510 rsp_hdr
->Id
.SyncId
.TreeId
= rcv_hdr
->Id
.SyncId
.TreeId
;
511 rsp_hdr
->SessionId
= rcv_hdr
->SessionId
;
512 memcpy(rsp_hdr
->Signature
, rcv_hdr
->Signature
, 16);
514 work
->syncronous
= true;
515 if (work
->async_id
) {
516 ksmbd_release_id(&conn
->async_ida
, work
->async_id
);
524 * smb2_allocate_rsp_buf() - allocate smb2 response buffer
525 * @work: smb work containing smb request buffer
527 * Return: 0 on success, otherwise -ENOMEM
529 int smb2_allocate_rsp_buf(struct ksmbd_work
*work
)
531 struct smb2_hdr
*hdr
= work
->request_buf
;
532 size_t small_sz
= MAX_CIFS_SMALL_BUFFER_SIZE
;
533 size_t large_sz
= small_sz
+ work
->conn
->vals
->max_trans_size
;
534 size_t sz
= small_sz
;
535 int cmd
= le16_to_cpu(hdr
->Command
);
537 if (cmd
== SMB2_IOCTL_HE
|| cmd
== SMB2_QUERY_DIRECTORY_HE
)
540 if (cmd
== SMB2_QUERY_INFO_HE
) {
541 struct smb2_query_info_req
*req
;
543 req
= work
->request_buf
;
544 if (req
->InfoType
== SMB2_O_INFO_FILE
&&
545 (req
->FileInfoClass
== FILE_FULL_EA_INFORMATION
||
546 req
->FileInfoClass
== FILE_ALL_INFORMATION
))
550 /* allocate large response buf for chained commands */
551 if (le32_to_cpu(hdr
->NextCommand
) > 0)
554 work
->response_buf
= kvmalloc(sz
, GFP_KERNEL
| __GFP_ZERO
);
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
= work
->request_buf
;
571 struct ksmbd_conn
*conn
= work
->conn
;
572 unsigned int cmd
= conn
->ops
->get_cmd_val(work
);
573 unsigned long long sess_id
;
577 * SMB2_ECHO, SMB2_NEGOTIATE, SMB2_SESSION_SETUP command do not
578 * require a session id, so no need to validate user session's for
581 if (cmd
== SMB2_ECHO_HE
|| cmd
== SMB2_NEGOTIATE_HE
||
582 cmd
== SMB2_SESSION_SETUP_HE
)
585 if (!ksmbd_conn_good(work
))
588 sess_id
= le64_to_cpu(req_hdr
->SessionId
);
589 /* Check for validity of user session */
590 work
->sess
= ksmbd_session_lookup_all(conn
, sess_id
);
593 ksmbd_debug(SMB
, "Invalid user session, Uid %llu\n", sess_id
);
597 static void destroy_previous_session(struct ksmbd_user
*user
, u64 id
)
599 struct ksmbd_session
*prev_sess
= ksmbd_session_lookup_slowpath(id
);
600 struct ksmbd_user
*prev_user
;
605 prev_user
= prev_sess
->user
;
608 strcmp(user
->name
, prev_user
->name
) ||
609 user
->passkey_sz
!= prev_user
->passkey_sz
||
610 memcmp(user
->passkey
, prev_user
->passkey
, user
->passkey_sz
)) {
611 put_session(prev_sess
);
615 put_session(prev_sess
);
616 ksmbd_session_destroy(prev_sess
);
620 * smb2_get_name() - get filename string from on the wire smb format
621 * @share: ksmbd_share_config pointer
622 * @src: source buffer
623 * @maxlen: maxlen of source string
624 * @nls_table: nls_table pointer
626 * Return: matching converted filename on success, otherwise error ptr
629 smb2_get_name(struct ksmbd_share_config
*share
, const char *src
,
630 const int maxlen
, struct nls_table
*local_nls
)
634 name
= smb_strndup_from_utf16(src
, maxlen
, 1, local_nls
);
636 pr_err("failed to get name %ld\n", PTR_ERR(name
));
640 ksmbd_conv_path_to_unix(name
);
641 ksmbd_strip_last_slash(name
);
645 int setup_async_work(struct ksmbd_work
*work
, void (*fn
)(void **), void **arg
)
647 struct smb2_hdr
*rsp_hdr
;
648 struct ksmbd_conn
*conn
= work
->conn
;
651 rsp_hdr
= work
->response_buf
;
652 rsp_hdr
->Flags
|= SMB2_FLAGS_ASYNC_COMMAND
;
654 id
= ksmbd_acquire_async_msg_id(&conn
->async_ida
);
656 pr_err("Failed to alloc async message id\n");
659 work
->syncronous
= false;
661 rsp_hdr
->Id
.AsyncId
= cpu_to_le64(id
);
664 "Send interim Response to inform async request id : %d\n",
667 work
->cancel_fn
= fn
;
668 work
->cancel_argv
= arg
;
670 if (list_empty(&work
->async_request_entry
)) {
671 spin_lock(&conn
->request_lock
);
672 list_add_tail(&work
->async_request_entry
, &conn
->async_requests
);
673 spin_unlock(&conn
->request_lock
);
679 void smb2_send_interim_resp(struct ksmbd_work
*work
, __le32 status
)
681 struct smb2_hdr
*rsp_hdr
;
683 rsp_hdr
= work
->response_buf
;
684 smb2_set_err_rsp(work
);
685 rsp_hdr
->Status
= status
;
688 ksmbd_conn_write(work
);
693 static __le32
smb2_get_reparse_tag_special_file(umode_t mode
)
695 if (S_ISDIR(mode
) || S_ISREG(mode
))
699 return IO_REPARSE_TAG_LX_SYMLINK_LE
;
700 else if (S_ISFIFO(mode
))
701 return IO_REPARSE_TAG_LX_FIFO_LE
;
702 else if (S_ISSOCK(mode
))
703 return IO_REPARSE_TAG_AF_UNIX_LE
;
704 else if (S_ISCHR(mode
))
705 return IO_REPARSE_TAG_LX_CHR_LE
;
706 else if (S_ISBLK(mode
))
707 return IO_REPARSE_TAG_LX_BLK_LE
;
713 * smb2_get_dos_mode() - get file mode in dos format from unix mode
714 * @stat: kstat containing file mode
715 * @attribute: attribute flags
717 * Return: converted dos mode
719 static int smb2_get_dos_mode(struct kstat
*stat
, int attribute
)
723 if (S_ISDIR(stat
->mode
)) {
724 attr
= ATTR_DIRECTORY
|
725 (attribute
& (ATTR_HIDDEN
| ATTR_SYSTEM
));
727 attr
= (attribute
& 0x00005137) | ATTR_ARCHIVE
;
728 attr
&= ~(ATTR_DIRECTORY
);
729 if (S_ISREG(stat
->mode
) && (server_conf
.share_fake_fscaps
&
730 FILE_SUPPORTS_SPARSE_FILES
))
733 if (smb2_get_reparse_tag_special_file(stat
->mode
))
734 attr
|= ATTR_REPARSE
;
740 static void build_preauth_ctxt(struct smb2_preauth_neg_context
*pneg_ctxt
,
743 pneg_ctxt
->ContextType
= SMB2_PREAUTH_INTEGRITY_CAPABILITIES
;
744 pneg_ctxt
->DataLength
= cpu_to_le16(38);
745 pneg_ctxt
->HashAlgorithmCount
= cpu_to_le16(1);
746 pneg_ctxt
->Reserved
= cpu_to_le32(0);
747 pneg_ctxt
->SaltLength
= cpu_to_le16(SMB311_SALT_SIZE
);
748 get_random_bytes(pneg_ctxt
->Salt
, SMB311_SALT_SIZE
);
749 pneg_ctxt
->HashAlgorithms
= hash_id
;
752 static void build_encrypt_ctxt(struct smb2_encryption_neg_context
*pneg_ctxt
,
755 pneg_ctxt
->ContextType
= SMB2_ENCRYPTION_CAPABILITIES
;
756 pneg_ctxt
->DataLength
= cpu_to_le16(4);
757 pneg_ctxt
->Reserved
= cpu_to_le32(0);
758 pneg_ctxt
->CipherCount
= cpu_to_le16(1);
759 pneg_ctxt
->Ciphers
[0] = cipher_type
;
762 static void build_compression_ctxt(struct smb2_compression_ctx
*pneg_ctxt
,
765 pneg_ctxt
->ContextType
= SMB2_COMPRESSION_CAPABILITIES
;
766 pneg_ctxt
->DataLength
=
767 cpu_to_le16(sizeof(struct smb2_compression_ctx
)
768 - sizeof(struct smb2_neg_context
));
769 pneg_ctxt
->Reserved
= cpu_to_le32(0);
770 pneg_ctxt
->CompressionAlgorithmCount
= cpu_to_le16(1);
771 pneg_ctxt
->Reserved1
= cpu_to_le32(0);
772 pneg_ctxt
->CompressionAlgorithms
[0] = comp_algo
;
775 static void build_sign_cap_ctxt(struct smb2_signing_capabilities
*pneg_ctxt
,
778 pneg_ctxt
->ContextType
= SMB2_SIGNING_CAPABILITIES
;
779 pneg_ctxt
->DataLength
=
780 cpu_to_le16((sizeof(struct smb2_signing_capabilities
) + 2)
781 - sizeof(struct smb2_neg_context
));
782 pneg_ctxt
->Reserved
= cpu_to_le32(0);
783 pneg_ctxt
->SigningAlgorithmCount
= cpu_to_le16(1);
784 pneg_ctxt
->SigningAlgorithms
[0] = sign_algo
;
787 static void build_posix_ctxt(struct smb2_posix_neg_context
*pneg_ctxt
)
789 pneg_ctxt
->ContextType
= SMB2_POSIX_EXTENSIONS_AVAILABLE
;
790 pneg_ctxt
->DataLength
= cpu_to_le16(POSIX_CTXT_DATA_LEN
);
791 /* SMB2_CREATE_TAG_POSIX is "0x93AD25509CB411E7B42383DE968BCD7C" */
792 pneg_ctxt
->Name
[0] = 0x93;
793 pneg_ctxt
->Name
[1] = 0xAD;
794 pneg_ctxt
->Name
[2] = 0x25;
795 pneg_ctxt
->Name
[3] = 0x50;
796 pneg_ctxt
->Name
[4] = 0x9C;
797 pneg_ctxt
->Name
[5] = 0xB4;
798 pneg_ctxt
->Name
[6] = 0x11;
799 pneg_ctxt
->Name
[7] = 0xE7;
800 pneg_ctxt
->Name
[8] = 0xB4;
801 pneg_ctxt
->Name
[9] = 0x23;
802 pneg_ctxt
->Name
[10] = 0x83;
803 pneg_ctxt
->Name
[11] = 0xDE;
804 pneg_ctxt
->Name
[12] = 0x96;
805 pneg_ctxt
->Name
[13] = 0x8B;
806 pneg_ctxt
->Name
[14] = 0xCD;
807 pneg_ctxt
->Name
[15] = 0x7C;
810 static void assemble_neg_contexts(struct ksmbd_conn
*conn
,
811 struct smb2_negotiate_rsp
*rsp
)
813 /* +4 is to account for the RFC1001 len field */
814 char *pneg_ctxt
= (char *)rsp
+
815 le32_to_cpu(rsp
->NegotiateContextOffset
) + 4;
816 int neg_ctxt_cnt
= 1;
820 "assemble SMB2_PREAUTH_INTEGRITY_CAPABILITIES context\n");
821 build_preauth_ctxt((struct smb2_preauth_neg_context
*)pneg_ctxt
,
822 conn
->preauth_info
->Preauth_HashId
);
823 rsp
->NegotiateContextCount
= cpu_to_le16(neg_ctxt_cnt
);
824 inc_rfc1001_len(rsp
, AUTH_GSS_PADDING
);
825 ctxt_size
= sizeof(struct smb2_preauth_neg_context
);
826 /* Round to 8 byte boundary */
827 pneg_ctxt
+= round_up(sizeof(struct smb2_preauth_neg_context
), 8);
829 if (conn
->cipher_type
) {
830 ctxt_size
= round_up(ctxt_size
, 8);
832 "assemble SMB2_ENCRYPTION_CAPABILITIES context\n");
833 build_encrypt_ctxt((struct smb2_encryption_neg_context
*)pneg_ctxt
,
835 rsp
->NegotiateContextCount
= cpu_to_le16(++neg_ctxt_cnt
);
836 ctxt_size
+= sizeof(struct smb2_encryption_neg_context
) + 2;
837 /* Round to 8 byte boundary */
839 round_up(sizeof(struct smb2_encryption_neg_context
) + 2,
843 if (conn
->compress_algorithm
) {
844 ctxt_size
= round_up(ctxt_size
, 8);
846 "assemble SMB2_COMPRESSION_CAPABILITIES context\n");
847 /* Temporarily set to SMB3_COMPRESS_NONE */
848 build_compression_ctxt((struct smb2_compression_ctx
*)pneg_ctxt
,
849 conn
->compress_algorithm
);
850 rsp
->NegotiateContextCount
= cpu_to_le16(++neg_ctxt_cnt
);
851 ctxt_size
+= sizeof(struct smb2_compression_ctx
) + 2;
852 /* Round to 8 byte boundary */
853 pneg_ctxt
+= round_up(sizeof(struct smb2_compression_ctx
) + 2,
857 if (conn
->posix_ext_supported
) {
858 ctxt_size
= round_up(ctxt_size
, 8);
860 "assemble SMB2_POSIX_EXTENSIONS_AVAILABLE context\n");
861 build_posix_ctxt((struct smb2_posix_neg_context
*)pneg_ctxt
);
862 rsp
->NegotiateContextCount
= cpu_to_le16(++neg_ctxt_cnt
);
863 ctxt_size
+= sizeof(struct smb2_posix_neg_context
);
864 /* Round to 8 byte boundary */
865 pneg_ctxt
+= round_up(sizeof(struct smb2_posix_neg_context
), 8);
868 if (conn
->signing_negotiated
) {
869 ctxt_size
= round_up(ctxt_size
, 8);
871 "assemble SMB2_SIGNING_CAPABILITIES context\n");
872 build_sign_cap_ctxt((struct smb2_signing_capabilities
*)pneg_ctxt
,
873 conn
->signing_algorithm
);
874 rsp
->NegotiateContextCount
= cpu_to_le16(++neg_ctxt_cnt
);
875 ctxt_size
+= sizeof(struct smb2_signing_capabilities
) + 2;
878 inc_rfc1001_len(rsp
, ctxt_size
);
881 static __le32
decode_preauth_ctxt(struct ksmbd_conn
*conn
,
882 struct smb2_preauth_neg_context
*pneg_ctxt
)
884 __le32 err
= STATUS_NO_PREAUTH_INTEGRITY_HASH_OVERLAP
;
886 if (pneg_ctxt
->HashAlgorithms
== SMB2_PREAUTH_INTEGRITY_SHA512
) {
887 conn
->preauth_info
->Preauth_HashId
=
888 SMB2_PREAUTH_INTEGRITY_SHA512
;
889 err
= STATUS_SUCCESS
;
895 static void decode_encrypt_ctxt(struct ksmbd_conn
*conn
,
896 struct smb2_encryption_neg_context
*pneg_ctxt
,
899 int cph_cnt
= le16_to_cpu(pneg_ctxt
->CipherCount
);
900 int i
, cphs_size
= cph_cnt
* sizeof(__le16
);
902 conn
->cipher_type
= 0;
904 if (sizeof(struct smb2_encryption_neg_context
) + cphs_size
>
906 pr_err("Invalid cipher count(%d)\n", cph_cnt
);
910 if (!(server_conf
.flags
& KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION
))
913 for (i
= 0; i
< cph_cnt
; i
++) {
914 if (pneg_ctxt
->Ciphers
[i
] == SMB2_ENCRYPTION_AES128_GCM
||
915 pneg_ctxt
->Ciphers
[i
] == SMB2_ENCRYPTION_AES128_CCM
||
916 pneg_ctxt
->Ciphers
[i
] == SMB2_ENCRYPTION_AES256_CCM
||
917 pneg_ctxt
->Ciphers
[i
] == SMB2_ENCRYPTION_AES256_GCM
) {
918 ksmbd_debug(SMB
, "Cipher ID = 0x%x\n",
919 pneg_ctxt
->Ciphers
[i
]);
920 conn
->cipher_type
= pneg_ctxt
->Ciphers
[i
];
927 * smb3_encryption_negotiated() - checks if server and client agreed on enabling encryption
928 * @conn: smb connection
930 * Return: true if connection should be encrypted, else false
932 static bool smb3_encryption_negotiated(struct ksmbd_conn
*conn
)
934 if (!conn
->ops
->generate_encryptionkey
)
938 * SMB 3.0 and 3.0.2 dialects use the SMB2_GLOBAL_CAP_ENCRYPTION flag.
939 * SMB 3.1.1 uses the cipher_type field.
941 return (conn
->vals
->capabilities
& SMB2_GLOBAL_CAP_ENCRYPTION
) ||
945 static void decode_compress_ctxt(struct ksmbd_conn
*conn
,
946 struct smb2_compression_ctx
*pneg_ctxt
)
948 conn
->compress_algorithm
= SMB3_COMPRESS_NONE
;
951 static void decode_sign_cap_ctxt(struct ksmbd_conn
*conn
,
952 struct smb2_signing_capabilities
*pneg_ctxt
,
955 int sign_algo_cnt
= le16_to_cpu(pneg_ctxt
->SigningAlgorithmCount
);
956 int i
, sign_alos_size
= sign_algo_cnt
* sizeof(__le16
);
958 conn
->signing_negotiated
= false;
960 if (sizeof(struct smb2_signing_capabilities
) + sign_alos_size
>
962 pr_err("Invalid signing algorithm count(%d)\n", sign_algo_cnt
);
966 for (i
= 0; i
< sign_algo_cnt
; i
++) {
967 if (pneg_ctxt
->SigningAlgorithms
[i
] == SIGNING_ALG_HMAC_SHA256
||
968 pneg_ctxt
->SigningAlgorithms
[i
] == SIGNING_ALG_AES_CMAC
) {
969 ksmbd_debug(SMB
, "Signing Algorithm ID = 0x%x\n",
970 pneg_ctxt
->SigningAlgorithms
[i
]);
971 conn
->signing_negotiated
= true;
972 conn
->signing_algorithm
=
973 pneg_ctxt
->SigningAlgorithms
[i
];
979 static __le32
deassemble_neg_contexts(struct ksmbd_conn
*conn
,
980 struct smb2_negotiate_req
*req
)
982 /* +4 is to account for the RFC1001 len field */
983 struct smb2_neg_context
*pctx
= (struct smb2_neg_context
*)((char *)req
+ 4);
984 int i
= 0, len_of_ctxts
;
985 int offset
= le32_to_cpu(req
->NegotiateContextOffset
);
986 int neg_ctxt_cnt
= le16_to_cpu(req
->NegotiateContextCount
);
987 int len_of_smb
= be32_to_cpu(req
->hdr
.smb2_buf_length
);
988 __le32 status
= STATUS_INVALID_PARAMETER
;
990 ksmbd_debug(SMB
, "decoding %d negotiate contexts\n", neg_ctxt_cnt
);
991 if (len_of_smb
<= offset
) {
992 ksmbd_debug(SMB
, "Invalid response: negotiate context offset\n");
996 len_of_ctxts
= len_of_smb
- offset
;
998 while (i
++ < neg_ctxt_cnt
) {
1001 /* check that offset is not beyond end of SMB */
1002 if (len_of_ctxts
== 0)
1005 if (len_of_ctxts
< sizeof(struct smb2_neg_context
))
1008 pctx
= (struct smb2_neg_context
*)((char *)pctx
+ offset
);
1009 clen
= le16_to_cpu(pctx
->DataLength
);
1010 if (clen
+ sizeof(struct smb2_neg_context
) > len_of_ctxts
)
1013 if (pctx
->ContextType
== SMB2_PREAUTH_INTEGRITY_CAPABILITIES
) {
1015 "deassemble SMB2_PREAUTH_INTEGRITY_CAPABILITIES context\n");
1016 if (conn
->preauth_info
->Preauth_HashId
)
1019 status
= decode_preauth_ctxt(conn
,
1020 (struct smb2_preauth_neg_context
*)pctx
);
1021 if (status
!= STATUS_SUCCESS
)
1023 } else if (pctx
->ContextType
== SMB2_ENCRYPTION_CAPABILITIES
) {
1025 "deassemble SMB2_ENCRYPTION_CAPABILITIES context\n");
1026 if (conn
->cipher_type
)
1029 decode_encrypt_ctxt(conn
,
1030 (struct smb2_encryption_neg_context
*)pctx
,
1032 } else if (pctx
->ContextType
== SMB2_COMPRESSION_CAPABILITIES
) {
1034 "deassemble SMB2_COMPRESSION_CAPABILITIES context\n");
1035 if (conn
->compress_algorithm
)
1038 decode_compress_ctxt(conn
,
1039 (struct smb2_compression_ctx
*)pctx
);
1040 } else if (pctx
->ContextType
== SMB2_NETNAME_NEGOTIATE_CONTEXT_ID
) {
1042 "deassemble SMB2_NETNAME_NEGOTIATE_CONTEXT_ID context\n");
1043 } else if (pctx
->ContextType
== SMB2_POSIX_EXTENSIONS_AVAILABLE
) {
1045 "deassemble SMB2_POSIX_EXTENSIONS_AVAILABLE context\n");
1046 conn
->posix_ext_supported
= true;
1047 } else if (pctx
->ContextType
== SMB2_SIGNING_CAPABILITIES
) {
1049 "deassemble SMB2_SIGNING_CAPABILITIES context\n");
1050 decode_sign_cap_ctxt(conn
,
1051 (struct smb2_signing_capabilities
*)pctx
,
1055 /* offsets must be 8 byte aligned */
1056 clen
= (clen
+ 7) & ~0x7;
1057 offset
= clen
+ sizeof(struct smb2_neg_context
);
1058 len_of_ctxts
-= clen
+ sizeof(struct smb2_neg_context
);
1064 * smb2_handle_negotiate() - handler for smb2 negotiate command
1065 * @work: smb work containing smb request buffer
1069 int smb2_handle_negotiate(struct ksmbd_work
*work
)
1071 struct ksmbd_conn
*conn
= work
->conn
;
1072 struct smb2_negotiate_req
*req
= work
->request_buf
;
1073 struct smb2_negotiate_rsp
*rsp
= work
->response_buf
;
1075 unsigned int smb2_buf_len
, smb2_neg_size
;
1078 ksmbd_debug(SMB
, "Received negotiate request\n");
1079 conn
->need_neg
= false;
1080 if (ksmbd_conn_good(work
)) {
1081 pr_err("conn->tcp_status is already in CifsGood State\n");
1082 work
->send_no_response
= 1;
1086 if (req
->DialectCount
== 0) {
1087 pr_err("malformed packet\n");
1088 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
1093 smb2_buf_len
= get_rfc1002_len(work
->request_buf
);
1094 smb2_neg_size
= offsetof(struct smb2_negotiate_req
, Dialects
) - 4;
1095 if (smb2_neg_size
> smb2_buf_len
) {
1096 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
1101 if (conn
->dialect
== SMB311_PROT_ID
) {
1102 unsigned int nego_ctxt_off
= le32_to_cpu(req
->NegotiateContextOffset
);
1104 if (smb2_buf_len
< nego_ctxt_off
) {
1105 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
1110 if (smb2_neg_size
> nego_ctxt_off
) {
1111 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
1116 if (smb2_neg_size
+ le16_to_cpu(req
->DialectCount
) * sizeof(__le16
) >
1118 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
1123 if (smb2_neg_size
+ le16_to_cpu(req
->DialectCount
) * sizeof(__le16
) >
1125 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
1131 conn
->cli_cap
= le32_to_cpu(req
->Capabilities
);
1132 switch (conn
->dialect
) {
1133 case SMB311_PROT_ID
:
1134 conn
->preauth_info
=
1135 kzalloc(sizeof(struct preauth_integrity_info
),
1137 if (!conn
->preauth_info
) {
1139 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
1143 status
= deassemble_neg_contexts(conn
, req
);
1144 if (status
!= STATUS_SUCCESS
) {
1145 pr_err("deassemble_neg_contexts error(0x%x)\n",
1147 rsp
->hdr
.Status
= status
;
1152 rc
= init_smb3_11_server(conn
);
1154 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
1158 ksmbd_gen_preauth_integrity_hash(conn
,
1160 conn
->preauth_info
->Preauth_HashValue
);
1161 rsp
->NegotiateContextOffset
=
1162 cpu_to_le32(OFFSET_OF_NEG_CONTEXT
);
1163 assemble_neg_contexts(conn
, rsp
);
1165 case SMB302_PROT_ID
:
1166 init_smb3_02_server(conn
);
1169 init_smb3_0_server(conn
);
1172 init_smb2_1_server(conn
);
1177 ksmbd_debug(SMB
, "Server dialect :0x%x not supported\n",
1179 rsp
->hdr
.Status
= STATUS_NOT_SUPPORTED
;
1183 rsp
->Capabilities
= cpu_to_le32(conn
->vals
->capabilities
);
1186 conn
->connection_type
= conn
->dialect
;
1188 rsp
->MaxTransactSize
= cpu_to_le32(conn
->vals
->max_trans_size
);
1189 rsp
->MaxReadSize
= cpu_to_le32(conn
->vals
->max_read_size
);
1190 rsp
->MaxWriteSize
= cpu_to_le32(conn
->vals
->max_write_size
);
1192 memcpy(conn
->ClientGUID
, req
->ClientGUID
,
1193 SMB2_CLIENT_GUID_SIZE
);
1194 conn
->cli_sec_mode
= le16_to_cpu(req
->SecurityMode
);
1196 rsp
->StructureSize
= cpu_to_le16(65);
1197 rsp
->DialectRevision
= cpu_to_le16(conn
->dialect
);
1198 /* Not setting conn guid rsp->ServerGUID, as it
1199 * not used by client for identifying server
1201 memset(rsp
->ServerGUID
, 0, SMB2_CLIENT_GUID_SIZE
);
1203 rsp
->SystemTime
= cpu_to_le64(ksmbd_systime());
1204 rsp
->ServerStartTime
= 0;
1205 ksmbd_debug(SMB
, "negotiate context offset %d, count %d\n",
1206 le32_to_cpu(rsp
->NegotiateContextOffset
),
1207 le16_to_cpu(rsp
->NegotiateContextCount
));
1209 rsp
->SecurityBufferOffset
= cpu_to_le16(128);
1210 rsp
->SecurityBufferLength
= cpu_to_le16(AUTH_GSS_LENGTH
);
1211 ksmbd_copy_gss_neg_header(((char *)(&rsp
->hdr
) +
1212 sizeof(rsp
->hdr
.smb2_buf_length
)) +
1213 le16_to_cpu(rsp
->SecurityBufferOffset
));
1214 inc_rfc1001_len(rsp
, sizeof(struct smb2_negotiate_rsp
) -
1215 sizeof(struct smb2_hdr
) - sizeof(rsp
->Buffer
) +
1217 rsp
->SecurityMode
= SMB2_NEGOTIATE_SIGNING_ENABLED_LE
;
1218 conn
->use_spnego
= true;
1220 if ((server_conf
.signing
== KSMBD_CONFIG_OPT_AUTO
||
1221 server_conf
.signing
== KSMBD_CONFIG_OPT_DISABLED
) &&
1222 req
->SecurityMode
& SMB2_NEGOTIATE_SIGNING_REQUIRED_LE
)
1224 else if (server_conf
.signing
== KSMBD_CONFIG_OPT_MANDATORY
) {
1225 server_conf
.enforced_signing
= true;
1226 rsp
->SecurityMode
|= SMB2_NEGOTIATE_SIGNING_REQUIRED_LE
;
1230 conn
->srv_sec_mode
= le16_to_cpu(rsp
->SecurityMode
);
1231 ksmbd_conn_set_need_negotiate(work
);
1235 smb2_set_err_rsp(work
);
1240 static int alloc_preauth_hash(struct ksmbd_session
*sess
,
1241 struct ksmbd_conn
*conn
)
1243 if (sess
->Preauth_HashValue
)
1246 sess
->Preauth_HashValue
= kmemdup(conn
->preauth_info
->Preauth_HashValue
,
1247 PREAUTH_HASHVALUE_SIZE
, GFP_KERNEL
);
1248 if (!sess
->Preauth_HashValue
)
1254 static int generate_preauth_hash(struct ksmbd_work
*work
)
1256 struct ksmbd_conn
*conn
= work
->conn
;
1257 struct ksmbd_session
*sess
= work
->sess
;
1260 if (conn
->dialect
!= SMB311_PROT_ID
)
1263 if (conn
->binding
) {
1264 struct preauth_session
*preauth_sess
;
1266 preauth_sess
= ksmbd_preauth_session_lookup(conn
, sess
->id
);
1267 if (!preauth_sess
) {
1268 preauth_sess
= ksmbd_preauth_session_alloc(conn
, sess
->id
);
1273 preauth_hash
= preauth_sess
->Preauth_HashValue
;
1275 if (!sess
->Preauth_HashValue
)
1276 if (alloc_preauth_hash(sess
, conn
))
1278 preauth_hash
= sess
->Preauth_HashValue
;
1281 ksmbd_gen_preauth_integrity_hash(conn
, work
->request_buf
, preauth_hash
);
1285 static int decode_negotiation_token(struct ksmbd_conn
*conn
,
1286 struct negotiate_message
*negblob
,
1289 if (!conn
->use_spnego
)
1292 if (ksmbd_decode_negTokenInit((char *)negblob
, sz
, conn
)) {
1293 if (ksmbd_decode_negTokenTarg((char *)negblob
, sz
, conn
)) {
1294 conn
->auth_mechs
|= KSMBD_AUTH_NTLMSSP
;
1295 conn
->preferred_auth_mech
= KSMBD_AUTH_NTLMSSP
;
1296 conn
->use_spnego
= false;
1302 static int ntlm_negotiate(struct ksmbd_work
*work
,
1303 struct negotiate_message
*negblob
,
1306 struct smb2_sess_setup_rsp
*rsp
= work
->response_buf
;
1307 struct challenge_message
*chgblob
;
1308 unsigned char *spnego_blob
= NULL
;
1309 u16 spnego_blob_len
;
1313 ksmbd_debug(SMB
, "negotiate phase\n");
1314 rc
= ksmbd_decode_ntlmssp_neg_blob(negblob
, negblob_len
, work
->sess
);
1318 sz
= le16_to_cpu(rsp
->SecurityBufferOffset
);
1320 (struct challenge_message
*)((char *)&rsp
->hdr
.ProtocolId
+ sz
);
1321 memset(chgblob
, 0, sizeof(struct challenge_message
));
1323 if (!work
->conn
->use_spnego
) {
1324 sz
= ksmbd_build_ntlmssp_challenge_blob(chgblob
, work
->sess
);
1328 rsp
->SecurityBufferLength
= cpu_to_le16(sz
);
1332 sz
= sizeof(struct challenge_message
);
1333 sz
+= (strlen(ksmbd_netbios_name()) * 2 + 1 + 4) * 6;
1335 neg_blob
= kzalloc(sz
, GFP_KERNEL
);
1339 chgblob
= (struct challenge_message
*)neg_blob
;
1340 sz
= ksmbd_build_ntlmssp_challenge_blob(chgblob
, work
->sess
);
1346 rc
= build_spnego_ntlmssp_neg_blob(&spnego_blob
, &spnego_blob_len
,
1353 sz
= le16_to_cpu(rsp
->SecurityBufferOffset
);
1354 memcpy((char *)&rsp
->hdr
.ProtocolId
+ sz
, spnego_blob
, spnego_blob_len
);
1355 rsp
->SecurityBufferLength
= cpu_to_le16(spnego_blob_len
);
1363 static struct authenticate_message
*user_authblob(struct ksmbd_conn
*conn
,
1364 struct smb2_sess_setup_req
*req
)
1368 if (conn
->use_spnego
&& conn
->mechToken
)
1369 return (struct authenticate_message
*)conn
->mechToken
;
1371 sz
= le16_to_cpu(req
->SecurityBufferOffset
);
1372 return (struct authenticate_message
*)((char *)&req
->hdr
.ProtocolId
1376 static struct ksmbd_user
*session_user(struct ksmbd_conn
*conn
,
1377 struct smb2_sess_setup_req
*req
)
1379 struct authenticate_message
*authblob
;
1380 struct ksmbd_user
*user
;
1382 unsigned int auth_msg_len
, name_off
, name_len
, secbuf_len
;
1384 secbuf_len
= le16_to_cpu(req
->SecurityBufferLength
);
1385 if (secbuf_len
< sizeof(struct authenticate_message
)) {
1386 ksmbd_debug(SMB
, "blob len %d too small\n", secbuf_len
);
1389 authblob
= user_authblob(conn
, req
);
1390 name_off
= le32_to_cpu(authblob
->UserName
.BufferOffset
);
1391 name_len
= le16_to_cpu(authblob
->UserName
.Length
);
1392 auth_msg_len
= le16_to_cpu(req
->SecurityBufferOffset
) + secbuf_len
;
1394 if (auth_msg_len
< (u64
)name_off
+ name_len
)
1397 name
= smb_strndup_from_utf16((const char *)authblob
+ name_off
,
1402 pr_err("cannot allocate memory\n");
1406 ksmbd_debug(SMB
, "session setup request for user %s\n", name
);
1407 user
= ksmbd_login_user(name
);
1412 static int ntlm_authenticate(struct ksmbd_work
*work
)
1414 struct smb2_sess_setup_req
*req
= work
->request_buf
;
1415 struct smb2_sess_setup_rsp
*rsp
= work
->response_buf
;
1416 struct ksmbd_conn
*conn
= work
->conn
;
1417 struct ksmbd_session
*sess
= work
->sess
;
1418 struct channel
*chann
= NULL
;
1419 struct ksmbd_user
*user
;
1423 ksmbd_debug(SMB
, "authenticate phase\n");
1424 if (conn
->use_spnego
) {
1425 unsigned char *spnego_blob
;
1426 u16 spnego_blob_len
;
1428 rc
= build_spnego_ntlmssp_auth_blob(&spnego_blob
,
1434 sz
= le16_to_cpu(rsp
->SecurityBufferOffset
);
1435 memcpy((char *)&rsp
->hdr
.ProtocolId
+ sz
, spnego_blob
, spnego_blob_len
);
1436 rsp
->SecurityBufferLength
= cpu_to_le16(spnego_blob_len
);
1438 inc_rfc1001_len(rsp
, spnego_blob_len
- 1);
1441 user
= session_user(conn
, req
);
1443 ksmbd_debug(SMB
, "Unknown user name or an error\n");
1447 /* Check for previous session */
1448 prev_id
= le64_to_cpu(req
->PreviousSessionId
);
1449 if (prev_id
&& prev_id
!= sess
->id
)
1450 destroy_previous_session(user
, prev_id
);
1452 if (sess
->state
== SMB2_SESSION_VALID
) {
1454 * Reuse session if anonymous try to connect
1455 * on reauthetication.
1457 if (ksmbd_anonymous_user(user
)) {
1458 ksmbd_free_user(user
);
1461 ksmbd_free_user(sess
->user
);
1465 if (user_guest(sess
->user
)) {
1466 rsp
->SessionFlags
= SMB2_SESSION_FLAG_IS_GUEST_LE
;
1468 struct authenticate_message
*authblob
;
1470 authblob
= user_authblob(conn
, req
);
1471 sz
= le16_to_cpu(req
->SecurityBufferLength
);
1472 rc
= ksmbd_decode_ntlmssp_auth_blob(authblob
, sz
, sess
);
1474 set_user_flag(sess
->user
, KSMBD_USER_FLAG_BAD_PASSWORD
);
1475 ksmbd_debug(SMB
, "authentication failed\n");
1481 * If session state is SMB2_SESSION_VALID, We can assume
1482 * that it is reauthentication. And the user/password
1483 * has been verified, so return it here.
1485 if (sess
->state
== SMB2_SESSION_VALID
) {
1487 goto binding_session
;
1491 if ((rsp
->SessionFlags
!= SMB2_SESSION_FLAG_IS_GUEST_LE
&&
1492 (conn
->sign
|| server_conf
.enforced_signing
)) ||
1493 (req
->SecurityMode
& SMB2_NEGOTIATE_SIGNING_REQUIRED
))
1496 if (smb3_encryption_negotiated(conn
) &&
1497 !(req
->Flags
& SMB2_SESSION_REQ_FLAG_BINDING
)) {
1498 rc
= conn
->ops
->generate_encryptionkey(sess
);
1501 "SMB3 encryption key generation failed\n");
1505 rsp
->SessionFlags
= SMB2_SESSION_FLAG_ENCRYPT_DATA_LE
;
1507 * signing is disable if encryption is enable
1514 if (conn
->dialect
>= SMB30_PROT_ID
) {
1515 chann
= lookup_chann_list(sess
, conn
);
1517 chann
= kmalloc(sizeof(struct channel
), GFP_KERNEL
);
1522 INIT_LIST_HEAD(&chann
->chann_list
);
1523 list_add(&chann
->chann_list
, &sess
->ksmbd_chann_list
);
1527 if (conn
->ops
->generate_signingkey
) {
1528 rc
= conn
->ops
->generate_signingkey(sess
, conn
);
1530 ksmbd_debug(SMB
, "SMB3 signing key generation failed\n");
1535 if (!ksmbd_conn_lookup_dialect(conn
)) {
1536 pr_err("fail to verify the dialect\n");
1542 #ifdef CONFIG_SMB_SERVER_KERBEROS5
1543 static int krb5_authenticate(struct ksmbd_work
*work
)
1545 struct smb2_sess_setup_req
*req
= work
->request_buf
;
1546 struct smb2_sess_setup_rsp
*rsp
= work
->response_buf
;
1547 struct ksmbd_conn
*conn
= work
->conn
;
1548 struct ksmbd_session
*sess
= work
->sess
;
1549 char *in_blob
, *out_blob
;
1550 struct channel
*chann
= NULL
;
1552 int in_len
, out_len
;
1555 in_blob
= (char *)&req
->hdr
.ProtocolId
+
1556 le16_to_cpu(req
->SecurityBufferOffset
);
1557 in_len
= le16_to_cpu(req
->SecurityBufferLength
);
1558 out_blob
= (char *)&rsp
->hdr
.ProtocolId
+
1559 le16_to_cpu(rsp
->SecurityBufferOffset
);
1560 out_len
= work
->response_sz
-
1561 offsetof(struct smb2_hdr
, smb2_buf_length
) -
1562 le16_to_cpu(rsp
->SecurityBufferOffset
);
1564 /* Check previous session */
1565 prev_sess_id
= le64_to_cpu(req
->PreviousSessionId
);
1566 if (prev_sess_id
&& prev_sess_id
!= sess
->id
)
1567 destroy_previous_session(sess
->user
, prev_sess_id
);
1569 if (sess
->state
== SMB2_SESSION_VALID
)
1570 ksmbd_free_user(sess
->user
);
1572 retval
= ksmbd_krb5_authenticate(sess
, in_blob
, in_len
,
1573 out_blob
, &out_len
);
1575 ksmbd_debug(SMB
, "krb5 authentication failed\n");
1578 rsp
->SecurityBufferLength
= cpu_to_le16(out_len
);
1579 inc_rfc1001_len(rsp
, out_len
- 1);
1581 if ((conn
->sign
|| server_conf
.enforced_signing
) ||
1582 (req
->SecurityMode
& SMB2_NEGOTIATE_SIGNING_REQUIRED
))
1585 if (smb3_encryption_negotiated(conn
)) {
1586 retval
= conn
->ops
->generate_encryptionkey(sess
);
1589 "SMB3 encryption key generation failed\n");
1593 rsp
->SessionFlags
= SMB2_SESSION_FLAG_ENCRYPT_DATA_LE
;
1597 if (conn
->dialect
>= SMB30_PROT_ID
) {
1598 chann
= lookup_chann_list(sess
, conn
);
1600 chann
= kmalloc(sizeof(struct channel
), GFP_KERNEL
);
1605 INIT_LIST_HEAD(&chann
->chann_list
);
1606 list_add(&chann
->chann_list
, &sess
->ksmbd_chann_list
);
1610 if (conn
->ops
->generate_signingkey
) {
1611 retval
= conn
->ops
->generate_signingkey(sess
, conn
);
1613 ksmbd_debug(SMB
, "SMB3 signing key generation failed\n");
1618 if (!ksmbd_conn_lookup_dialect(conn
)) {
1619 pr_err("fail to verify the dialect\n");
1625 static int krb5_authenticate(struct ksmbd_work
*work
)
1631 int smb2_sess_setup(struct ksmbd_work
*work
)
1633 struct ksmbd_conn
*conn
= work
->conn
;
1634 struct smb2_sess_setup_req
*req
= work
->request_buf
;
1635 struct smb2_sess_setup_rsp
*rsp
= work
->response_buf
;
1636 struct ksmbd_session
*sess
;
1637 struct negotiate_message
*negblob
;
1638 unsigned int negblob_len
, negblob_off
;
1641 ksmbd_debug(SMB
, "Received request for session setup\n");
1643 rsp
->StructureSize
= cpu_to_le16(9);
1644 rsp
->SessionFlags
= 0;
1645 rsp
->SecurityBufferOffset
= cpu_to_le16(72);
1646 rsp
->SecurityBufferLength
= 0;
1647 inc_rfc1001_len(rsp
, 9);
1649 if (!req
->hdr
.SessionId
) {
1650 sess
= ksmbd_smb2_session_create();
1655 rsp
->hdr
.SessionId
= cpu_to_le64(sess
->id
);
1656 ksmbd_session_register(conn
, sess
);
1657 } else if (conn
->dialect
>= SMB30_PROT_ID
&&
1658 (server_conf
.flags
& KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL
) &&
1659 req
->Flags
& SMB2_SESSION_REQ_FLAG_BINDING
) {
1660 u64 sess_id
= le64_to_cpu(req
->hdr
.SessionId
);
1662 sess
= ksmbd_session_lookup_slowpath(sess_id
);
1668 if (conn
->dialect
!= sess
->conn
->dialect
) {
1673 if (!(req
->hdr
.Flags
& SMB2_FLAGS_SIGNED
)) {
1678 if (strncmp(conn
->ClientGUID
, sess
->conn
->ClientGUID
,
1679 SMB2_CLIENT_GUID_SIZE
)) {
1684 if (sess
->state
== SMB2_SESSION_IN_PROGRESS
) {
1689 if (sess
->state
== SMB2_SESSION_EXPIRED
) {
1694 if (ksmbd_session_lookup(conn
, sess_id
)) {
1699 conn
->binding
= true;
1700 } else if ((conn
->dialect
< SMB30_PROT_ID
||
1701 server_conf
.flags
& KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL
) &&
1702 (req
->Flags
& SMB2_SESSION_REQ_FLAG_BINDING
)) {
1707 sess
= ksmbd_session_lookup(conn
,
1708 le64_to_cpu(req
->hdr
.SessionId
));
1716 if (sess
->state
== SMB2_SESSION_EXPIRED
)
1717 sess
->state
= SMB2_SESSION_IN_PROGRESS
;
1719 negblob_off
= le16_to_cpu(req
->SecurityBufferOffset
);
1720 negblob_len
= le16_to_cpu(req
->SecurityBufferLength
);
1721 if (negblob_off
< (offsetof(struct smb2_sess_setup_req
, Buffer
) - 4) ||
1722 negblob_len
< offsetof(struct negotiate_message
, NegotiateFlags
)) {
1727 negblob
= (struct negotiate_message
*)((char *)&req
->hdr
.ProtocolId
+
1730 if (decode_negotiation_token(conn
, negblob
, negblob_len
) == 0) {
1731 if (conn
->mechToken
)
1732 negblob
= (struct negotiate_message
*)conn
->mechToken
;
1735 if (server_conf
.auth_mechs
& conn
->auth_mechs
) {
1736 rc
= generate_preauth_hash(work
);
1740 if (conn
->preferred_auth_mech
&
1741 (KSMBD_AUTH_KRB5
| KSMBD_AUTH_MSKRB5
)) {
1742 rc
= krb5_authenticate(work
);
1748 ksmbd_conn_set_good(work
);
1749 sess
->state
= SMB2_SESSION_VALID
;
1750 kfree(sess
->Preauth_HashValue
);
1751 sess
->Preauth_HashValue
= NULL
;
1752 } else if (conn
->preferred_auth_mech
== KSMBD_AUTH_NTLMSSP
) {
1753 if (negblob
->MessageType
== NtLmNegotiate
) {
1754 rc
= ntlm_negotiate(work
, negblob
, negblob_len
);
1758 STATUS_MORE_PROCESSING_REQUIRED
;
1760 * Note: here total size -1 is done as an
1761 * adjustment for 0 size blob
1763 inc_rfc1001_len(rsp
, le16_to_cpu(rsp
->SecurityBufferLength
) - 1);
1765 } else if (negblob
->MessageType
== NtLmAuthenticate
) {
1766 rc
= ntlm_authenticate(work
);
1770 ksmbd_conn_set_good(work
);
1771 sess
->state
= SMB2_SESSION_VALID
;
1772 if (conn
->binding
) {
1773 struct preauth_session
*preauth_sess
;
1776 ksmbd_preauth_session_lookup(conn
, sess
->id
);
1778 list_del(&preauth_sess
->preauth_entry
);
1779 kfree(preauth_sess
);
1782 kfree(sess
->Preauth_HashValue
);
1783 sess
->Preauth_HashValue
= NULL
;
1786 /* TODO: need one more negotiation */
1787 pr_err("Not support the preferred authentication\n");
1791 pr_err("Not support authentication\n");
1797 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
1798 else if (rc
== -ENOENT
)
1799 rsp
->hdr
.Status
= STATUS_USER_SESSION_DELETED
;
1800 else if (rc
== -EACCES
)
1801 rsp
->hdr
.Status
= STATUS_REQUEST_NOT_ACCEPTED
;
1802 else if (rc
== -EFAULT
)
1803 rsp
->hdr
.Status
= STATUS_NETWORK_SESSION_EXPIRED
;
1804 else if (rc
== -ENOMEM
)
1805 rsp
->hdr
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
1807 rsp
->hdr
.Status
= STATUS_LOGON_FAILURE
;
1809 if (conn
->use_spnego
&& conn
->mechToken
) {
1810 kfree(conn
->mechToken
);
1811 conn
->mechToken
= NULL
;
1816 * SecurityBufferOffset should be set to zero
1817 * in session setup error response.
1819 rsp
->SecurityBufferOffset
= 0;
1822 bool try_delay
= false;
1825 * To avoid dictionary attacks (repeated session setups rapidly sent) to
1826 * connect to server, ksmbd make a delay of a 5 seconds on session setup
1827 * failure to make it harder to send enough random connection requests
1828 * to break into a server.
1830 if (sess
->user
&& sess
->user
->flags
& KSMBD_USER_FLAG_DELAY_SESSION
)
1833 ksmbd_session_destroy(sess
);
1844 * smb2_tree_connect() - handler for smb2 tree connect command
1845 * @work: smb work containing smb request buffer
1847 * Return: 0 on success, otherwise error
1849 int smb2_tree_connect(struct ksmbd_work
*work
)
1851 struct ksmbd_conn
*conn
= work
->conn
;
1852 struct smb2_tree_connect_req
*req
= work
->request_buf
;
1853 struct smb2_tree_connect_rsp
*rsp
= work
->response_buf
;
1854 struct ksmbd_session
*sess
= work
->sess
;
1855 char *treename
= NULL
, *name
= NULL
;
1856 struct ksmbd_tree_conn_status status
;
1857 struct ksmbd_share_config
*share
;
1860 treename
= smb_strndup_from_utf16(req
->Buffer
,
1861 le16_to_cpu(req
->PathLength
), true,
1863 if (IS_ERR(treename
)) {
1864 pr_err("treename is NULL\n");
1865 status
.ret
= KSMBD_TREE_CONN_STATUS_ERROR
;
1869 name
= ksmbd_extract_sharename(treename
);
1871 status
.ret
= KSMBD_TREE_CONN_STATUS_ERROR
;
1875 ksmbd_debug(SMB
, "tree connect request for tree %s treename %s\n",
1878 status
= ksmbd_tree_conn_connect(sess
, name
);
1879 if (status
.ret
== KSMBD_TREE_CONN_STATUS_OK
)
1880 rsp
->hdr
.Id
.SyncId
.TreeId
= cpu_to_le32(status
.tree_conn
->id
);
1884 share
= status
.tree_conn
->share_conf
;
1885 if (test_share_config_flag(share
, KSMBD_SHARE_FLAG_PIPE
)) {
1886 ksmbd_debug(SMB
, "IPC share path request\n");
1887 rsp
->ShareType
= SMB2_SHARE_TYPE_PIPE
;
1888 rsp
->MaximalAccess
= FILE_READ_DATA_LE
| FILE_READ_EA_LE
|
1889 FILE_EXECUTE_LE
| FILE_READ_ATTRIBUTES_LE
|
1890 FILE_DELETE_LE
| FILE_READ_CONTROL_LE
|
1891 FILE_WRITE_DAC_LE
| FILE_WRITE_OWNER_LE
|
1892 FILE_SYNCHRONIZE_LE
;
1894 rsp
->ShareType
= SMB2_SHARE_TYPE_DISK
;
1895 rsp
->MaximalAccess
= FILE_READ_DATA_LE
| FILE_READ_EA_LE
|
1896 FILE_EXECUTE_LE
| FILE_READ_ATTRIBUTES_LE
;
1897 if (test_tree_conn_flag(status
.tree_conn
,
1898 KSMBD_TREE_CONN_FLAG_WRITABLE
)) {
1899 rsp
->MaximalAccess
|= FILE_WRITE_DATA_LE
|
1900 FILE_APPEND_DATA_LE
| FILE_WRITE_EA_LE
|
1901 FILE_DELETE_LE
| FILE_WRITE_ATTRIBUTES_LE
|
1902 FILE_DELETE_CHILD_LE
| FILE_READ_CONTROL_LE
|
1903 FILE_WRITE_DAC_LE
| FILE_WRITE_OWNER_LE
|
1904 FILE_SYNCHRONIZE_LE
;
1908 status
.tree_conn
->maximal_access
= le32_to_cpu(rsp
->MaximalAccess
);
1909 if (conn
->posix_ext_supported
)
1910 status
.tree_conn
->posix_extensions
= true;
1913 rsp
->StructureSize
= cpu_to_le16(16);
1914 rsp
->Capabilities
= 0;
1916 /* default manual caching */
1917 rsp
->ShareFlags
= SMB2_SHAREFLAG_MANUAL_CACHING
;
1918 inc_rfc1001_len(rsp
, 16);
1920 if (!IS_ERR(treename
))
1925 switch (status
.ret
) {
1926 case KSMBD_TREE_CONN_STATUS_OK
:
1927 rsp
->hdr
.Status
= STATUS_SUCCESS
;
1930 case KSMBD_TREE_CONN_STATUS_NO_SHARE
:
1931 rsp
->hdr
.Status
= STATUS_BAD_NETWORK_PATH
;
1934 case KSMBD_TREE_CONN_STATUS_NOMEM
:
1935 rsp
->hdr
.Status
= STATUS_NO_MEMORY
;
1937 case KSMBD_TREE_CONN_STATUS_ERROR
:
1938 case KSMBD_TREE_CONN_STATUS_TOO_MANY_CONNS
:
1939 case KSMBD_TREE_CONN_STATUS_TOO_MANY_SESSIONS
:
1940 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
1943 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
1946 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
1953 * smb2_create_open_flags() - convert smb open flags to unix open flags
1954 * @file_present: is file already present
1955 * @access: file access flags
1956 * @disposition: file disposition flags
1957 * @may_flags: set with MAY_ flags
1959 * Return: file open flags
1961 static int smb2_create_open_flags(bool file_present
, __le32 access
,
1965 int oflags
= O_NONBLOCK
| O_LARGEFILE
;
1967 if (access
& FILE_READ_DESIRED_ACCESS_LE
&&
1968 access
& FILE_WRITE_DESIRE_ACCESS_LE
) {
1970 *may_flags
= MAY_OPEN
| MAY_READ
| MAY_WRITE
;
1971 } else if (access
& FILE_WRITE_DESIRE_ACCESS_LE
) {
1973 *may_flags
= MAY_OPEN
| MAY_WRITE
;
1976 *may_flags
= MAY_OPEN
| MAY_READ
;
1979 if (access
== FILE_READ_ATTRIBUTES_LE
)
1983 switch (disposition
& FILE_CREATE_MASK_LE
) {
1985 case FILE_CREATE_LE
:
1987 case FILE_SUPERSEDE_LE
:
1988 case FILE_OVERWRITE_LE
:
1989 case FILE_OVERWRITE_IF_LE
:
1996 switch (disposition
& FILE_CREATE_MASK_LE
) {
1997 case FILE_SUPERSEDE_LE
:
1998 case FILE_CREATE_LE
:
1999 case FILE_OPEN_IF_LE
:
2000 case FILE_OVERWRITE_IF_LE
:
2004 case FILE_OVERWRITE_LE
:
2016 * smb2_tree_disconnect() - handler for smb tree connect request
2017 * @work: smb work containing request buffer
2021 int smb2_tree_disconnect(struct ksmbd_work
*work
)
2023 struct smb2_tree_disconnect_rsp
*rsp
= work
->response_buf
;
2024 struct ksmbd_session
*sess
= work
->sess
;
2025 struct ksmbd_tree_connect
*tcon
= work
->tcon
;
2027 rsp
->StructureSize
= cpu_to_le16(4);
2028 inc_rfc1001_len(rsp
, 4);
2030 ksmbd_debug(SMB
, "request\n");
2033 struct smb2_tree_disconnect_req
*req
= work
->request_buf
;
2035 ksmbd_debug(SMB
, "Invalid tid %d\n", req
->hdr
.Id
.SyncId
.TreeId
);
2036 rsp
->hdr
.Status
= STATUS_NETWORK_NAME_DELETED
;
2037 smb2_set_err_rsp(work
);
2041 ksmbd_close_tree_conn_fds(work
);
2042 ksmbd_tree_conn_disconnect(sess
, tcon
);
2047 * smb2_session_logoff() - handler for session log off request
2048 * @work: smb work containing request buffer
2052 int smb2_session_logoff(struct ksmbd_work
*work
)
2054 struct ksmbd_conn
*conn
= work
->conn
;
2055 struct smb2_logoff_rsp
*rsp
= work
->response_buf
;
2056 struct ksmbd_session
*sess
= work
->sess
;
2058 rsp
->StructureSize
= cpu_to_le16(4);
2059 inc_rfc1001_len(rsp
, 4);
2061 ksmbd_debug(SMB
, "request\n");
2063 /* Got a valid session, set connection state */
2064 WARN_ON(sess
->conn
!= conn
);
2066 /* setting CifsExiting here may race with start_tcp_sess */
2067 ksmbd_conn_set_need_reconnect(work
);
2068 ksmbd_close_session_fds(work
);
2069 ksmbd_conn_wait_idle(conn
);
2071 if (ksmbd_tree_conn_session_logoff(sess
)) {
2072 struct smb2_logoff_req
*req
= work
->request_buf
;
2074 ksmbd_debug(SMB
, "Invalid tid %d\n", req
->hdr
.Id
.SyncId
.TreeId
);
2075 rsp
->hdr
.Status
= STATUS_NETWORK_NAME_DELETED
;
2076 smb2_set_err_rsp(work
);
2080 ksmbd_destroy_file_table(&sess
->file_table
);
2081 sess
->state
= SMB2_SESSION_EXPIRED
;
2083 ksmbd_free_user(sess
->user
);
2086 /* let start_tcp_sess free connection info now */
2087 ksmbd_conn_set_need_negotiate(work
);
2092 * create_smb2_pipe() - create IPC pipe
2093 * @work: smb work containing request buffer
2095 * Return: 0 on success, otherwise error
2097 static noinline
int create_smb2_pipe(struct ksmbd_work
*work
)
2099 struct smb2_create_rsp
*rsp
= work
->response_buf
;
2100 struct smb2_create_req
*req
= work
->request_buf
;
2105 name
= smb_strndup_from_utf16(req
->Buffer
, le16_to_cpu(req
->NameLength
),
2106 1, work
->conn
->local_nls
);
2108 rsp
->hdr
.Status
= STATUS_NO_MEMORY
;
2109 err
= PTR_ERR(name
);
2113 id
= ksmbd_session_rpc_open(work
->sess
, name
);
2115 pr_err("Unable to open RPC pipe: %d\n", id
);
2120 rsp
->hdr
.Status
= STATUS_SUCCESS
;
2121 rsp
->StructureSize
= cpu_to_le16(89);
2122 rsp
->OplockLevel
= SMB2_OPLOCK_LEVEL_NONE
;
2124 rsp
->CreateAction
= cpu_to_le32(FILE_OPENED
);
2126 rsp
->CreationTime
= cpu_to_le64(0);
2127 rsp
->LastAccessTime
= cpu_to_le64(0);
2128 rsp
->ChangeTime
= cpu_to_le64(0);
2129 rsp
->AllocationSize
= cpu_to_le64(0);
2130 rsp
->EndofFile
= cpu_to_le64(0);
2131 rsp
->FileAttributes
= ATTR_NORMAL_LE
;
2133 rsp
->VolatileFileId
= cpu_to_le64(id
);
2134 rsp
->PersistentFileId
= 0;
2135 rsp
->CreateContextsOffset
= 0;
2136 rsp
->CreateContextsLength
= 0;
2138 inc_rfc1001_len(rsp
, 88); /* StructureSize - 1*/
2145 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
2149 rsp
->hdr
.Status
= STATUS_NO_MEMORY
;
2156 smb2_set_err_rsp(work
);
2161 * smb2_set_ea() - handler for setting extended attributes using set
2163 * @eabuf: set info command buffer
2164 * @buf_len: set info command buffer length
2165 * @path: dentry path for get ea
2167 * Return: 0 on success, otherwise error
2169 static int smb2_set_ea(struct smb2_ea_info
*eabuf
, unsigned int buf_len
,
2172 struct user_namespace
*user_ns
= mnt_user_ns(path
->mnt
);
2173 char *attr_name
= NULL
, *value
;
2175 unsigned int next
= 0;
2177 if (buf_len
< sizeof(struct smb2_ea_info
) + eabuf
->EaNameLength
+
2178 le16_to_cpu(eabuf
->EaValueLength
))
2181 attr_name
= kmalloc(XATTR_NAME_MAX
+ 1, GFP_KERNEL
);
2186 if (!eabuf
->EaNameLength
)
2190 "name : <%s>, name_len : %u, value_len : %u, next : %u\n",
2191 eabuf
->name
, eabuf
->EaNameLength
,
2192 le16_to_cpu(eabuf
->EaValueLength
),
2193 le32_to_cpu(eabuf
->NextEntryOffset
));
2195 if (eabuf
->EaNameLength
>
2196 (XATTR_NAME_MAX
- XATTR_USER_PREFIX_LEN
)) {
2201 memcpy(attr_name
, XATTR_USER_PREFIX
, XATTR_USER_PREFIX_LEN
);
2202 memcpy(&attr_name
[XATTR_USER_PREFIX_LEN
], eabuf
->name
,
2203 eabuf
->EaNameLength
);
2204 attr_name
[XATTR_USER_PREFIX_LEN
+ eabuf
->EaNameLength
] = '\0';
2205 value
= (char *)&eabuf
->name
+ eabuf
->EaNameLength
+ 1;
2207 if (!eabuf
->EaValueLength
) {
2208 rc
= ksmbd_vfs_casexattr_len(user_ns
,
2211 XATTR_USER_PREFIX_LEN
+
2212 eabuf
->EaNameLength
);
2214 /* delete the EA only when it exits */
2216 rc
= ksmbd_vfs_remove_xattr(user_ns
,
2222 "remove xattr failed(%d)\n",
2228 /* if the EA doesn't exist, just do nothing. */
2231 rc
= ksmbd_vfs_setxattr(user_ns
,
2232 path
->dentry
, attr_name
, value
,
2233 le16_to_cpu(eabuf
->EaValueLength
), 0);
2236 "ksmbd_vfs_setxattr is failed(%d)\n",
2243 next
= le32_to_cpu(eabuf
->NextEntryOffset
);
2244 if (next
== 0 || buf_len
< next
)
2247 eabuf
= (struct smb2_ea_info
*)((char *)eabuf
+ next
);
2248 if (next
< (u32
)eabuf
->EaNameLength
+ le16_to_cpu(eabuf
->EaValueLength
))
2251 } while (next
!= 0);
2257 static noinline
int smb2_set_stream_name_xattr(struct path
*path
,
2258 struct ksmbd_file
*fp
,
2259 char *stream_name
, int s_type
)
2261 struct user_namespace
*user_ns
= mnt_user_ns(path
->mnt
);
2262 size_t xattr_stream_size
;
2263 char *xattr_stream_name
;
2266 rc
= ksmbd_vfs_xattr_stream_name(stream_name
,
2273 fp
->stream
.name
= xattr_stream_name
;
2274 fp
->stream
.size
= xattr_stream_size
;
2276 /* Check if there is stream prefix in xattr space */
2277 rc
= ksmbd_vfs_casexattr_len(user_ns
,
2284 if (fp
->cdoption
== FILE_OPEN_LE
) {
2285 ksmbd_debug(SMB
, "XATTR stream name lookup failed: %d\n", rc
);
2289 rc
= ksmbd_vfs_setxattr(user_ns
, path
->dentry
,
2290 xattr_stream_name
, NULL
, 0, 0);
2292 pr_err("Failed to store XATTR stream name :%d\n", rc
);
2296 static int smb2_remove_smb_xattrs(struct path
*path
)
2298 struct user_namespace
*user_ns
= mnt_user_ns(path
->mnt
);
2299 char *name
, *xattr_list
= NULL
;
2300 ssize_t xattr_list_len
;
2303 xattr_list_len
= ksmbd_vfs_listxattr(path
->dentry
, &xattr_list
);
2304 if (xattr_list_len
< 0) {
2306 } else if (!xattr_list_len
) {
2307 ksmbd_debug(SMB
, "empty xattr in the file\n");
2311 for (name
= xattr_list
; name
- xattr_list
< xattr_list_len
;
2312 name
+= strlen(name
) + 1) {
2313 ksmbd_debug(SMB
, "%s, len %zd\n", name
, strlen(name
));
2315 if (strncmp(name
, XATTR_USER_PREFIX
, XATTR_USER_PREFIX_LEN
) &&
2316 strncmp(&name
[XATTR_USER_PREFIX_LEN
], DOS_ATTRIBUTE_PREFIX
,
2317 DOS_ATTRIBUTE_PREFIX_LEN
) &&
2318 strncmp(&name
[XATTR_USER_PREFIX_LEN
], STREAM_PREFIX
, STREAM_PREFIX_LEN
))
2321 err
= ksmbd_vfs_remove_xattr(user_ns
, path
->dentry
, name
);
2323 ksmbd_debug(SMB
, "remove xattr failed : %s\n", name
);
2330 static int smb2_create_truncate(struct path
*path
)
2332 int rc
= vfs_truncate(path
, 0);
2335 pr_err("vfs_truncate failed, rc %d\n", rc
);
2339 rc
= smb2_remove_smb_xattrs(path
);
2340 if (rc
== -EOPNOTSUPP
)
2344 "ksmbd_truncate_stream_name_xattr failed, rc %d\n",
2349 static void smb2_new_xattrs(struct ksmbd_tree_connect
*tcon
, struct path
*path
,
2350 struct ksmbd_file
*fp
)
2352 struct xattr_dos_attrib da
= {0};
2355 if (!test_share_config_flag(tcon
->share_conf
,
2356 KSMBD_SHARE_FLAG_STORE_DOS_ATTRS
))
2360 da
.attr
= le32_to_cpu(fp
->f_ci
->m_fattr
);
2361 da
.itime
= da
.create_time
= fp
->create_time
;
2362 da
.flags
= XATTR_DOSINFO_ATTRIB
| XATTR_DOSINFO_CREATE_TIME
|
2363 XATTR_DOSINFO_ITIME
;
2365 rc
= ksmbd_vfs_set_dos_attrib_xattr(mnt_user_ns(path
->mnt
),
2368 ksmbd_debug(SMB
, "failed to store file attribute into xattr\n");
2371 static void smb2_update_xattrs(struct ksmbd_tree_connect
*tcon
,
2372 struct path
*path
, struct ksmbd_file
*fp
)
2374 struct xattr_dos_attrib da
;
2377 fp
->f_ci
->m_fattr
&= ~(ATTR_HIDDEN_LE
| ATTR_SYSTEM_LE
);
2379 /* get FileAttributes from XATTR_NAME_DOS_ATTRIBUTE */
2380 if (!test_share_config_flag(tcon
->share_conf
,
2381 KSMBD_SHARE_FLAG_STORE_DOS_ATTRS
))
2384 rc
= ksmbd_vfs_get_dos_attrib_xattr(mnt_user_ns(path
->mnt
),
2387 fp
->f_ci
->m_fattr
= cpu_to_le32(da
.attr
);
2388 fp
->create_time
= da
.create_time
;
2389 fp
->itime
= da
.itime
;
2393 static int smb2_creat(struct ksmbd_work
*work
, struct path
*path
, char *name
,
2394 int open_flags
, umode_t posix_mode
, bool is_dir
)
2396 struct ksmbd_tree_connect
*tcon
= work
->tcon
;
2397 struct ksmbd_share_config
*share
= tcon
->share_conf
;
2401 if (!(open_flags
& O_CREAT
))
2404 ksmbd_debug(SMB
, "file does not exist, so creating\n");
2405 if (is_dir
== true) {
2406 ksmbd_debug(SMB
, "creating directory\n");
2408 mode
= share_config_directory_mode(share
, posix_mode
);
2409 rc
= ksmbd_vfs_mkdir(work
, name
, mode
);
2413 ksmbd_debug(SMB
, "creating regular file\n");
2415 mode
= share_config_create_mode(share
, posix_mode
);
2416 rc
= ksmbd_vfs_create(work
, name
, mode
);
2421 rc
= ksmbd_vfs_kern_path(work
, name
, 0, path
, 0);
2423 pr_err("cannot get linux path (%s), err = %d\n",
2430 static int smb2_create_sd_buffer(struct ksmbd_work
*work
,
2431 struct smb2_create_req
*req
,
2434 struct create_context
*context
;
2435 struct create_sd_buf_req
*sd_buf
;
2437 if (!req
->CreateContextsOffset
)
2440 /* Parse SD BUFFER create contexts */
2441 context
= smb2_find_context_vals(req
, SMB2_CREATE_SD_BUFFER
);
2444 else if (IS_ERR(context
))
2445 return PTR_ERR(context
);
2448 "Set ACLs using SMB2_CREATE_SD_BUFFER context\n");
2449 sd_buf
= (struct create_sd_buf_req
*)context
;
2450 if (le16_to_cpu(context
->DataOffset
) +
2451 le32_to_cpu(context
->DataLength
) <
2452 sizeof(struct create_sd_buf_req
))
2454 return set_info_sec(work
->conn
, work
->tcon
, path
, &sd_buf
->ntsd
,
2455 le32_to_cpu(sd_buf
->ccontext
.DataLength
), true);
2458 static void ksmbd_acls_fattr(struct smb_fattr
*fattr
,
2459 struct user_namespace
*mnt_userns
,
2460 struct inode
*inode
)
2462 fattr
->cf_uid
= i_uid_into_mnt(mnt_userns
, inode
);
2463 fattr
->cf_gid
= i_gid_into_mnt(mnt_userns
, inode
);
2464 fattr
->cf_mode
= inode
->i_mode
;
2465 fattr
->cf_acls
= NULL
;
2466 fattr
->cf_dacls
= NULL
;
2468 if (IS_ENABLED(CONFIG_FS_POSIX_ACL
)) {
2469 fattr
->cf_acls
= get_acl(inode
, ACL_TYPE_ACCESS
);
2470 if (S_ISDIR(inode
->i_mode
))
2471 fattr
->cf_dacls
= get_acl(inode
, ACL_TYPE_DEFAULT
);
2476 * smb2_open() - handler for smb file open request
2477 * @work: smb work containing request buffer
2479 * Return: 0 on success, otherwise error
2481 int smb2_open(struct ksmbd_work
*work
)
2483 struct ksmbd_conn
*conn
= work
->conn
;
2484 struct ksmbd_session
*sess
= work
->sess
;
2485 struct ksmbd_tree_connect
*tcon
= work
->tcon
;
2486 struct smb2_create_req
*req
;
2487 struct smb2_create_rsp
*rsp
, *rsp_org
;
2489 struct ksmbd_share_config
*share
= tcon
->share_conf
;
2490 struct ksmbd_file
*fp
= NULL
;
2491 struct file
*filp
= NULL
;
2492 struct user_namespace
*user_ns
= NULL
;
2494 struct create_context
*context
;
2495 struct lease_ctx_info
*lc
= NULL
;
2496 struct create_ea_buf_req
*ea_buf
= NULL
;
2497 struct oplock_info
*opinfo
;
2498 __le32
*next_ptr
= NULL
;
2499 int req_op_level
= 0, open_flags
= 0, may_flags
= 0, file_info
= 0;
2501 int contxt_cnt
= 0, query_disk_id
= 0;
2502 int maximal_access_ctxt
= 0, posix_ctxt
= 0;
2506 char *stream_name
= NULL
;
2507 bool file_present
= false, created
= false, already_permitted
= false;
2508 int share_ret
, need_truncate
= 0;
2510 umode_t posix_mode
= 0;
2511 __le32 daccess
, maximal_access
= 0;
2513 rsp_org
= work
->response_buf
;
2514 WORK_BUFFERS(work
, req
, rsp
);
2516 if (req
->hdr
.NextCommand
&& !work
->next_smb2_rcv_hdr_off
&&
2517 (req
->hdr
.Flags
& SMB2_FLAGS_RELATED_OPERATIONS
)) {
2518 ksmbd_debug(SMB
, "invalid flag in chained command\n");
2519 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
2520 smb2_set_err_rsp(work
);
2524 if (test_share_config_flag(share
, KSMBD_SHARE_FLAG_PIPE
)) {
2525 ksmbd_debug(SMB
, "IPC pipe create request\n");
2526 return create_smb2_pipe(work
);
2529 if (req
->NameLength
) {
2530 if ((req
->CreateOptions
& FILE_DIRECTORY_FILE_LE
) &&
2531 *(char *)req
->Buffer
== '\\') {
2532 pr_err("not allow directory name included leading slash\n");
2537 name
= smb2_get_name(share
,
2539 le16_to_cpu(req
->NameLength
),
2540 work
->conn
->local_nls
);
2549 ksmbd_debug(SMB
, "converted name = %s\n", name
);
2550 if (strchr(name
, ':')) {
2551 if (!test_share_config_flag(work
->tcon
->share_conf
,
2552 KSMBD_SHARE_FLAG_STREAMS
)) {
2556 rc
= parse_stream_name(name
, &stream_name
, &s_type
);
2561 rc
= ksmbd_validate_filename(name
);
2565 if (ksmbd_share_veto_filename(share
, name
)) {
2567 ksmbd_debug(SMB
, "Reject open(), vetoed file: %s\n",
2572 name
= kstrdup("", GFP_KERNEL
);
2579 req_op_level
= req
->RequestedOplockLevel
;
2580 if (req_op_level
== SMB2_OPLOCK_LEVEL_LEASE
)
2581 lc
= parse_lease_state(req
);
2583 if (le32_to_cpu(req
->ImpersonationLevel
) > le32_to_cpu(IL_DELEGATE_LE
)) {
2584 pr_err("Invalid impersonationlevel : 0x%x\n",
2585 le32_to_cpu(req
->ImpersonationLevel
));
2587 rsp
->hdr
.Status
= STATUS_BAD_IMPERSONATION_LEVEL
;
2591 if (req
->CreateOptions
&& !(req
->CreateOptions
& CREATE_OPTIONS_MASK
)) {
2592 pr_err("Invalid create options : 0x%x\n",
2593 le32_to_cpu(req
->CreateOptions
));
2597 if (req
->CreateOptions
& FILE_SEQUENTIAL_ONLY_LE
&&
2598 req
->CreateOptions
& FILE_RANDOM_ACCESS_LE
)
2599 req
->CreateOptions
= ~(FILE_SEQUENTIAL_ONLY_LE
);
2601 if (req
->CreateOptions
&
2602 (FILE_OPEN_BY_FILE_ID_LE
| CREATE_TREE_CONNECTION
|
2603 FILE_RESERVE_OPFILTER_LE
)) {
2608 if (req
->CreateOptions
& FILE_DIRECTORY_FILE_LE
) {
2609 if (req
->CreateOptions
& FILE_NON_DIRECTORY_FILE_LE
) {
2612 } else if (req
->CreateOptions
& FILE_NO_COMPRESSION_LE
) {
2613 req
->CreateOptions
= ~(FILE_NO_COMPRESSION_LE
);
2618 if (le32_to_cpu(req
->CreateDisposition
) >
2619 le32_to_cpu(FILE_OVERWRITE_IF_LE
)) {
2620 pr_err("Invalid create disposition : 0x%x\n",
2621 le32_to_cpu(req
->CreateDisposition
));
2626 if (!(req
->DesiredAccess
& DESIRED_ACCESS_MASK
)) {
2627 pr_err("Invalid desired access : 0x%x\n",
2628 le32_to_cpu(req
->DesiredAccess
));
2633 if (req
->FileAttributes
&& !(req
->FileAttributes
& ATTR_MASK_LE
)) {
2634 pr_err("Invalid file attribute : 0x%x\n",
2635 le32_to_cpu(req
->FileAttributes
));
2640 if (req
->CreateContextsOffset
) {
2641 /* Parse non-durable handle create contexts */
2642 context
= smb2_find_context_vals(req
, SMB2_CREATE_EA_BUFFER
);
2643 if (IS_ERR(context
)) {
2644 rc
= PTR_ERR(context
);
2646 } else if (context
) {
2647 ea_buf
= (struct create_ea_buf_req
*)context
;
2648 if (le16_to_cpu(context
->DataOffset
) +
2649 le32_to_cpu(context
->DataLength
) <
2650 sizeof(struct create_ea_buf_req
)) {
2654 if (req
->CreateOptions
& FILE_NO_EA_KNOWLEDGE_LE
) {
2655 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
2661 context
= smb2_find_context_vals(req
,
2662 SMB2_CREATE_QUERY_MAXIMAL_ACCESS_REQUEST
);
2663 if (IS_ERR(context
)) {
2664 rc
= PTR_ERR(context
);
2666 } else if (context
) {
2668 "get query maximal access context\n");
2669 maximal_access_ctxt
= 1;
2672 context
= smb2_find_context_vals(req
,
2673 SMB2_CREATE_TIMEWARP_REQUEST
);
2674 if (IS_ERR(context
)) {
2675 rc
= PTR_ERR(context
);
2677 } else if (context
) {
2678 ksmbd_debug(SMB
, "get timewarp context\n");
2683 if (tcon
->posix_extensions
) {
2684 context
= smb2_find_context_vals(req
,
2685 SMB2_CREATE_TAG_POSIX
);
2686 if (IS_ERR(context
)) {
2687 rc
= PTR_ERR(context
);
2689 } else if (context
) {
2690 struct create_posix
*posix
=
2691 (struct create_posix
*)context
;
2692 if (le16_to_cpu(context
->DataOffset
) +
2693 le32_to_cpu(context
->DataLength
) <
2694 sizeof(struct create_posix
) - 4) {
2698 ksmbd_debug(SMB
, "get posix context\n");
2700 posix_mode
= le32_to_cpu(posix
->Mode
);
2706 if (ksmbd_override_fsids(work
)) {
2711 rc
= ksmbd_vfs_kern_path(work
, name
, LOOKUP_NO_SYMLINKS
, &path
, 1);
2713 if (req
->CreateOptions
& FILE_DELETE_ON_CLOSE_LE
) {
2715 * If file exists with under flags, return access
2718 if (req
->CreateDisposition
== FILE_OVERWRITE_IF_LE
||
2719 req
->CreateDisposition
== FILE_OPEN_IF_LE
) {
2725 if (!test_tree_conn_flag(tcon
, KSMBD_TREE_CONN_FLAG_WRITABLE
)) {
2727 "User does not have write permission\n");
2732 } else if (d_is_symlink(path
.dentry
)) {
2742 ksmbd_debug(SMB
, "can not get linux path for %s, rc = %d\n",
2746 file_present
= true;
2747 user_ns
= mnt_user_ns(path
.mnt
);
2748 generic_fillattr(user_ns
, d_inode(path
.dentry
), &stat
);
2751 if (req
->CreateOptions
& FILE_DIRECTORY_FILE_LE
) {
2752 if (s_type
== DATA_STREAM
) {
2754 rsp
->hdr
.Status
= STATUS_NOT_A_DIRECTORY
;
2757 if (S_ISDIR(stat
.mode
) && s_type
== DATA_STREAM
) {
2759 rsp
->hdr
.Status
= STATUS_FILE_IS_A_DIRECTORY
;
2763 if (req
->CreateOptions
& FILE_DIRECTORY_FILE_LE
&&
2764 req
->FileAttributes
& ATTR_NORMAL_LE
) {
2765 rsp
->hdr
.Status
= STATUS_NOT_A_DIRECTORY
;
2773 if (file_present
&& req
->CreateOptions
& FILE_NON_DIRECTORY_FILE_LE
&&
2774 S_ISDIR(stat
.mode
) && !(req
->CreateOptions
& FILE_DELETE_ON_CLOSE_LE
)) {
2775 ksmbd_debug(SMB
, "open() argument is a directory: %s, %x\n",
2776 name
, req
->CreateOptions
);
2777 rsp
->hdr
.Status
= STATUS_FILE_IS_A_DIRECTORY
;
2782 if (file_present
&& (req
->CreateOptions
& FILE_DIRECTORY_FILE_LE
) &&
2783 !(req
->CreateDisposition
== FILE_CREATE_LE
) &&
2784 !S_ISDIR(stat
.mode
)) {
2785 rsp
->hdr
.Status
= STATUS_NOT_A_DIRECTORY
;
2790 if (!stream_name
&& file_present
&&
2791 req
->CreateDisposition
== FILE_CREATE_LE
) {
2796 daccess
= smb_map_generic_desired_access(req
->DesiredAccess
);
2798 if (file_present
&& !(req
->CreateOptions
& FILE_DELETE_ON_CLOSE_LE
)) {
2799 rc
= smb_check_perm_dacl(conn
, &path
, &daccess
,
2805 if (daccess
& FILE_MAXIMAL_ACCESS_LE
) {
2806 if (!file_present
) {
2807 daccess
= cpu_to_le32(GENERIC_ALL_FLAGS
);
2809 rc
= ksmbd_vfs_query_maximal_access(user_ns
,
2814 already_permitted
= true;
2816 maximal_access
= daccess
;
2819 open_flags
= smb2_create_open_flags(file_present
, daccess
,
2820 req
->CreateDisposition
,
2823 if (!test_tree_conn_flag(tcon
, KSMBD_TREE_CONN_FLAG_WRITABLE
)) {
2824 if (open_flags
& O_CREAT
) {
2826 "User does not have write permission\n");
2832 /*create file if not present */
2833 if (!file_present
) {
2834 rc
= smb2_creat(work
, &path
, name
, open_flags
, posix_mode
,
2835 req
->CreateOptions
& FILE_DIRECTORY_FILE_LE
);
2837 if (rc
== -ENOENT
) {
2839 rsp
->hdr
.Status
= STATUS_OBJECT_PATH_NOT_FOUND
;
2845 user_ns
= mnt_user_ns(path
.mnt
);
2847 if (le32_to_cpu(ea_buf
->ccontext
.DataLength
) <
2848 sizeof(struct smb2_ea_info
)) {
2853 rc
= smb2_set_ea(&ea_buf
->ea
,
2854 le32_to_cpu(ea_buf
->ccontext
.DataLength
),
2856 if (rc
== -EOPNOTSUPP
)
2861 } else if (!already_permitted
) {
2862 /* FILE_READ_ATTRIBUTE is allowed without inode_permission,
2863 * because execute(search) permission on a parent directory,
2864 * is already granted.
2866 if (daccess
& ~(FILE_READ_ATTRIBUTES_LE
| FILE_READ_CONTROL_LE
)) {
2867 rc
= inode_permission(user_ns
,
2868 d_inode(path
.dentry
),
2873 if ((daccess
& FILE_DELETE_LE
) ||
2874 (req
->CreateOptions
& FILE_DELETE_ON_CLOSE_LE
)) {
2875 rc
= ksmbd_vfs_may_delete(user_ns
,
2883 rc
= ksmbd_query_inode_status(d_inode(path
.dentry
->d_parent
));
2884 if (rc
== KSMBD_INODE_STATUS_PENDING_DELETE
) {
2890 filp
= dentry_open(&path
, open_flags
, current_cred());
2893 pr_err("dentry open for dir failed, rc %d\n", rc
);
2898 if (!(open_flags
& O_TRUNC
))
2899 file_info
= FILE_OPENED
;
2901 file_info
= FILE_OVERWRITTEN
;
2903 if ((req
->CreateDisposition
& FILE_CREATE_MASK_LE
) ==
2905 file_info
= FILE_SUPERSEDED
;
2906 } else if (open_flags
& O_CREAT
) {
2907 file_info
= FILE_CREATED
;
2910 ksmbd_vfs_set_fadvise(filp
, req
->CreateOptions
);
2912 /* Obtain Volatile-ID */
2913 fp
= ksmbd_open_fd(work
, filp
);
2921 /* Get Persistent-ID */
2922 ksmbd_open_durable_fd(fp
);
2923 if (!has_file_id(fp
->persistent_id
)) {
2928 fp
->filename
= name
;
2929 fp
->cdoption
= req
->CreateDisposition
;
2930 fp
->daccess
= daccess
;
2931 fp
->saccess
= req
->ShareAccess
;
2932 fp
->coption
= req
->CreateOptions
;
2934 /* Set default windows and posix acls if creating new file */
2937 struct inode
*inode
= d_inode(path
.dentry
);
2939 posix_acl_rc
= ksmbd_vfs_inherit_posix_acl(user_ns
,
2941 d_inode(path
.dentry
->d_parent
));
2943 ksmbd_debug(SMB
, "inherit posix acl failed : %d\n", posix_acl_rc
);
2945 if (test_share_config_flag(work
->tcon
->share_conf
,
2946 KSMBD_SHARE_FLAG_ACL_XATTR
)) {
2947 rc
= smb_inherit_dacl(conn
, &path
, sess
->user
->uid
,
2952 rc
= smb2_create_sd_buffer(work
, req
, &path
);
2955 ksmbd_vfs_set_init_posix_acl(user_ns
,
2958 if (test_share_config_flag(work
->tcon
->share_conf
,
2959 KSMBD_SHARE_FLAG_ACL_XATTR
)) {
2960 struct smb_fattr fattr
;
2961 struct smb_ntsd
*pntsd
;
2962 int pntsd_size
, ace_num
= 0;
2964 ksmbd_acls_fattr(&fattr
, user_ns
, inode
);
2966 ace_num
= fattr
.cf_acls
->a_count
;
2968 ace_num
+= fattr
.cf_dacls
->a_count
;
2970 pntsd
= kmalloc(sizeof(struct smb_ntsd
) +
2971 sizeof(struct smb_sid
) * 3 +
2972 sizeof(struct smb_acl
) +
2973 sizeof(struct smb_ace
) * ace_num
* 2,
2978 rc
= build_sec_desc(user_ns
,
2983 &pntsd_size
, &fattr
);
2984 posix_acl_release(fattr
.cf_acls
);
2985 posix_acl_release(fattr
.cf_dacls
);
2991 rc
= ksmbd_vfs_set_sd_xattr(conn
,
2998 pr_err("failed to store ntacl in xattr : %d\n",
3007 rc
= smb2_set_stream_name_xattr(&path
,
3013 file_info
= FILE_CREATED
;
3016 fp
->attrib_only
= !(req
->DesiredAccess
& ~(FILE_READ_ATTRIBUTES_LE
|
3017 FILE_WRITE_ATTRIBUTES_LE
| FILE_SYNCHRONIZE_LE
));
3018 if (!S_ISDIR(file_inode(filp
)->i_mode
) && open_flags
& O_TRUNC
&&
3019 !fp
->attrib_only
&& !stream_name
) {
3020 smb_break_all_oplock(work
, fp
);
3024 /* fp should be searchable through ksmbd_inode.m_fp_list
3025 * after daccess, saccess, attrib_only, and stream are
3028 write_lock(&fp
->f_ci
->m_lock
);
3029 list_add(&fp
->node
, &fp
->f_ci
->m_fp_list
);
3030 write_unlock(&fp
->f_ci
->m_lock
);
3032 rc
= ksmbd_vfs_getattr(&path
, &stat
);
3034 generic_fillattr(user_ns
, d_inode(path
.dentry
), &stat
);
3038 /* Check delete pending among previous fp before oplock break */
3039 if (ksmbd_inode_pending_delete(fp
)) {
3044 share_ret
= ksmbd_smb_check_shared_mode(fp
->filp
, fp
);
3045 if (!test_share_config_flag(work
->tcon
->share_conf
, KSMBD_SHARE_FLAG_OPLOCKS
) ||
3046 (req_op_level
== SMB2_OPLOCK_LEVEL_LEASE
&&
3047 !(conn
->vals
->capabilities
& SMB2_GLOBAL_CAP_LEASING
))) {
3048 if (share_ret
< 0 && !S_ISDIR(file_inode(fp
->filp
)->i_mode
)) {
3053 if (req_op_level
== SMB2_OPLOCK_LEVEL_LEASE
) {
3054 req_op_level
= smb2_map_lease_to_oplock(lc
->req_state
);
3056 "lease req for(%s) req oplock state 0x%x, lease state 0x%x\n",
3057 name
, req_op_level
, lc
->req_state
);
3058 rc
= find_same_lease_key(sess
, fp
->f_ci
, lc
);
3061 } else if (open_flags
== O_RDONLY
&&
3062 (req_op_level
== SMB2_OPLOCK_LEVEL_BATCH
||
3063 req_op_level
== SMB2_OPLOCK_LEVEL_EXCLUSIVE
))
3064 req_op_level
= SMB2_OPLOCK_LEVEL_II
;
3066 rc
= smb_grant_oplock(work
, req_op_level
,
3067 fp
->persistent_id
, fp
,
3068 le32_to_cpu(req
->hdr
.Id
.SyncId
.TreeId
),
3074 if (req
->CreateOptions
& FILE_DELETE_ON_CLOSE_LE
)
3075 ksmbd_fd_set_delete_on_close(fp
, file_info
);
3077 if (need_truncate
) {
3078 rc
= smb2_create_truncate(&path
);
3083 if (req
->CreateContextsOffset
) {
3084 struct create_alloc_size_req
*az_req
;
3086 az_req
= (struct create_alloc_size_req
*)smb2_find_context_vals(req
,
3087 SMB2_CREATE_ALLOCATION_SIZE
);
3088 if (IS_ERR(az_req
)) {
3089 rc
= PTR_ERR(az_req
);
3091 } else if (az_req
) {
3095 if (le16_to_cpu(az_req
->ccontext
.DataOffset
) +
3096 le32_to_cpu(az_req
->ccontext
.DataLength
) <
3097 sizeof(struct create_alloc_size_req
)) {
3101 alloc_size
= le64_to_cpu(az_req
->AllocationSize
);
3103 "request smb2 create allocate size : %llu\n",
3105 smb_break_all_levII_oplock(work
, fp
, 1);
3106 err
= vfs_fallocate(fp
->filp
, FALLOC_FL_KEEP_SIZE
, 0,
3110 "vfs_fallocate is failed : %d\n",
3114 context
= smb2_find_context_vals(req
, SMB2_CREATE_QUERY_ON_DISK_ID
);
3115 if (IS_ERR(context
)) {
3116 rc
= PTR_ERR(context
);
3118 } else if (context
) {
3119 ksmbd_debug(SMB
, "get query on disk id context\n");
3124 if (stat
.result_mask
& STATX_BTIME
)
3125 fp
->create_time
= ksmbd_UnixTimeToNT(stat
.btime
);
3127 fp
->create_time
= ksmbd_UnixTimeToNT(stat
.ctime
);
3128 if (req
->FileAttributes
|| fp
->f_ci
->m_fattr
== 0)
3130 cpu_to_le32(smb2_get_dos_mode(&stat
, le32_to_cpu(req
->FileAttributes
)));
3133 smb2_update_xattrs(tcon
, &path
, fp
);
3135 smb2_new_xattrs(tcon
, &path
, fp
);
3137 memcpy(fp
->client_guid
, conn
->ClientGUID
, SMB2_CLIENT_GUID_SIZE
);
3139 generic_fillattr(user_ns
, file_inode(fp
->filp
),
3142 rsp
->StructureSize
= cpu_to_le16(89);
3144 opinfo
= rcu_dereference(fp
->f_opinfo
);
3145 rsp
->OplockLevel
= opinfo
!= NULL
? opinfo
->level
: 0;
3148 rsp
->CreateAction
= cpu_to_le32(file_info
);
3149 rsp
->CreationTime
= cpu_to_le64(fp
->create_time
);
3150 time
= ksmbd_UnixTimeToNT(stat
.atime
);
3151 rsp
->LastAccessTime
= cpu_to_le64(time
);
3152 time
= ksmbd_UnixTimeToNT(stat
.mtime
);
3153 rsp
->LastWriteTime
= cpu_to_le64(time
);
3154 time
= ksmbd_UnixTimeToNT(stat
.ctime
);
3155 rsp
->ChangeTime
= cpu_to_le64(time
);
3156 rsp
->AllocationSize
= S_ISDIR(stat
.mode
) ? 0 :
3157 cpu_to_le64(stat
.blocks
<< 9);
3158 rsp
->EndofFile
= S_ISDIR(stat
.mode
) ? 0 : cpu_to_le64(stat
.size
);
3159 rsp
->FileAttributes
= fp
->f_ci
->m_fattr
;
3163 rsp
->PersistentFileId
= cpu_to_le64(fp
->persistent_id
);
3164 rsp
->VolatileFileId
= cpu_to_le64(fp
->volatile_id
);
3166 rsp
->CreateContextsOffset
= 0;
3167 rsp
->CreateContextsLength
= 0;
3168 inc_rfc1001_len(rsp_org
, 88); /* StructureSize - 1*/
3170 /* If lease is request send lease context response */
3171 if (opinfo
&& opinfo
->is_lease
) {
3172 struct create_context
*lease_ccontext
;
3174 ksmbd_debug(SMB
, "lease granted on(%s) lease state 0x%x\n",
3175 name
, opinfo
->o_lease
->state
);
3176 rsp
->OplockLevel
= SMB2_OPLOCK_LEVEL_LEASE
;
3178 lease_ccontext
= (struct create_context
*)rsp
->Buffer
;
3180 create_lease_buf(rsp
->Buffer
, opinfo
->o_lease
);
3181 le32_add_cpu(&rsp
->CreateContextsLength
,
3182 conn
->vals
->create_lease_size
);
3183 inc_rfc1001_len(rsp_org
, conn
->vals
->create_lease_size
);
3184 next_ptr
= &lease_ccontext
->Next
;
3185 next_off
= conn
->vals
->create_lease_size
;
3188 if (maximal_access_ctxt
) {
3189 struct create_context
*mxac_ccontext
;
3191 if (maximal_access
== 0)
3192 ksmbd_vfs_query_maximal_access(user_ns
,
3195 mxac_ccontext
= (struct create_context
*)(rsp
->Buffer
+
3196 le32_to_cpu(rsp
->CreateContextsLength
));
3198 create_mxac_rsp_buf(rsp
->Buffer
+
3199 le32_to_cpu(rsp
->CreateContextsLength
),
3200 le32_to_cpu(maximal_access
));
3201 le32_add_cpu(&rsp
->CreateContextsLength
,
3202 conn
->vals
->create_mxac_size
);
3203 inc_rfc1001_len(rsp_org
, conn
->vals
->create_mxac_size
);
3205 *next_ptr
= cpu_to_le32(next_off
);
3206 next_ptr
= &mxac_ccontext
->Next
;
3207 next_off
= conn
->vals
->create_mxac_size
;
3210 if (query_disk_id
) {
3211 struct create_context
*disk_id_ccontext
;
3213 disk_id_ccontext
= (struct create_context
*)(rsp
->Buffer
+
3214 le32_to_cpu(rsp
->CreateContextsLength
));
3216 create_disk_id_rsp_buf(rsp
->Buffer
+
3217 le32_to_cpu(rsp
->CreateContextsLength
),
3218 stat
.ino
, tcon
->id
);
3219 le32_add_cpu(&rsp
->CreateContextsLength
,
3220 conn
->vals
->create_disk_id_size
);
3221 inc_rfc1001_len(rsp_org
, conn
->vals
->create_disk_id_size
);
3223 *next_ptr
= cpu_to_le32(next_off
);
3224 next_ptr
= &disk_id_ccontext
->Next
;
3225 next_off
= conn
->vals
->create_disk_id_size
;
3230 create_posix_rsp_buf(rsp
->Buffer
+
3231 le32_to_cpu(rsp
->CreateContextsLength
),
3233 le32_add_cpu(&rsp
->CreateContextsLength
,
3234 conn
->vals
->create_posix_size
);
3235 inc_rfc1001_len(rsp_org
, conn
->vals
->create_posix_size
);
3237 *next_ptr
= cpu_to_le32(next_off
);
3240 if (contxt_cnt
> 0) {
3241 rsp
->CreateContextsOffset
=
3242 cpu_to_le32(offsetof(struct smb2_create_rsp
, Buffer
)
3247 if (file_present
|| created
)
3249 ksmbd_revert_fsids(work
);
3253 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
3254 else if (rc
== -EOPNOTSUPP
)
3255 rsp
->hdr
.Status
= STATUS_NOT_SUPPORTED
;
3256 else if (rc
== -EACCES
|| rc
== -ESTALE
|| rc
== -EXDEV
)
3257 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
3258 else if (rc
== -ENOENT
)
3259 rsp
->hdr
.Status
= STATUS_OBJECT_NAME_INVALID
;
3260 else if (rc
== -EPERM
)
3261 rsp
->hdr
.Status
= STATUS_SHARING_VIOLATION
;
3262 else if (rc
== -EBUSY
)
3263 rsp
->hdr
.Status
= STATUS_DELETE_PENDING
;
3264 else if (rc
== -EBADF
)
3265 rsp
->hdr
.Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
3266 else if (rc
== -ENOEXEC
)
3267 rsp
->hdr
.Status
= STATUS_DUPLICATE_OBJECTID
;
3268 else if (rc
== -ENXIO
)
3269 rsp
->hdr
.Status
= STATUS_NO_SUCH_DEVICE
;
3270 else if (rc
== -EEXIST
)
3271 rsp
->hdr
.Status
= STATUS_OBJECT_NAME_COLLISION
;
3272 else if (rc
== -EMFILE
)
3273 rsp
->hdr
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
3274 if (!rsp
->hdr
.Status
)
3275 rsp
->hdr
.Status
= STATUS_UNEXPECTED_IO_ERROR
;
3277 if (!fp
|| !fp
->filename
)
3280 ksmbd_fd_put(work
, fp
);
3281 smb2_set_err_rsp(work
);
3282 ksmbd_debug(SMB
, "Error response: %x\n", rsp
->hdr
.Status
);
3290 static int readdir_info_level_struct_sz(int info_level
)
3292 switch (info_level
) {
3293 case FILE_FULL_DIRECTORY_INFORMATION
:
3294 return sizeof(struct file_full_directory_info
);
3295 case FILE_BOTH_DIRECTORY_INFORMATION
:
3296 return sizeof(struct file_both_directory_info
);
3297 case FILE_DIRECTORY_INFORMATION
:
3298 return sizeof(struct file_directory_info
);
3299 case FILE_NAMES_INFORMATION
:
3300 return sizeof(struct file_names_info
);
3301 case FILEID_FULL_DIRECTORY_INFORMATION
:
3302 return sizeof(struct file_id_full_dir_info
);
3303 case FILEID_BOTH_DIRECTORY_INFORMATION
:
3304 return sizeof(struct file_id_both_directory_info
);
3305 case SMB_FIND_FILE_POSIX_INFO
:
3306 return sizeof(struct smb2_posix_info
);
3312 static int dentry_name(struct ksmbd_dir_info
*d_info
, int info_level
)
3314 switch (info_level
) {
3315 case FILE_FULL_DIRECTORY_INFORMATION
:
3317 struct file_full_directory_info
*ffdinfo
;
3319 ffdinfo
= (struct file_full_directory_info
*)d_info
->rptr
;
3320 d_info
->rptr
+= le32_to_cpu(ffdinfo
->NextEntryOffset
);
3321 d_info
->name
= ffdinfo
->FileName
;
3322 d_info
->name_len
= le32_to_cpu(ffdinfo
->FileNameLength
);
3325 case FILE_BOTH_DIRECTORY_INFORMATION
:
3327 struct file_both_directory_info
*fbdinfo
;
3329 fbdinfo
= (struct file_both_directory_info
*)d_info
->rptr
;
3330 d_info
->rptr
+= le32_to_cpu(fbdinfo
->NextEntryOffset
);
3331 d_info
->name
= fbdinfo
->FileName
;
3332 d_info
->name_len
= le32_to_cpu(fbdinfo
->FileNameLength
);
3335 case FILE_DIRECTORY_INFORMATION
:
3337 struct file_directory_info
*fdinfo
;
3339 fdinfo
= (struct file_directory_info
*)d_info
->rptr
;
3340 d_info
->rptr
+= le32_to_cpu(fdinfo
->NextEntryOffset
);
3341 d_info
->name
= fdinfo
->FileName
;
3342 d_info
->name_len
= le32_to_cpu(fdinfo
->FileNameLength
);
3345 case FILE_NAMES_INFORMATION
:
3347 struct file_names_info
*fninfo
;
3349 fninfo
= (struct file_names_info
*)d_info
->rptr
;
3350 d_info
->rptr
+= le32_to_cpu(fninfo
->NextEntryOffset
);
3351 d_info
->name
= fninfo
->FileName
;
3352 d_info
->name_len
= le32_to_cpu(fninfo
->FileNameLength
);
3355 case FILEID_FULL_DIRECTORY_INFORMATION
:
3357 struct file_id_full_dir_info
*dinfo
;
3359 dinfo
= (struct file_id_full_dir_info
*)d_info
->rptr
;
3360 d_info
->rptr
+= le32_to_cpu(dinfo
->NextEntryOffset
);
3361 d_info
->name
= dinfo
->FileName
;
3362 d_info
->name_len
= le32_to_cpu(dinfo
->FileNameLength
);
3365 case FILEID_BOTH_DIRECTORY_INFORMATION
:
3367 struct file_id_both_directory_info
*fibdinfo
;
3369 fibdinfo
= (struct file_id_both_directory_info
*)d_info
->rptr
;
3370 d_info
->rptr
+= le32_to_cpu(fibdinfo
->NextEntryOffset
);
3371 d_info
->name
= fibdinfo
->FileName
;
3372 d_info
->name_len
= le32_to_cpu(fibdinfo
->FileNameLength
);
3375 case SMB_FIND_FILE_POSIX_INFO
:
3377 struct smb2_posix_info
*posix_info
;
3379 posix_info
= (struct smb2_posix_info
*)d_info
->rptr
;
3380 d_info
->rptr
+= le32_to_cpu(posix_info
->NextEntryOffset
);
3381 d_info
->name
= posix_info
->name
;
3382 d_info
->name_len
= le32_to_cpu(posix_info
->name_len
);
3391 * smb2_populate_readdir_entry() - encode directory entry in smb2 response
3393 * @conn: connection instance
3394 * @info_level: smb information level
3395 * @d_info: structure included variables for query dir
3396 * @user_ns: user namespace
3397 * @ksmbd_kstat: ksmbd wrapper of dirent stat information
3399 * if directory has many entries, find first can't read it fully.
3400 * find next might be called multiple times to read remaining dir entries
3402 * Return: 0 on success, otherwise error
3404 static int smb2_populate_readdir_entry(struct ksmbd_conn
*conn
, int info_level
,
3405 struct ksmbd_dir_info
*d_info
,
3406 struct ksmbd_kstat
*ksmbd_kstat
)
3408 int next_entry_offset
= 0;
3412 int struct_sz
, rc
= 0;
3414 conv_name
= ksmbd_convert_dir_info_name(d_info
,
3420 /* Somehow the name has only terminating NULL bytes */
3423 goto free_conv_name
;
3426 struct_sz
= readdir_info_level_struct_sz(info_level
) - 1 + conv_len
;
3427 next_entry_offset
= ALIGN(struct_sz
, KSMBD_DIR_INFO_ALIGNMENT
);
3428 d_info
->last_entry_off_align
= next_entry_offset
- struct_sz
;
3430 if (next_entry_offset
> d_info
->out_buf_len
) {
3431 d_info
->out_buf_len
= 0;
3433 goto free_conv_name
;
3436 kstat
= d_info
->wptr
;
3437 if (info_level
!= FILE_NAMES_INFORMATION
)
3438 kstat
= ksmbd_vfs_init_kstat(&d_info
->wptr
, ksmbd_kstat
);
3440 switch (info_level
) {
3441 case FILE_FULL_DIRECTORY_INFORMATION
:
3443 struct file_full_directory_info
*ffdinfo
;
3445 ffdinfo
= (struct file_full_directory_info
*)kstat
;
3446 ffdinfo
->FileNameLength
= cpu_to_le32(conv_len
);
3448 smb2_get_reparse_tag_special_file(ksmbd_kstat
->kstat
->mode
);
3449 if (ffdinfo
->EaSize
)
3450 ffdinfo
->ExtFileAttributes
= ATTR_REPARSE_POINT_LE
;
3451 if (d_info
->hide_dot_file
&& d_info
->name
[0] == '.')
3452 ffdinfo
->ExtFileAttributes
|= ATTR_HIDDEN_LE
;
3453 memcpy(ffdinfo
->FileName
, conv_name
, conv_len
);
3454 ffdinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
3457 case FILE_BOTH_DIRECTORY_INFORMATION
:
3459 struct file_both_directory_info
*fbdinfo
;
3461 fbdinfo
= (struct file_both_directory_info
*)kstat
;
3462 fbdinfo
->FileNameLength
= cpu_to_le32(conv_len
);
3464 smb2_get_reparse_tag_special_file(ksmbd_kstat
->kstat
->mode
);
3465 if (fbdinfo
->EaSize
)
3466 fbdinfo
->ExtFileAttributes
= ATTR_REPARSE_POINT_LE
;
3467 fbdinfo
->ShortNameLength
= 0;
3468 fbdinfo
->Reserved
= 0;
3469 if (d_info
->hide_dot_file
&& d_info
->name
[0] == '.')
3470 fbdinfo
->ExtFileAttributes
|= ATTR_HIDDEN_LE
;
3471 memcpy(fbdinfo
->FileName
, conv_name
, conv_len
);
3472 fbdinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
3475 case FILE_DIRECTORY_INFORMATION
:
3477 struct file_directory_info
*fdinfo
;
3479 fdinfo
= (struct file_directory_info
*)kstat
;
3480 fdinfo
->FileNameLength
= cpu_to_le32(conv_len
);
3481 if (d_info
->hide_dot_file
&& d_info
->name
[0] == '.')
3482 fdinfo
->ExtFileAttributes
|= ATTR_HIDDEN_LE
;
3483 memcpy(fdinfo
->FileName
, conv_name
, conv_len
);
3484 fdinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
3487 case FILE_NAMES_INFORMATION
:
3489 struct file_names_info
*fninfo
;
3491 fninfo
= (struct file_names_info
*)kstat
;
3492 fninfo
->FileNameLength
= cpu_to_le32(conv_len
);
3493 memcpy(fninfo
->FileName
, conv_name
, conv_len
);
3494 fninfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
3497 case FILEID_FULL_DIRECTORY_INFORMATION
:
3499 struct file_id_full_dir_info
*dinfo
;
3501 dinfo
= (struct file_id_full_dir_info
*)kstat
;
3502 dinfo
->FileNameLength
= cpu_to_le32(conv_len
);
3504 smb2_get_reparse_tag_special_file(ksmbd_kstat
->kstat
->mode
);
3506 dinfo
->ExtFileAttributes
= ATTR_REPARSE_POINT_LE
;
3507 dinfo
->Reserved
= 0;
3508 dinfo
->UniqueId
= cpu_to_le64(ksmbd_kstat
->kstat
->ino
);
3509 if (d_info
->hide_dot_file
&& d_info
->name
[0] == '.')
3510 dinfo
->ExtFileAttributes
|= ATTR_HIDDEN_LE
;
3511 memcpy(dinfo
->FileName
, conv_name
, conv_len
);
3512 dinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
3515 case FILEID_BOTH_DIRECTORY_INFORMATION
:
3517 struct file_id_both_directory_info
*fibdinfo
;
3519 fibdinfo
= (struct file_id_both_directory_info
*)kstat
;
3520 fibdinfo
->FileNameLength
= cpu_to_le32(conv_len
);
3522 smb2_get_reparse_tag_special_file(ksmbd_kstat
->kstat
->mode
);
3523 if (fibdinfo
->EaSize
)
3524 fibdinfo
->ExtFileAttributes
= ATTR_REPARSE_POINT_LE
;
3525 fibdinfo
->UniqueId
= cpu_to_le64(ksmbd_kstat
->kstat
->ino
);
3526 fibdinfo
->ShortNameLength
= 0;
3527 fibdinfo
->Reserved
= 0;
3528 fibdinfo
->Reserved2
= cpu_to_le16(0);
3529 if (d_info
->hide_dot_file
&& d_info
->name
[0] == '.')
3530 fibdinfo
->ExtFileAttributes
|= ATTR_HIDDEN_LE
;
3531 memcpy(fibdinfo
->FileName
, conv_name
, conv_len
);
3532 fibdinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
3535 case SMB_FIND_FILE_POSIX_INFO
:
3537 struct smb2_posix_info
*posix_info
;
3540 posix_info
= (struct smb2_posix_info
*)kstat
;
3541 posix_info
->Ignored
= 0;
3542 posix_info
->CreationTime
= cpu_to_le64(ksmbd_kstat
->create_time
);
3543 time
= ksmbd_UnixTimeToNT(ksmbd_kstat
->kstat
->ctime
);
3544 posix_info
->ChangeTime
= cpu_to_le64(time
);
3545 time
= ksmbd_UnixTimeToNT(ksmbd_kstat
->kstat
->atime
);
3546 posix_info
->LastAccessTime
= cpu_to_le64(time
);
3547 time
= ksmbd_UnixTimeToNT(ksmbd_kstat
->kstat
->mtime
);
3548 posix_info
->LastWriteTime
= cpu_to_le64(time
);
3549 posix_info
->EndOfFile
= cpu_to_le64(ksmbd_kstat
->kstat
->size
);
3550 posix_info
->AllocationSize
= cpu_to_le64(ksmbd_kstat
->kstat
->blocks
<< 9);
3551 posix_info
->DeviceId
= cpu_to_le32(ksmbd_kstat
->kstat
->rdev
);
3552 posix_info
->HardLinks
= cpu_to_le32(ksmbd_kstat
->kstat
->nlink
);
3553 posix_info
->Mode
= cpu_to_le32(ksmbd_kstat
->kstat
->mode
);
3554 posix_info
->Inode
= cpu_to_le64(ksmbd_kstat
->kstat
->ino
);
3555 posix_info
->DosAttributes
=
3556 S_ISDIR(ksmbd_kstat
->kstat
->mode
) ? ATTR_DIRECTORY_LE
: ATTR_ARCHIVE_LE
;
3557 if (d_info
->hide_dot_file
&& d_info
->name
[0] == '.')
3558 posix_info
->DosAttributes
|= ATTR_HIDDEN_LE
;
3559 id_to_sid(from_kuid_munged(&init_user_ns
, ksmbd_kstat
->kstat
->uid
),
3560 SIDNFS_USER
, (struct smb_sid
*)&posix_info
->SidBuffer
[0]);
3561 id_to_sid(from_kgid_munged(&init_user_ns
, ksmbd_kstat
->kstat
->gid
),
3562 SIDNFS_GROUP
, (struct smb_sid
*)&posix_info
->SidBuffer
[20]);
3563 memcpy(posix_info
->name
, conv_name
, conv_len
);
3564 posix_info
->name_len
= cpu_to_le32(conv_len
);
3565 posix_info
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
3569 } /* switch (info_level) */
3571 d_info
->last_entry_offset
= d_info
->data_count
;
3572 d_info
->data_count
+= next_entry_offset
;
3573 d_info
->out_buf_len
-= next_entry_offset
;
3574 d_info
->wptr
+= next_entry_offset
;
3577 "info_level : %d, buf_len :%d, next_offset : %d, data_count : %d\n",
3578 info_level
, d_info
->out_buf_len
,
3579 next_entry_offset
, d_info
->data_count
);
3586 struct smb2_query_dir_private
{
3587 struct ksmbd_work
*work
;
3588 char *search_pattern
;
3589 struct ksmbd_file
*dir_fp
;
3591 struct ksmbd_dir_info
*d_info
;
3595 static void lock_dir(struct ksmbd_file
*dir_fp
)
3597 struct dentry
*dir
= dir_fp
->filp
->f_path
.dentry
;
3599 inode_lock_nested(d_inode(dir
), I_MUTEX_PARENT
);
3602 static void unlock_dir(struct ksmbd_file
*dir_fp
)
3604 struct dentry
*dir
= dir_fp
->filp
->f_path
.dentry
;
3606 inode_unlock(d_inode(dir
));
3609 static int process_query_dir_entries(struct smb2_query_dir_private
*priv
)
3611 struct user_namespace
*user_ns
= file_mnt_user_ns(priv
->dir_fp
->filp
);
3613 struct ksmbd_kstat ksmbd_kstat
;
3617 for (i
= 0; i
< priv
->d_info
->num_entry
; i
++) {
3618 struct dentry
*dent
;
3620 if (dentry_name(priv
->d_info
, priv
->info_level
))
3623 lock_dir(priv
->dir_fp
);
3624 dent
= lookup_one(user_ns
, priv
->d_info
->name
,
3625 priv
->dir_fp
->filp
->f_path
.dentry
,
3626 priv
->d_info
->name_len
);
3627 unlock_dir(priv
->dir_fp
);
3630 ksmbd_debug(SMB
, "Cannot lookup `%s' [%ld]\n",
3635 if (unlikely(d_is_negative(dent
))) {
3637 ksmbd_debug(SMB
, "Negative dentry `%s'\n",
3638 priv
->d_info
->name
);
3642 ksmbd_kstat
.kstat
= &kstat
;
3643 if (priv
->info_level
!= FILE_NAMES_INFORMATION
)
3644 ksmbd_vfs_fill_dentry_attrs(priv
->work
,
3649 rc
= smb2_populate_readdir_entry(priv
->work
->conn
,
3660 static int reserve_populate_dentry(struct ksmbd_dir_info
*d_info
,
3665 int next_entry_offset
;
3667 struct_sz
= readdir_info_level_struct_sz(info_level
);
3668 if (struct_sz
== -EOPNOTSUPP
)
3671 conv_len
= (d_info
->name_len
+ 1) * 2;
3672 next_entry_offset
= ALIGN(struct_sz
- 1 + conv_len
,
3673 KSMBD_DIR_INFO_ALIGNMENT
);
3675 if (next_entry_offset
> d_info
->out_buf_len
) {
3676 d_info
->out_buf_len
= 0;
3680 switch (info_level
) {
3681 case FILE_FULL_DIRECTORY_INFORMATION
:
3683 struct file_full_directory_info
*ffdinfo
;
3685 ffdinfo
= (struct file_full_directory_info
*)d_info
->wptr
;
3686 memcpy(ffdinfo
->FileName
, d_info
->name
, d_info
->name_len
);
3687 ffdinfo
->FileName
[d_info
->name_len
] = 0x00;
3688 ffdinfo
->FileNameLength
= cpu_to_le32(d_info
->name_len
);
3689 ffdinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
3692 case FILE_BOTH_DIRECTORY_INFORMATION
:
3694 struct file_both_directory_info
*fbdinfo
;
3696 fbdinfo
= (struct file_both_directory_info
*)d_info
->wptr
;
3697 memcpy(fbdinfo
->FileName
, d_info
->name
, d_info
->name_len
);
3698 fbdinfo
->FileName
[d_info
->name_len
] = 0x00;
3699 fbdinfo
->FileNameLength
= cpu_to_le32(d_info
->name_len
);
3700 fbdinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
3703 case FILE_DIRECTORY_INFORMATION
:
3705 struct file_directory_info
*fdinfo
;
3707 fdinfo
= (struct file_directory_info
*)d_info
->wptr
;
3708 memcpy(fdinfo
->FileName
, d_info
->name
, d_info
->name_len
);
3709 fdinfo
->FileName
[d_info
->name_len
] = 0x00;
3710 fdinfo
->FileNameLength
= cpu_to_le32(d_info
->name_len
);
3711 fdinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
3714 case FILE_NAMES_INFORMATION
:
3716 struct file_names_info
*fninfo
;
3718 fninfo
= (struct file_names_info
*)d_info
->wptr
;
3719 memcpy(fninfo
->FileName
, d_info
->name
, d_info
->name_len
);
3720 fninfo
->FileName
[d_info
->name_len
] = 0x00;
3721 fninfo
->FileNameLength
= cpu_to_le32(d_info
->name_len
);
3722 fninfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
3725 case FILEID_FULL_DIRECTORY_INFORMATION
:
3727 struct file_id_full_dir_info
*dinfo
;
3729 dinfo
= (struct file_id_full_dir_info
*)d_info
->wptr
;
3730 memcpy(dinfo
->FileName
, d_info
->name
, d_info
->name_len
);
3731 dinfo
->FileName
[d_info
->name_len
] = 0x00;
3732 dinfo
->FileNameLength
= cpu_to_le32(d_info
->name_len
);
3733 dinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
3736 case FILEID_BOTH_DIRECTORY_INFORMATION
:
3738 struct file_id_both_directory_info
*fibdinfo
;
3740 fibdinfo
= (struct file_id_both_directory_info
*)d_info
->wptr
;
3741 memcpy(fibdinfo
->FileName
, d_info
->name
, d_info
->name_len
);
3742 fibdinfo
->FileName
[d_info
->name_len
] = 0x00;
3743 fibdinfo
->FileNameLength
= cpu_to_le32(d_info
->name_len
);
3744 fibdinfo
->NextEntryOffset
= cpu_to_le32(next_entry_offset
);
3747 case SMB_FIND_FILE_POSIX_INFO
:
3749 struct smb2_posix_info
*posix_info
;
3751 posix_info
= (struct smb2_posix_info
*)d_info
->wptr
;
3752 memcpy(posix_info
->name
, d_info
->name
, d_info
->name_len
);
3753 posix_info
->name
[d_info
->name_len
] = 0x00;
3754 posix_info
->name_len
= cpu_to_le32(d_info
->name_len
);
3755 posix_info
->NextEntryOffset
=
3756 cpu_to_le32(next_entry_offset
);
3759 } /* switch (info_level) */
3761 d_info
->num_entry
++;
3762 d_info
->out_buf_len
-= next_entry_offset
;
3763 d_info
->wptr
+= next_entry_offset
;
3767 static int __query_dir(struct dir_context
*ctx
, const char *name
, int namlen
,
3768 loff_t offset
, u64 ino
, unsigned int d_type
)
3770 struct ksmbd_readdir_data
*buf
;
3771 struct smb2_query_dir_private
*priv
;
3772 struct ksmbd_dir_info
*d_info
;
3775 buf
= container_of(ctx
, struct ksmbd_readdir_data
, ctx
);
3776 priv
= buf
->private;
3777 d_info
= priv
->d_info
;
3779 /* dot and dotdot entries are already reserved */
3780 if (!strcmp(".", name
) || !strcmp("..", name
))
3782 if (ksmbd_share_veto_filename(priv
->work
->tcon
->share_conf
, name
))
3784 if (!match_pattern(name
, namlen
, priv
->search_pattern
))
3787 d_info
->name
= name
;
3788 d_info
->name_len
= namlen
;
3789 rc
= reserve_populate_dentry(d_info
, priv
->info_level
);
3792 if (d_info
->flags
& SMB2_RETURN_SINGLE_ENTRY
) {
3793 d_info
->out_buf_len
= 0;
3799 static void restart_ctx(struct dir_context
*ctx
)
3804 static int verify_info_level(int info_level
)
3806 switch (info_level
) {
3807 case FILE_FULL_DIRECTORY_INFORMATION
:
3808 case FILE_BOTH_DIRECTORY_INFORMATION
:
3809 case FILE_DIRECTORY_INFORMATION
:
3810 case FILE_NAMES_INFORMATION
:
3811 case FILEID_FULL_DIRECTORY_INFORMATION
:
3812 case FILEID_BOTH_DIRECTORY_INFORMATION
:
3813 case SMB_FIND_FILE_POSIX_INFO
:
3822 static int smb2_calc_max_out_buf_len(struct ksmbd_work
*work
,
3823 unsigned short hdr2_len
,
3824 unsigned int out_buf_len
)
3828 if (out_buf_len
> work
->conn
->vals
->max_trans_size
)
3831 free_len
= (int)(work
->response_sz
-
3832 (get_rfc1002_len(work
->response_buf
) + 4)) -
3837 return min_t(int, out_buf_len
, free_len
);
3840 int smb2_query_dir(struct ksmbd_work
*work
)
3842 struct ksmbd_conn
*conn
= work
->conn
;
3843 struct smb2_query_directory_req
*req
;
3844 struct smb2_query_directory_rsp
*rsp
, *rsp_org
;
3845 struct ksmbd_share_config
*share
= work
->tcon
->share_conf
;
3846 struct ksmbd_file
*dir_fp
= NULL
;
3847 struct ksmbd_dir_info d_info
;
3849 char *srch_ptr
= NULL
;
3850 unsigned char srch_flag
;
3852 struct smb2_query_dir_private query_dir_private
= {NULL
, };
3854 rsp_org
= work
->response_buf
;
3855 WORK_BUFFERS(work
, req
, rsp
);
3857 if (ksmbd_override_fsids(work
)) {
3858 rsp
->hdr
.Status
= STATUS_NO_MEMORY
;
3859 smb2_set_err_rsp(work
);
3863 rc
= verify_info_level(req
->FileInformationClass
);
3869 dir_fp
= ksmbd_lookup_fd_slow(work
,
3870 le64_to_cpu(req
->VolatileFileId
),
3871 le64_to_cpu(req
->PersistentFileId
));
3877 if (!(dir_fp
->daccess
& FILE_LIST_DIRECTORY_LE
) ||
3878 inode_permission(file_mnt_user_ns(dir_fp
->filp
),
3879 file_inode(dir_fp
->filp
),
3880 MAY_READ
| MAY_EXEC
)) {
3881 pr_err("no right to enumerate directory (%pd)\n",
3882 dir_fp
->filp
->f_path
.dentry
);
3887 if (!S_ISDIR(file_inode(dir_fp
->filp
)->i_mode
)) {
3888 pr_err("can't do query dir for a file\n");
3893 srch_flag
= req
->Flags
;
3894 srch_ptr
= smb_strndup_from_utf16(req
->Buffer
,
3895 le16_to_cpu(req
->FileNameLength
), 1,
3897 if (IS_ERR(srch_ptr
)) {
3898 ksmbd_debug(SMB
, "Search Pattern not found\n");
3902 ksmbd_debug(SMB
, "Search pattern is %s\n", srch_ptr
);
3905 ksmbd_debug(SMB
, "Directory name is %s\n", dir_fp
->filename
);
3907 if (srch_flag
& SMB2_REOPEN
|| srch_flag
& SMB2_RESTART_SCANS
) {
3908 ksmbd_debug(SMB
, "Restart directory scan\n");
3909 generic_file_llseek(dir_fp
->filp
, 0, SEEK_SET
);
3910 restart_ctx(&dir_fp
->readdir_data
.ctx
);
3913 memset(&d_info
, 0, sizeof(struct ksmbd_dir_info
));
3914 d_info
.wptr
= (char *)rsp
->Buffer
;
3915 d_info
.rptr
= (char *)rsp
->Buffer
;
3916 d_info
.out_buf_len
=
3917 smb2_calc_max_out_buf_len(work
, 8,
3918 le32_to_cpu(req
->OutputBufferLength
));
3919 if (d_info
.out_buf_len
< 0) {
3923 d_info
.flags
= srch_flag
;
3926 * reserve dot and dotdot entries in head of buffer
3929 rc
= ksmbd_populate_dot_dotdot_entries(work
, req
->FileInformationClass
,
3930 dir_fp
, &d_info
, srch_ptr
,
3931 smb2_populate_readdir_entry
);
3937 if (test_share_config_flag(share
, KSMBD_SHARE_FLAG_HIDE_DOT_FILES
))
3938 d_info
.hide_dot_file
= true;
3940 buffer_sz
= d_info
.out_buf_len
;
3941 d_info
.rptr
= d_info
.wptr
;
3942 query_dir_private
.work
= work
;
3943 query_dir_private
.search_pattern
= srch_ptr
;
3944 query_dir_private
.dir_fp
= dir_fp
;
3945 query_dir_private
.d_info
= &d_info
;
3946 query_dir_private
.info_level
= req
->FileInformationClass
;
3947 dir_fp
->readdir_data
.private = &query_dir_private
;
3948 set_ctx_actor(&dir_fp
->readdir_data
.ctx
, __query_dir
);
3950 rc
= iterate_dir(dir_fp
->filp
, &dir_fp
->readdir_data
.ctx
);
3952 restart_ctx(&dir_fp
->readdir_data
.ctx
);
3958 d_info
.wptr
= d_info
.rptr
;
3959 d_info
.out_buf_len
= buffer_sz
;
3960 rc
= process_query_dir_entries(&query_dir_private
);
3964 if (!d_info
.data_count
&& d_info
.out_buf_len
>= 0) {
3965 if (srch_flag
& SMB2_RETURN_SINGLE_ENTRY
&& !is_asterisk(srch_ptr
)) {
3966 rsp
->hdr
.Status
= STATUS_NO_SUCH_FILE
;
3968 dir_fp
->dot_dotdot
[0] = dir_fp
->dot_dotdot
[1] = 0;
3969 rsp
->hdr
.Status
= STATUS_NO_MORE_FILES
;
3971 rsp
->StructureSize
= cpu_to_le16(9);
3972 rsp
->OutputBufferOffset
= cpu_to_le16(0);
3973 rsp
->OutputBufferLength
= cpu_to_le32(0);
3975 inc_rfc1001_len(rsp_org
, 9);
3977 ((struct file_directory_info
*)
3978 ((char *)rsp
->Buffer
+ d_info
.last_entry_offset
))
3979 ->NextEntryOffset
= 0;
3980 d_info
.data_count
-= d_info
.last_entry_off_align
;
3982 rsp
->StructureSize
= cpu_to_le16(9);
3983 rsp
->OutputBufferOffset
= cpu_to_le16(72);
3984 rsp
->OutputBufferLength
= cpu_to_le32(d_info
.data_count
);
3985 inc_rfc1001_len(rsp_org
, 8 + d_info
.data_count
);
3989 ksmbd_fd_put(work
, dir_fp
);
3990 ksmbd_revert_fsids(work
);
3994 pr_err("error while processing smb2 query dir rc = %d\n", rc
);
3999 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
4000 else if (rc
== -EACCES
)
4001 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
4002 else if (rc
== -ENOENT
)
4003 rsp
->hdr
.Status
= STATUS_NO_SUCH_FILE
;
4004 else if (rc
== -EBADF
)
4005 rsp
->hdr
.Status
= STATUS_FILE_CLOSED
;
4006 else if (rc
== -ENOMEM
)
4007 rsp
->hdr
.Status
= STATUS_NO_MEMORY
;
4008 else if (rc
== -EFAULT
)
4009 rsp
->hdr
.Status
= STATUS_INVALID_INFO_CLASS
;
4010 if (!rsp
->hdr
.Status
)
4011 rsp
->hdr
.Status
= STATUS_UNEXPECTED_IO_ERROR
;
4013 smb2_set_err_rsp(work
);
4014 ksmbd_fd_put(work
, dir_fp
);
4015 ksmbd_revert_fsids(work
);
4020 * buffer_check_err() - helper function to check buffer errors
4021 * @reqOutputBufferLength: max buffer length expected in command response
4022 * @rsp: query info response buffer contains output buffer length
4023 * @infoclass_size: query info class response buffer size
4025 * Return: 0 on success, otherwise error
4027 static int buffer_check_err(int reqOutputBufferLength
,
4028 struct smb2_query_info_rsp
*rsp
, int infoclass_size
)
4030 if (reqOutputBufferLength
< le32_to_cpu(rsp
->OutputBufferLength
)) {
4031 if (reqOutputBufferLength
< infoclass_size
) {
4032 pr_err("Invalid Buffer Size Requested\n");
4033 rsp
->hdr
.Status
= STATUS_INFO_LENGTH_MISMATCH
;
4034 rsp
->hdr
.smb2_buf_length
= cpu_to_be32(sizeof(struct smb2_hdr
) - 4);
4038 ksmbd_debug(SMB
, "Buffer Overflow\n");
4039 rsp
->hdr
.Status
= STATUS_BUFFER_OVERFLOW
;
4040 rsp
->hdr
.smb2_buf_length
= cpu_to_be32(sizeof(struct smb2_hdr
) - 4 +
4041 reqOutputBufferLength
);
4042 rsp
->OutputBufferLength
= cpu_to_le32(reqOutputBufferLength
);
4047 static void get_standard_info_pipe(struct smb2_query_info_rsp
*rsp
)
4049 struct smb2_file_standard_info
*sinfo
;
4051 sinfo
= (struct smb2_file_standard_info
*)rsp
->Buffer
;
4053 sinfo
->AllocationSize
= cpu_to_le64(4096);
4054 sinfo
->EndOfFile
= cpu_to_le64(0);
4055 sinfo
->NumberOfLinks
= cpu_to_le32(1);
4056 sinfo
->DeletePending
= 1;
4057 sinfo
->Directory
= 0;
4058 rsp
->OutputBufferLength
=
4059 cpu_to_le32(sizeof(struct smb2_file_standard_info
));
4060 inc_rfc1001_len(rsp
, sizeof(struct smb2_file_standard_info
));
4063 static void get_internal_info_pipe(struct smb2_query_info_rsp
*rsp
, u64 num
)
4065 struct smb2_file_internal_info
*file_info
;
4067 file_info
= (struct smb2_file_internal_info
*)rsp
->Buffer
;
4069 /* any unique number */
4070 file_info
->IndexNumber
= cpu_to_le64(num
| (1ULL << 63));
4071 rsp
->OutputBufferLength
=
4072 cpu_to_le32(sizeof(struct smb2_file_internal_info
));
4073 inc_rfc1001_len(rsp
, sizeof(struct smb2_file_internal_info
));
4076 static int smb2_get_info_file_pipe(struct ksmbd_session
*sess
,
4077 struct smb2_query_info_req
*req
,
4078 struct smb2_query_info_rsp
*rsp
)
4084 * Windows can sometime send query file info request on
4085 * pipe without opening it, checking error condition here
4087 id
= le64_to_cpu(req
->VolatileFileId
);
4088 if (!ksmbd_session_rpc_method(sess
, id
))
4091 ksmbd_debug(SMB
, "FileInfoClass %u, FileId 0x%llx\n",
4092 req
->FileInfoClass
, le64_to_cpu(req
->VolatileFileId
));
4094 switch (req
->FileInfoClass
) {
4095 case FILE_STANDARD_INFORMATION
:
4096 get_standard_info_pipe(rsp
);
4097 rc
= buffer_check_err(le32_to_cpu(req
->OutputBufferLength
),
4098 rsp
, FILE_STANDARD_INFORMATION_SIZE
);
4100 case FILE_INTERNAL_INFORMATION
:
4101 get_internal_info_pipe(rsp
, id
);
4102 rc
= buffer_check_err(le32_to_cpu(req
->OutputBufferLength
),
4103 rsp
, FILE_INTERNAL_INFORMATION_SIZE
);
4106 ksmbd_debug(SMB
, "smb2_info_file_pipe for %u not supported\n",
4107 req
->FileInfoClass
);
4114 * smb2_get_ea() - handler for smb2 get extended attribute command
4115 * @work: smb work containing query info command buffer
4116 * @fp: ksmbd_file pointer
4117 * @req: get extended attribute request
4118 * @rsp: response buffer pointer
4119 * @rsp_org: base response buffer pointer in case of chained response
4121 * Return: 0 on success, otherwise error
4123 static int smb2_get_ea(struct ksmbd_work
*work
, struct ksmbd_file
*fp
,
4124 struct smb2_query_info_req
*req
,
4125 struct smb2_query_info_rsp
*rsp
, void *rsp_org
)
4127 struct smb2_ea_info
*eainfo
, *prev_eainfo
;
4128 char *name
, *ptr
, *xattr_list
= NULL
, *buf
;
4129 int rc
, name_len
, value_len
, xattr_list_len
, idx
;
4130 ssize_t buf_free_len
, alignment_bytes
, next_offset
, rsp_data_cnt
= 0;
4131 struct smb2_ea_info_req
*ea_req
= NULL
;
4133 struct user_namespace
*user_ns
= file_mnt_user_ns(fp
->filp
);
4135 if (!(fp
->daccess
& FILE_READ_EA_LE
)) {
4136 pr_err("Not permitted to read ext attr : 0x%x\n",
4141 path
= &fp
->filp
->f_path
;
4142 /* single EA entry is requested with given user.* name */
4143 if (req
->InputBufferLength
) {
4144 if (le32_to_cpu(req
->InputBufferLength
) <
4145 sizeof(struct smb2_ea_info_req
))
4148 ea_req
= (struct smb2_ea_info_req
*)req
->Buffer
;
4150 /* need to send all EAs, if no specific EA is requested*/
4151 if (le32_to_cpu(req
->Flags
) & SL_RETURN_SINGLE_ENTRY
)
4153 "All EAs are requested but need to send single EA entry in rsp flags 0x%x\n",
4154 le32_to_cpu(req
->Flags
));
4158 smb2_calc_max_out_buf_len(work
, 8,
4159 le32_to_cpu(req
->OutputBufferLength
));
4160 if (buf_free_len
< 0)
4163 rc
= ksmbd_vfs_listxattr(path
->dentry
, &xattr_list
);
4165 rsp
->hdr
.Status
= STATUS_INVALID_HANDLE
;
4167 } else if (!rc
) { /* there is no EA in the file */
4168 ksmbd_debug(SMB
, "no ea data in the file\n");
4171 xattr_list_len
= rc
;
4173 ptr
= (char *)rsp
->Buffer
;
4174 eainfo
= (struct smb2_ea_info
*)ptr
;
4175 prev_eainfo
= eainfo
;
4178 while (idx
< xattr_list_len
) {
4179 name
= xattr_list
+ idx
;
4180 name_len
= strlen(name
);
4182 ksmbd_debug(SMB
, "%s, len %d\n", name
, name_len
);
4183 idx
+= name_len
+ 1;
4186 * CIFS does not support EA other than user.* namespace,
4187 * still keep the framework generic, to list other attrs
4190 if (strncmp(name
, XATTR_USER_PREFIX
, XATTR_USER_PREFIX_LEN
))
4193 if (!strncmp(&name
[XATTR_USER_PREFIX_LEN
], STREAM_PREFIX
,
4197 if (req
->InputBufferLength
&&
4198 strncmp(&name
[XATTR_USER_PREFIX_LEN
], ea_req
->name
,
4199 ea_req
->EaNameLength
))
4202 if (!strncmp(&name
[XATTR_USER_PREFIX_LEN
],
4203 DOS_ATTRIBUTE_PREFIX
, DOS_ATTRIBUTE_PREFIX_LEN
))
4206 if (!strncmp(name
, XATTR_USER_PREFIX
, XATTR_USER_PREFIX_LEN
))
4207 name_len
-= XATTR_USER_PREFIX_LEN
;
4209 ptr
= (char *)(&eainfo
->name
+ name_len
+ 1);
4210 buf_free_len
-= (offsetof(struct smb2_ea_info
, name
) +
4212 /* bailout if xattr can't fit in buf_free_len */
4213 value_len
= ksmbd_vfs_getxattr(user_ns
, path
->dentry
,
4215 if (value_len
<= 0) {
4217 rsp
->hdr
.Status
= STATUS_INVALID_HANDLE
;
4221 buf_free_len
-= value_len
;
4222 if (buf_free_len
< 0) {
4227 memcpy(ptr
, buf
, value_len
);
4232 eainfo
->EaNameLength
= name_len
;
4234 if (!strncmp(name
, XATTR_USER_PREFIX
, XATTR_USER_PREFIX_LEN
))
4235 memcpy(eainfo
->name
, &name
[XATTR_USER_PREFIX_LEN
],
4238 memcpy(eainfo
->name
, name
, name_len
);
4240 eainfo
->name
[name_len
] = '\0';
4241 eainfo
->EaValueLength
= cpu_to_le16(value_len
);
4242 next_offset
= offsetof(struct smb2_ea_info
, name
) +
4243 name_len
+ 1 + value_len
;
4245 /* align next xattr entry at 4 byte bundary */
4246 alignment_bytes
= ((next_offset
+ 3) & ~3) - next_offset
;
4247 if (alignment_bytes
) {
4248 memset(ptr
, '\0', alignment_bytes
);
4249 ptr
+= alignment_bytes
;
4250 next_offset
+= alignment_bytes
;
4251 buf_free_len
-= alignment_bytes
;
4253 eainfo
->NextEntryOffset
= cpu_to_le32(next_offset
);
4254 prev_eainfo
= eainfo
;
4255 eainfo
= (struct smb2_ea_info
*)ptr
;
4256 rsp_data_cnt
+= next_offset
;
4258 if (req
->InputBufferLength
) {
4259 ksmbd_debug(SMB
, "single entry requested\n");
4264 /* no more ea entries */
4265 prev_eainfo
->NextEntryOffset
= 0;
4268 if (rsp_data_cnt
== 0)
4269 rsp
->hdr
.Status
= STATUS_NO_EAS_ON_FILE
;
4270 rsp
->OutputBufferLength
= cpu_to_le32(rsp_data_cnt
);
4271 inc_rfc1001_len(rsp_org
, rsp_data_cnt
);
4277 static void get_file_access_info(struct smb2_query_info_rsp
*rsp
,
4278 struct ksmbd_file
*fp
, void *rsp_org
)
4280 struct smb2_file_access_info
*file_info
;
4282 file_info
= (struct smb2_file_access_info
*)rsp
->Buffer
;
4283 file_info
->AccessFlags
= fp
->daccess
;
4284 rsp
->OutputBufferLength
=
4285 cpu_to_le32(sizeof(struct smb2_file_access_info
));
4286 inc_rfc1001_len(rsp_org
, sizeof(struct smb2_file_access_info
));
4289 static int get_file_basic_info(struct smb2_query_info_rsp
*rsp
,
4290 struct ksmbd_file
*fp
, void *rsp_org
)
4292 struct smb2_file_basic_info
*basic_info
;
4296 if (!(fp
->daccess
& FILE_READ_ATTRIBUTES_LE
)) {
4297 pr_err("no right to read the attributes : 0x%x\n",
4302 basic_info
= (struct smb2_file_basic_info
*)rsp
->Buffer
;
4303 generic_fillattr(file_mnt_user_ns(fp
->filp
), file_inode(fp
->filp
),
4305 basic_info
->CreationTime
= cpu_to_le64(fp
->create_time
);
4306 time
= ksmbd_UnixTimeToNT(stat
.atime
);
4307 basic_info
->LastAccessTime
= cpu_to_le64(time
);
4308 time
= ksmbd_UnixTimeToNT(stat
.mtime
);
4309 basic_info
->LastWriteTime
= cpu_to_le64(time
);
4310 time
= ksmbd_UnixTimeToNT(stat
.ctime
);
4311 basic_info
->ChangeTime
= cpu_to_le64(time
);
4312 basic_info
->Attributes
= fp
->f_ci
->m_fattr
;
4313 basic_info
->Pad1
= 0;
4314 rsp
->OutputBufferLength
=
4315 cpu_to_le32(sizeof(struct smb2_file_basic_info
));
4316 inc_rfc1001_len(rsp_org
, sizeof(struct smb2_file_basic_info
));
4320 static unsigned long long get_allocation_size(struct inode
*inode
,
4323 unsigned long long alloc_size
= 0;
4325 if (!S_ISDIR(stat
->mode
)) {
4326 if ((inode
->i_blocks
<< 9) <= stat
->size
)
4327 alloc_size
= stat
->size
;
4329 alloc_size
= inode
->i_blocks
<< 9;
4335 static void get_file_standard_info(struct smb2_query_info_rsp
*rsp
,
4336 struct ksmbd_file
*fp
, void *rsp_org
)
4338 struct smb2_file_standard_info
*sinfo
;
4339 unsigned int delete_pending
;
4340 struct inode
*inode
;
4343 inode
= file_inode(fp
->filp
);
4344 generic_fillattr(file_mnt_user_ns(fp
->filp
), inode
, &stat
);
4346 sinfo
= (struct smb2_file_standard_info
*)rsp
->Buffer
;
4347 delete_pending
= ksmbd_inode_pending_delete(fp
);
4349 sinfo
->AllocationSize
= cpu_to_le64(get_allocation_size(inode
, &stat
));
4350 sinfo
->EndOfFile
= S_ISDIR(stat
.mode
) ? 0 : cpu_to_le64(stat
.size
);
4351 sinfo
->NumberOfLinks
= cpu_to_le32(get_nlink(&stat
) - delete_pending
);
4352 sinfo
->DeletePending
= delete_pending
;
4353 sinfo
->Directory
= S_ISDIR(stat
.mode
) ? 1 : 0;
4354 rsp
->OutputBufferLength
=
4355 cpu_to_le32(sizeof(struct smb2_file_standard_info
));
4356 inc_rfc1001_len(rsp_org
,
4357 sizeof(struct smb2_file_standard_info
));
4360 static void get_file_alignment_info(struct smb2_query_info_rsp
*rsp
,
4363 struct smb2_file_alignment_info
*file_info
;
4365 file_info
= (struct smb2_file_alignment_info
*)rsp
->Buffer
;
4366 file_info
->AlignmentRequirement
= 0;
4367 rsp
->OutputBufferLength
=
4368 cpu_to_le32(sizeof(struct smb2_file_alignment_info
));
4369 inc_rfc1001_len(rsp_org
,
4370 sizeof(struct smb2_file_alignment_info
));
4373 static int get_file_all_info(struct ksmbd_work
*work
,
4374 struct smb2_query_info_rsp
*rsp
,
4375 struct ksmbd_file
*fp
,
4378 struct ksmbd_conn
*conn
= work
->conn
;
4379 struct smb2_file_all_info
*file_info
;
4380 unsigned int delete_pending
;
4381 struct inode
*inode
;
4387 if (!(fp
->daccess
& FILE_READ_ATTRIBUTES_LE
)) {
4388 ksmbd_debug(SMB
, "no right to read the attributes : 0x%x\n",
4393 filename
= convert_to_nt_pathname(fp
->filename
);
4397 inode
= file_inode(fp
->filp
);
4398 generic_fillattr(file_mnt_user_ns(fp
->filp
), inode
, &stat
);
4400 ksmbd_debug(SMB
, "filename = %s\n", filename
);
4401 delete_pending
= ksmbd_inode_pending_delete(fp
);
4402 file_info
= (struct smb2_file_all_info
*)rsp
->Buffer
;
4404 file_info
->CreationTime
= cpu_to_le64(fp
->create_time
);
4405 time
= ksmbd_UnixTimeToNT(stat
.atime
);
4406 file_info
->LastAccessTime
= cpu_to_le64(time
);
4407 time
= ksmbd_UnixTimeToNT(stat
.mtime
);
4408 file_info
->LastWriteTime
= cpu_to_le64(time
);
4409 time
= ksmbd_UnixTimeToNT(stat
.ctime
);
4410 file_info
->ChangeTime
= cpu_to_le64(time
);
4411 file_info
->Attributes
= fp
->f_ci
->m_fattr
;
4412 file_info
->Pad1
= 0;
4413 file_info
->AllocationSize
=
4414 cpu_to_le64(get_allocation_size(inode
, &stat
));
4415 file_info
->EndOfFile
= S_ISDIR(stat
.mode
) ? 0 : cpu_to_le64(stat
.size
);
4416 file_info
->NumberOfLinks
=
4417 cpu_to_le32(get_nlink(&stat
) - delete_pending
);
4418 file_info
->DeletePending
= delete_pending
;
4419 file_info
->Directory
= S_ISDIR(stat
.mode
) ? 1 : 0;
4420 file_info
->Pad2
= 0;
4421 file_info
->IndexNumber
= cpu_to_le64(stat
.ino
);
4422 file_info
->EASize
= 0;
4423 file_info
->AccessFlags
= fp
->daccess
;
4424 file_info
->CurrentByteOffset
= cpu_to_le64(fp
->filp
->f_pos
);
4425 file_info
->Mode
= fp
->coption
;
4426 file_info
->AlignmentRequirement
= 0;
4427 conv_len
= smbConvertToUTF16((__le16
*)file_info
->FileName
, filename
,
4428 PATH_MAX
, conn
->local_nls
, 0);
4430 file_info
->FileNameLength
= cpu_to_le32(conv_len
);
4431 rsp
->OutputBufferLength
=
4432 cpu_to_le32(sizeof(struct smb2_file_all_info
) + conv_len
- 1);
4434 inc_rfc1001_len(rsp_org
, le32_to_cpu(rsp
->OutputBufferLength
));
4438 static void get_file_alternate_info(struct ksmbd_work
*work
,
4439 struct smb2_query_info_rsp
*rsp
,
4440 struct ksmbd_file
*fp
,
4443 struct ksmbd_conn
*conn
= work
->conn
;
4444 struct smb2_file_alt_name_info
*file_info
;
4445 struct dentry
*dentry
= fp
->filp
->f_path
.dentry
;
4448 spin_lock(&dentry
->d_lock
);
4449 file_info
= (struct smb2_file_alt_name_info
*)rsp
->Buffer
;
4450 conv_len
= ksmbd_extract_shortname(conn
,
4451 dentry
->d_name
.name
,
4452 file_info
->FileName
);
4453 spin_unlock(&dentry
->d_lock
);
4454 file_info
->FileNameLength
= cpu_to_le32(conv_len
);
4455 rsp
->OutputBufferLength
=
4456 cpu_to_le32(sizeof(struct smb2_file_alt_name_info
) + conv_len
);
4457 inc_rfc1001_len(rsp_org
, le32_to_cpu(rsp
->OutputBufferLength
));
4460 static void get_file_stream_info(struct ksmbd_work
*work
,
4461 struct smb2_query_info_rsp
*rsp
,
4462 struct ksmbd_file
*fp
,
4465 struct ksmbd_conn
*conn
= work
->conn
;
4466 struct smb2_file_stream_info
*file_info
;
4467 char *stream_name
, *xattr_list
= NULL
, *stream_buf
;
4469 struct path
*path
= &fp
->filp
->f_path
;
4470 ssize_t xattr_list_len
;
4471 int nbytes
= 0, streamlen
, stream_name_len
, next
, idx
= 0;
4473 struct smb2_query_info_req
*req
= ksmbd_req_buf_next(work
);
4475 generic_fillattr(file_mnt_user_ns(fp
->filp
), file_inode(fp
->filp
),
4477 file_info
= (struct smb2_file_stream_info
*)rsp
->Buffer
;
4480 smb2_calc_max_out_buf_len(work
, 8,
4481 le32_to_cpu(req
->OutputBufferLength
));
4482 if (buf_free_len
< 0)
4485 xattr_list_len
= ksmbd_vfs_listxattr(path
->dentry
, &xattr_list
);
4486 if (xattr_list_len
< 0) {
4488 } else if (!xattr_list_len
) {
4489 ksmbd_debug(SMB
, "empty xattr in the file\n");
4493 while (idx
< xattr_list_len
) {
4494 stream_name
= xattr_list
+ idx
;
4495 streamlen
= strlen(stream_name
);
4496 idx
+= streamlen
+ 1;
4498 ksmbd_debug(SMB
, "%s, len %d\n", stream_name
, streamlen
);
4500 if (strncmp(&stream_name
[XATTR_USER_PREFIX_LEN
],
4501 STREAM_PREFIX
, STREAM_PREFIX_LEN
))
4504 stream_name_len
= streamlen
- (XATTR_USER_PREFIX_LEN
+
4506 streamlen
= stream_name_len
;
4510 stream_buf
= kmalloc(streamlen
+ 1, GFP_KERNEL
);
4514 streamlen
= snprintf(stream_buf
, streamlen
+ 1,
4515 ":%s", &stream_name
[XATTR_NAME_STREAM_LEN
]);
4517 next
= sizeof(struct smb2_file_stream_info
) + streamlen
* 2;
4518 if (next
> buf_free_len
) {
4523 file_info
= (struct smb2_file_stream_info
*)&rsp
->Buffer
[nbytes
];
4524 streamlen
= smbConvertToUTF16((__le16
*)file_info
->StreamName
,
4525 stream_buf
, streamlen
,
4526 conn
->local_nls
, 0);
4529 file_info
->StreamNameLength
= cpu_to_le32(streamlen
);
4530 file_info
->StreamSize
= cpu_to_le64(stream_name_len
);
4531 file_info
->StreamAllocationSize
= cpu_to_le64(stream_name_len
);
4534 buf_free_len
-= next
;
4535 file_info
->NextEntryOffset
= cpu_to_le32(next
);
4539 if (!S_ISDIR(stat
.mode
) &&
4540 buf_free_len
>= sizeof(struct smb2_file_stream_info
) + 7 * 2) {
4541 file_info
= (struct smb2_file_stream_info
*)
4542 &rsp
->Buffer
[nbytes
];
4543 streamlen
= smbConvertToUTF16((__le16
*)file_info
->StreamName
,
4544 "::$DATA", 7, conn
->local_nls
, 0);
4546 file_info
->StreamNameLength
= cpu_to_le32(streamlen
);
4547 file_info
->StreamSize
= cpu_to_le64(stat
.size
);
4548 file_info
->StreamAllocationSize
= cpu_to_le64(stat
.blocks
<< 9);
4549 nbytes
+= sizeof(struct smb2_file_stream_info
) + streamlen
;
4552 /* last entry offset should be 0 */
4553 file_info
->NextEntryOffset
= 0;
4556 rsp
->OutputBufferLength
= cpu_to_le32(nbytes
);
4557 inc_rfc1001_len(rsp_org
, nbytes
);
4560 static void get_file_internal_info(struct smb2_query_info_rsp
*rsp
,
4561 struct ksmbd_file
*fp
, void *rsp_org
)
4563 struct smb2_file_internal_info
*file_info
;
4566 generic_fillattr(file_mnt_user_ns(fp
->filp
), file_inode(fp
->filp
),
4568 file_info
= (struct smb2_file_internal_info
*)rsp
->Buffer
;
4569 file_info
->IndexNumber
= cpu_to_le64(stat
.ino
);
4570 rsp
->OutputBufferLength
=
4571 cpu_to_le32(sizeof(struct smb2_file_internal_info
));
4572 inc_rfc1001_len(rsp_org
, sizeof(struct smb2_file_internal_info
));
4575 static int get_file_network_open_info(struct smb2_query_info_rsp
*rsp
,
4576 struct ksmbd_file
*fp
, void *rsp_org
)
4578 struct smb2_file_ntwrk_info
*file_info
;
4579 struct inode
*inode
;
4583 if (!(fp
->daccess
& FILE_READ_ATTRIBUTES_LE
)) {
4584 pr_err("no right to read the attributes : 0x%x\n",
4589 file_info
= (struct smb2_file_ntwrk_info
*)rsp
->Buffer
;
4591 inode
= file_inode(fp
->filp
);
4592 generic_fillattr(file_mnt_user_ns(fp
->filp
), inode
, &stat
);
4594 file_info
->CreationTime
= cpu_to_le64(fp
->create_time
);
4595 time
= ksmbd_UnixTimeToNT(stat
.atime
);
4596 file_info
->LastAccessTime
= cpu_to_le64(time
);
4597 time
= ksmbd_UnixTimeToNT(stat
.mtime
);
4598 file_info
->LastWriteTime
= cpu_to_le64(time
);
4599 time
= ksmbd_UnixTimeToNT(stat
.ctime
);
4600 file_info
->ChangeTime
= cpu_to_le64(time
);
4601 file_info
->Attributes
= fp
->f_ci
->m_fattr
;
4602 file_info
->AllocationSize
=
4603 cpu_to_le64(get_allocation_size(inode
, &stat
));
4604 file_info
->EndOfFile
= S_ISDIR(stat
.mode
) ? 0 : cpu_to_le64(stat
.size
);
4605 file_info
->Reserved
= cpu_to_le32(0);
4606 rsp
->OutputBufferLength
=
4607 cpu_to_le32(sizeof(struct smb2_file_ntwrk_info
));
4608 inc_rfc1001_len(rsp_org
, sizeof(struct smb2_file_ntwrk_info
));
4612 static void get_file_ea_info(struct smb2_query_info_rsp
*rsp
, void *rsp_org
)
4614 struct smb2_file_ea_info
*file_info
;
4616 file_info
= (struct smb2_file_ea_info
*)rsp
->Buffer
;
4617 file_info
->EASize
= 0;
4618 rsp
->OutputBufferLength
=
4619 cpu_to_le32(sizeof(struct smb2_file_ea_info
));
4620 inc_rfc1001_len(rsp_org
, sizeof(struct smb2_file_ea_info
));
4623 static void get_file_position_info(struct smb2_query_info_rsp
*rsp
,
4624 struct ksmbd_file
*fp
, void *rsp_org
)
4626 struct smb2_file_pos_info
*file_info
;
4628 file_info
= (struct smb2_file_pos_info
*)rsp
->Buffer
;
4629 file_info
->CurrentByteOffset
= cpu_to_le64(fp
->filp
->f_pos
);
4630 rsp
->OutputBufferLength
=
4631 cpu_to_le32(sizeof(struct smb2_file_pos_info
));
4632 inc_rfc1001_len(rsp_org
, sizeof(struct smb2_file_pos_info
));
4635 static void get_file_mode_info(struct smb2_query_info_rsp
*rsp
,
4636 struct ksmbd_file
*fp
, void *rsp_org
)
4638 struct smb2_file_mode_info
*file_info
;
4640 file_info
= (struct smb2_file_mode_info
*)rsp
->Buffer
;
4641 file_info
->Mode
= fp
->coption
& FILE_MODE_INFO_MASK
;
4642 rsp
->OutputBufferLength
=
4643 cpu_to_le32(sizeof(struct smb2_file_mode_info
));
4644 inc_rfc1001_len(rsp_org
, sizeof(struct smb2_file_mode_info
));
4647 static void get_file_compression_info(struct smb2_query_info_rsp
*rsp
,
4648 struct ksmbd_file
*fp
, void *rsp_org
)
4650 struct smb2_file_comp_info
*file_info
;
4653 generic_fillattr(file_mnt_user_ns(fp
->filp
), file_inode(fp
->filp
),
4656 file_info
= (struct smb2_file_comp_info
*)rsp
->Buffer
;
4657 file_info
->CompressedFileSize
= cpu_to_le64(stat
.blocks
<< 9);
4658 file_info
->CompressionFormat
= COMPRESSION_FORMAT_NONE
;
4659 file_info
->CompressionUnitShift
= 0;
4660 file_info
->ChunkShift
= 0;
4661 file_info
->ClusterShift
= 0;
4662 memset(&file_info
->Reserved
[0], 0, 3);
4664 rsp
->OutputBufferLength
=
4665 cpu_to_le32(sizeof(struct smb2_file_comp_info
));
4666 inc_rfc1001_len(rsp_org
, sizeof(struct smb2_file_comp_info
));
4669 static int get_file_attribute_tag_info(struct smb2_query_info_rsp
*rsp
,
4670 struct ksmbd_file
*fp
, void *rsp_org
)
4672 struct smb2_file_attr_tag_info
*file_info
;
4674 if (!(fp
->daccess
& FILE_READ_ATTRIBUTES_LE
)) {
4675 pr_err("no right to read the attributes : 0x%x\n",
4680 file_info
= (struct smb2_file_attr_tag_info
*)rsp
->Buffer
;
4681 file_info
->FileAttributes
= fp
->f_ci
->m_fattr
;
4682 file_info
->ReparseTag
= 0;
4683 rsp
->OutputBufferLength
=
4684 cpu_to_le32(sizeof(struct smb2_file_attr_tag_info
));
4685 inc_rfc1001_len(rsp_org
, sizeof(struct smb2_file_attr_tag_info
));
4689 static int find_file_posix_info(struct smb2_query_info_rsp
*rsp
,
4690 struct ksmbd_file
*fp
, void *rsp_org
)
4692 struct smb311_posix_qinfo
*file_info
;
4693 struct inode
*inode
= file_inode(fp
->filp
);
4696 file_info
= (struct smb311_posix_qinfo
*)rsp
->Buffer
;
4697 file_info
->CreationTime
= cpu_to_le64(fp
->create_time
);
4698 time
= ksmbd_UnixTimeToNT(inode
->i_atime
);
4699 file_info
->LastAccessTime
= cpu_to_le64(time
);
4700 time
= ksmbd_UnixTimeToNT(inode
->i_mtime
);
4701 file_info
->LastWriteTime
= cpu_to_le64(time
);
4702 time
= ksmbd_UnixTimeToNT(inode
->i_ctime
);
4703 file_info
->ChangeTime
= cpu_to_le64(time
);
4704 file_info
->DosAttributes
= fp
->f_ci
->m_fattr
;
4705 file_info
->Inode
= cpu_to_le64(inode
->i_ino
);
4706 file_info
->EndOfFile
= cpu_to_le64(inode
->i_size
);
4707 file_info
->AllocationSize
= cpu_to_le64(inode
->i_blocks
<< 9);
4708 file_info
->HardLinks
= cpu_to_le32(inode
->i_nlink
);
4709 file_info
->Mode
= cpu_to_le32(inode
->i_mode
);
4710 file_info
->DeviceId
= cpu_to_le32(inode
->i_rdev
);
4711 rsp
->OutputBufferLength
=
4712 cpu_to_le32(sizeof(struct smb311_posix_qinfo
));
4713 inc_rfc1001_len(rsp_org
, sizeof(struct smb311_posix_qinfo
));
4717 static int smb2_get_info_file(struct ksmbd_work
*work
,
4718 struct smb2_query_info_req
*req
,
4719 struct smb2_query_info_rsp
*rsp
, void *rsp_org
)
4721 struct ksmbd_file
*fp
;
4722 int fileinfoclass
= 0;
4724 int file_infoclass_size
;
4725 unsigned int id
= KSMBD_NO_FID
, pid
= KSMBD_NO_FID
;
4727 if (test_share_config_flag(work
->tcon
->share_conf
,
4728 KSMBD_SHARE_FLAG_PIPE
)) {
4729 /* smb2 info file called for pipe */
4730 return smb2_get_info_file_pipe(work
->sess
, req
, rsp
);
4733 if (work
->next_smb2_rcv_hdr_off
) {
4734 if (!has_file_id(le64_to_cpu(req
->VolatileFileId
))) {
4735 ksmbd_debug(SMB
, "Compound request set FID = %llu\n",
4736 work
->compound_fid
);
4737 id
= work
->compound_fid
;
4738 pid
= work
->compound_pfid
;
4742 if (!has_file_id(id
)) {
4743 id
= le64_to_cpu(req
->VolatileFileId
);
4744 pid
= le64_to_cpu(req
->PersistentFileId
);
4747 fp
= ksmbd_lookup_fd_slow(work
, id
, pid
);
4751 fileinfoclass
= req
->FileInfoClass
;
4753 switch (fileinfoclass
) {
4754 case FILE_ACCESS_INFORMATION
:
4755 get_file_access_info(rsp
, fp
, rsp_org
);
4756 file_infoclass_size
= FILE_ACCESS_INFORMATION_SIZE
;
4759 case FILE_BASIC_INFORMATION
:
4760 rc
= get_file_basic_info(rsp
, fp
, rsp_org
);
4761 file_infoclass_size
= FILE_BASIC_INFORMATION_SIZE
;
4764 case FILE_STANDARD_INFORMATION
:
4765 get_file_standard_info(rsp
, fp
, rsp_org
);
4766 file_infoclass_size
= FILE_STANDARD_INFORMATION_SIZE
;
4769 case FILE_ALIGNMENT_INFORMATION
:
4770 get_file_alignment_info(rsp
, rsp_org
);
4771 file_infoclass_size
= FILE_ALIGNMENT_INFORMATION_SIZE
;
4774 case FILE_ALL_INFORMATION
:
4775 rc
= get_file_all_info(work
, rsp
, fp
, rsp_org
);
4776 file_infoclass_size
= FILE_ALL_INFORMATION_SIZE
;
4779 case FILE_ALTERNATE_NAME_INFORMATION
:
4780 get_file_alternate_info(work
, rsp
, fp
, rsp_org
);
4781 file_infoclass_size
= FILE_ALTERNATE_NAME_INFORMATION_SIZE
;
4784 case FILE_STREAM_INFORMATION
:
4785 get_file_stream_info(work
, rsp
, fp
, rsp_org
);
4786 file_infoclass_size
= FILE_STREAM_INFORMATION_SIZE
;
4789 case FILE_INTERNAL_INFORMATION
:
4790 get_file_internal_info(rsp
, fp
, rsp_org
);
4791 file_infoclass_size
= FILE_INTERNAL_INFORMATION_SIZE
;
4794 case FILE_NETWORK_OPEN_INFORMATION
:
4795 rc
= get_file_network_open_info(rsp
, fp
, rsp_org
);
4796 file_infoclass_size
= FILE_NETWORK_OPEN_INFORMATION_SIZE
;
4799 case FILE_EA_INFORMATION
:
4800 get_file_ea_info(rsp
, rsp_org
);
4801 file_infoclass_size
= FILE_EA_INFORMATION_SIZE
;
4804 case FILE_FULL_EA_INFORMATION
:
4805 rc
= smb2_get_ea(work
, fp
, req
, rsp
, rsp_org
);
4806 file_infoclass_size
= FILE_FULL_EA_INFORMATION_SIZE
;
4809 case FILE_POSITION_INFORMATION
:
4810 get_file_position_info(rsp
, fp
, rsp_org
);
4811 file_infoclass_size
= FILE_POSITION_INFORMATION_SIZE
;
4814 case FILE_MODE_INFORMATION
:
4815 get_file_mode_info(rsp
, fp
, rsp_org
);
4816 file_infoclass_size
= FILE_MODE_INFORMATION_SIZE
;
4819 case FILE_COMPRESSION_INFORMATION
:
4820 get_file_compression_info(rsp
, fp
, rsp_org
);
4821 file_infoclass_size
= FILE_COMPRESSION_INFORMATION_SIZE
;
4824 case FILE_ATTRIBUTE_TAG_INFORMATION
:
4825 rc
= get_file_attribute_tag_info(rsp
, fp
, rsp_org
);
4826 file_infoclass_size
= FILE_ATTRIBUTE_TAG_INFORMATION_SIZE
;
4828 case SMB_FIND_FILE_POSIX_INFO
:
4829 if (!work
->tcon
->posix_extensions
) {
4830 pr_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n");
4833 rc
= find_file_posix_info(rsp
, fp
, rsp_org
);
4834 file_infoclass_size
= sizeof(struct smb311_posix_qinfo
);
4838 ksmbd_debug(SMB
, "fileinfoclass %d not supported yet\n",
4843 rc
= buffer_check_err(le32_to_cpu(req
->OutputBufferLength
),
4845 file_infoclass_size
);
4846 ksmbd_fd_put(work
, fp
);
4850 static int smb2_get_info_filesystem(struct ksmbd_work
*work
,
4851 struct smb2_query_info_req
*req
,
4852 struct smb2_query_info_rsp
*rsp
, void *rsp_org
)
4854 struct ksmbd_session
*sess
= work
->sess
;
4855 struct ksmbd_conn
*conn
= sess
->conn
;
4856 struct ksmbd_share_config
*share
= work
->tcon
->share_conf
;
4857 int fsinfoclass
= 0;
4858 struct kstatfs stfs
;
4861 int fs_infoclass_size
= 0;
4863 rc
= kern_path(share
->path
, LOOKUP_NO_SYMLINKS
, &path
);
4865 pr_err("cannot create vfs path\n");
4869 rc
= vfs_statfs(&path
, &stfs
);
4871 pr_err("cannot do stat of path %s\n", share
->path
);
4876 fsinfoclass
= req
->FileInfoClass
;
4878 switch (fsinfoclass
) {
4879 case FS_DEVICE_INFORMATION
:
4881 struct filesystem_device_info
*info
;
4883 info
= (struct filesystem_device_info
*)rsp
->Buffer
;
4885 info
->DeviceType
= cpu_to_le32(stfs
.f_type
);
4886 info
->DeviceCharacteristics
= cpu_to_le32(0x00000020);
4887 rsp
->OutputBufferLength
= cpu_to_le32(8);
4888 inc_rfc1001_len(rsp_org
, 8);
4889 fs_infoclass_size
= FS_DEVICE_INFORMATION_SIZE
;
4892 case FS_ATTRIBUTE_INFORMATION
:
4894 struct filesystem_attribute_info
*info
;
4897 info
= (struct filesystem_attribute_info
*)rsp
->Buffer
;
4898 info
->Attributes
= cpu_to_le32(FILE_SUPPORTS_OBJECT_IDS
|
4899 FILE_PERSISTENT_ACLS
|
4900 FILE_UNICODE_ON_DISK
|
4901 FILE_CASE_PRESERVED_NAMES
|
4902 FILE_CASE_SENSITIVE_SEARCH
|
4903 FILE_SUPPORTS_BLOCK_REFCOUNTING
);
4905 info
->Attributes
|= cpu_to_le32(server_conf
.share_fake_fscaps
);
4907 info
->MaxPathNameComponentLength
= cpu_to_le32(stfs
.f_namelen
);
4908 len
= smbConvertToUTF16((__le16
*)info
->FileSystemName
,
4909 "NTFS", PATH_MAX
, conn
->local_nls
, 0);
4911 info
->FileSystemNameLen
= cpu_to_le32(len
);
4912 sz
= sizeof(struct filesystem_attribute_info
) - 2 + len
;
4913 rsp
->OutputBufferLength
= cpu_to_le32(sz
);
4914 inc_rfc1001_len(rsp_org
, sz
);
4915 fs_infoclass_size
= FS_ATTRIBUTE_INFORMATION_SIZE
;
4918 case FS_VOLUME_INFORMATION
:
4920 struct filesystem_vol_info
*info
;
4922 unsigned int serial_crc
= 0;
4924 info
= (struct filesystem_vol_info
*)(rsp
->Buffer
);
4925 info
->VolumeCreationTime
= 0;
4926 serial_crc
= crc32_le(serial_crc
, share
->name
,
4927 strlen(share
->name
));
4928 serial_crc
= crc32_le(serial_crc
, share
->path
,
4929 strlen(share
->path
));
4930 serial_crc
= crc32_le(serial_crc
, ksmbd_netbios_name(),
4931 strlen(ksmbd_netbios_name()));
4932 /* Taking dummy value of serial number*/
4933 info
->SerialNumber
= cpu_to_le32(serial_crc
);
4934 len
= smbConvertToUTF16((__le16
*)info
->VolumeLabel
,
4935 share
->name
, PATH_MAX
,
4936 conn
->local_nls
, 0);
4938 info
->VolumeLabelSize
= cpu_to_le32(len
);
4940 sz
= sizeof(struct filesystem_vol_info
) - 2 + len
;
4941 rsp
->OutputBufferLength
= cpu_to_le32(sz
);
4942 inc_rfc1001_len(rsp_org
, sz
);
4943 fs_infoclass_size
= FS_VOLUME_INFORMATION_SIZE
;
4946 case FS_SIZE_INFORMATION
:
4948 struct filesystem_info
*info
;
4950 info
= (struct filesystem_info
*)(rsp
->Buffer
);
4951 info
->TotalAllocationUnits
= cpu_to_le64(stfs
.f_blocks
);
4952 info
->FreeAllocationUnits
= cpu_to_le64(stfs
.f_bfree
);
4953 info
->SectorsPerAllocationUnit
= cpu_to_le32(1);
4954 info
->BytesPerSector
= cpu_to_le32(stfs
.f_bsize
);
4955 rsp
->OutputBufferLength
= cpu_to_le32(24);
4956 inc_rfc1001_len(rsp_org
, 24);
4957 fs_infoclass_size
= FS_SIZE_INFORMATION_SIZE
;
4960 case FS_FULL_SIZE_INFORMATION
:
4962 struct smb2_fs_full_size_info
*info
;
4964 info
= (struct smb2_fs_full_size_info
*)(rsp
->Buffer
);
4965 info
->TotalAllocationUnits
= cpu_to_le64(stfs
.f_blocks
);
4966 info
->CallerAvailableAllocationUnits
=
4967 cpu_to_le64(stfs
.f_bavail
);
4968 info
->ActualAvailableAllocationUnits
=
4969 cpu_to_le64(stfs
.f_bfree
);
4970 info
->SectorsPerAllocationUnit
= cpu_to_le32(1);
4971 info
->BytesPerSector
= cpu_to_le32(stfs
.f_bsize
);
4972 rsp
->OutputBufferLength
= cpu_to_le32(32);
4973 inc_rfc1001_len(rsp_org
, 32);
4974 fs_infoclass_size
= FS_FULL_SIZE_INFORMATION_SIZE
;
4977 case FS_OBJECT_ID_INFORMATION
:
4979 struct object_id_info
*info
;
4981 info
= (struct object_id_info
*)(rsp
->Buffer
);
4983 if (!user_guest(sess
->user
))
4984 memcpy(info
->objid
, user_passkey(sess
->user
), 16);
4986 memset(info
->objid
, 0, 16);
4988 info
->extended_info
.magic
= cpu_to_le32(EXTENDED_INFO_MAGIC
);
4989 info
->extended_info
.version
= cpu_to_le32(1);
4990 info
->extended_info
.release
= cpu_to_le32(1);
4991 info
->extended_info
.rel_date
= 0;
4992 memcpy(info
->extended_info
.version_string
, "1.1.0", strlen("1.1.0"));
4993 rsp
->OutputBufferLength
= cpu_to_le32(64);
4994 inc_rfc1001_len(rsp_org
, 64);
4995 fs_infoclass_size
= FS_OBJECT_ID_INFORMATION_SIZE
;
4998 case FS_SECTOR_SIZE_INFORMATION
:
5000 struct smb3_fs_ss_info
*info
;
5001 unsigned int sector_size
=
5002 min_t(unsigned int, path
.mnt
->mnt_sb
->s_blocksize
, 4096);
5004 info
= (struct smb3_fs_ss_info
*)(rsp
->Buffer
);
5006 info
->LogicalBytesPerSector
= cpu_to_le32(sector_size
);
5007 info
->PhysicalBytesPerSectorForAtomicity
=
5008 cpu_to_le32(sector_size
);
5009 info
->PhysicalBytesPerSectorForPerf
= cpu_to_le32(sector_size
);
5010 info
->FSEffPhysicalBytesPerSectorForAtomicity
=
5011 cpu_to_le32(sector_size
);
5012 info
->Flags
= cpu_to_le32(SSINFO_FLAGS_ALIGNED_DEVICE
|
5013 SSINFO_FLAGS_PARTITION_ALIGNED_ON_DEVICE
);
5014 info
->ByteOffsetForSectorAlignment
= 0;
5015 info
->ByteOffsetForPartitionAlignment
= 0;
5016 rsp
->OutputBufferLength
= cpu_to_le32(28);
5017 inc_rfc1001_len(rsp_org
, 28);
5018 fs_infoclass_size
= FS_SECTOR_SIZE_INFORMATION_SIZE
;
5021 case FS_CONTROL_INFORMATION
:
5024 * TODO : The current implementation is based on
5025 * test result with win7(NTFS) server. It's need to
5026 * modify this to get valid Quota values
5029 struct smb2_fs_control_info
*info
;
5031 info
= (struct smb2_fs_control_info
*)(rsp
->Buffer
);
5032 info
->FreeSpaceStartFiltering
= 0;
5033 info
->FreeSpaceThreshold
= 0;
5034 info
->FreeSpaceStopFiltering
= 0;
5035 info
->DefaultQuotaThreshold
= cpu_to_le64(SMB2_NO_FID
);
5036 info
->DefaultQuotaLimit
= cpu_to_le64(SMB2_NO_FID
);
5038 rsp
->OutputBufferLength
= cpu_to_le32(48);
5039 inc_rfc1001_len(rsp_org
, 48);
5040 fs_infoclass_size
= FS_CONTROL_INFORMATION_SIZE
;
5043 case FS_POSIX_INFORMATION
:
5045 struct filesystem_posix_info
*info
;
5047 if (!work
->tcon
->posix_extensions
) {
5048 pr_err("client doesn't negotiate with SMB3.1.1 POSIX Extensions\n");
5051 info
= (struct filesystem_posix_info
*)(rsp
->Buffer
);
5052 info
->OptimalTransferSize
= cpu_to_le32(stfs
.f_bsize
);
5053 info
->BlockSize
= cpu_to_le32(stfs
.f_bsize
);
5054 info
->TotalBlocks
= cpu_to_le64(stfs
.f_blocks
);
5055 info
->BlocksAvail
= cpu_to_le64(stfs
.f_bfree
);
5056 info
->UserBlocksAvail
= cpu_to_le64(stfs
.f_bavail
);
5057 info
->TotalFileNodes
= cpu_to_le64(stfs
.f_files
);
5058 info
->FreeFileNodes
= cpu_to_le64(stfs
.f_ffree
);
5059 rsp
->OutputBufferLength
= cpu_to_le32(56);
5060 inc_rfc1001_len(rsp_org
, 56);
5061 fs_infoclass_size
= FS_POSIX_INFORMATION_SIZE
;
5069 rc
= buffer_check_err(le32_to_cpu(req
->OutputBufferLength
),
5076 static int smb2_get_info_sec(struct ksmbd_work
*work
,
5077 struct smb2_query_info_req
*req
,
5078 struct smb2_query_info_rsp
*rsp
, void *rsp_org
)
5080 struct ksmbd_file
*fp
;
5081 struct user_namespace
*user_ns
;
5082 struct smb_ntsd
*pntsd
= (struct smb_ntsd
*)rsp
->Buffer
, *ppntsd
= NULL
;
5083 struct smb_fattr fattr
= {{0}};
5084 struct inode
*inode
;
5086 unsigned int id
= KSMBD_NO_FID
, pid
= KSMBD_NO_FID
;
5087 int addition_info
= le32_to_cpu(req
->AdditionalInformation
);
5090 if (addition_info
& ~(OWNER_SECINFO
| GROUP_SECINFO
| DACL_SECINFO
|
5091 PROTECTED_DACL_SECINFO
|
5092 UNPROTECTED_DACL_SECINFO
)) {
5093 ksmbd_debug(SMB
, "Unsupported addition info: 0x%x)\n",
5096 pntsd
->revision
= cpu_to_le16(1);
5097 pntsd
->type
= cpu_to_le16(SELF_RELATIVE
| DACL_PROTECTED
);
5098 pntsd
->osidoffset
= 0;
5099 pntsd
->gsidoffset
= 0;
5100 pntsd
->sacloffset
= 0;
5101 pntsd
->dacloffset
= 0;
5103 secdesclen
= sizeof(struct smb_ntsd
);
5104 rsp
->OutputBufferLength
= cpu_to_le32(secdesclen
);
5105 inc_rfc1001_len(rsp_org
, secdesclen
);
5110 if (work
->next_smb2_rcv_hdr_off
) {
5111 if (!has_file_id(le64_to_cpu(req
->VolatileFileId
))) {
5112 ksmbd_debug(SMB
, "Compound request set FID = %llu\n",
5113 work
->compound_fid
);
5114 id
= work
->compound_fid
;
5115 pid
= work
->compound_pfid
;
5119 if (!has_file_id(id
)) {
5120 id
= le64_to_cpu(req
->VolatileFileId
);
5121 pid
= le64_to_cpu(req
->PersistentFileId
);
5124 fp
= ksmbd_lookup_fd_slow(work
, id
, pid
);
5128 user_ns
= file_mnt_user_ns(fp
->filp
);
5129 inode
= file_inode(fp
->filp
);
5130 ksmbd_acls_fattr(&fattr
, user_ns
, inode
);
5132 if (test_share_config_flag(work
->tcon
->share_conf
,
5133 KSMBD_SHARE_FLAG_ACL_XATTR
))
5134 ksmbd_vfs_get_sd_xattr(work
->conn
, user_ns
,
5135 fp
->filp
->f_path
.dentry
, &ppntsd
);
5137 rc
= build_sec_desc(user_ns
, pntsd
, ppntsd
, addition_info
,
5138 &secdesclen
, &fattr
);
5139 posix_acl_release(fattr
.cf_acls
);
5140 posix_acl_release(fattr
.cf_dacls
);
5142 ksmbd_fd_put(work
, fp
);
5146 rsp
->OutputBufferLength
= cpu_to_le32(secdesclen
);
5147 inc_rfc1001_len(rsp_org
, secdesclen
);
5152 * smb2_query_info() - handler for smb2 query info command
5153 * @work: smb work containing query info request buffer
5155 * Return: 0 on success, otherwise error
5157 int smb2_query_info(struct ksmbd_work
*work
)
5159 struct smb2_query_info_req
*req
;
5160 struct smb2_query_info_rsp
*rsp
, *rsp_org
;
5163 rsp_org
= work
->response_buf
;
5164 WORK_BUFFERS(work
, req
, rsp
);
5166 ksmbd_debug(SMB
, "GOT query info request\n");
5168 switch (req
->InfoType
) {
5169 case SMB2_O_INFO_FILE
:
5170 ksmbd_debug(SMB
, "GOT SMB2_O_INFO_FILE\n");
5171 rc
= smb2_get_info_file(work
, req
, rsp
, (void *)rsp_org
);
5173 case SMB2_O_INFO_FILESYSTEM
:
5174 ksmbd_debug(SMB
, "GOT SMB2_O_INFO_FILESYSTEM\n");
5175 rc
= smb2_get_info_filesystem(work
, req
, rsp
, (void *)rsp_org
);
5177 case SMB2_O_INFO_SECURITY
:
5178 ksmbd_debug(SMB
, "GOT SMB2_O_INFO_SECURITY\n");
5179 rc
= smb2_get_info_sec(work
, req
, rsp
, (void *)rsp_org
);
5182 ksmbd_debug(SMB
, "InfoType %d not supported yet\n",
5189 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
5190 else if (rc
== -ENOENT
)
5191 rsp
->hdr
.Status
= STATUS_FILE_CLOSED
;
5192 else if (rc
== -EIO
)
5193 rsp
->hdr
.Status
= STATUS_UNEXPECTED_IO_ERROR
;
5194 else if (rc
== -EOPNOTSUPP
|| rsp
->hdr
.Status
== 0)
5195 rsp
->hdr
.Status
= STATUS_INVALID_INFO_CLASS
;
5196 smb2_set_err_rsp(work
);
5198 ksmbd_debug(SMB
, "error while processing smb2 query rc = %d\n",
5202 rsp
->StructureSize
= cpu_to_le16(9);
5203 rsp
->OutputBufferOffset
= cpu_to_le16(72);
5204 inc_rfc1001_len(rsp_org
, 8);
5209 * smb2_close_pipe() - handler for closing IPC pipe
5210 * @work: smb work containing close request buffer
5214 static noinline
int smb2_close_pipe(struct ksmbd_work
*work
)
5217 struct smb2_close_req
*req
= work
->request_buf
;
5218 struct smb2_close_rsp
*rsp
= work
->response_buf
;
5220 id
= le64_to_cpu(req
->VolatileFileId
);
5221 ksmbd_session_rpc_close(work
->sess
, id
);
5223 rsp
->StructureSize
= cpu_to_le16(60);
5226 rsp
->CreationTime
= 0;
5227 rsp
->LastAccessTime
= 0;
5228 rsp
->LastWriteTime
= 0;
5229 rsp
->ChangeTime
= 0;
5230 rsp
->AllocationSize
= 0;
5232 rsp
->Attributes
= 0;
5233 inc_rfc1001_len(rsp
, 60);
5238 * smb2_close() - handler for smb2 close file command
5239 * @work: smb work containing close request buffer
5243 int smb2_close(struct ksmbd_work
*work
)
5245 u64 volatile_id
= KSMBD_NO_FID
;
5247 struct smb2_close_req
*req
;
5248 struct smb2_close_rsp
*rsp
;
5249 struct smb2_close_rsp
*rsp_org
;
5250 struct ksmbd_conn
*conn
= work
->conn
;
5251 struct ksmbd_file
*fp
;
5252 struct inode
*inode
;
5256 rsp_org
= work
->response_buf
;
5257 WORK_BUFFERS(work
, req
, rsp
);
5259 if (test_share_config_flag(work
->tcon
->share_conf
,
5260 KSMBD_SHARE_FLAG_PIPE
)) {
5261 ksmbd_debug(SMB
, "IPC pipe close request\n");
5262 return smb2_close_pipe(work
);
5265 sess_id
= le64_to_cpu(req
->hdr
.SessionId
);
5266 if (req
->hdr
.Flags
& SMB2_FLAGS_RELATED_OPERATIONS
)
5267 sess_id
= work
->compound_sid
;
5269 work
->compound_sid
= 0;
5270 if (check_session_id(conn
, sess_id
)) {
5271 work
->compound_sid
= sess_id
;
5273 rsp
->hdr
.Status
= STATUS_USER_SESSION_DELETED
;
5274 if (req
->hdr
.Flags
& SMB2_FLAGS_RELATED_OPERATIONS
)
5275 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
5280 if (work
->next_smb2_rcv_hdr_off
&&
5281 !has_file_id(le64_to_cpu(req
->VolatileFileId
))) {
5282 if (!has_file_id(work
->compound_fid
)) {
5283 /* file already closed, return FILE_CLOSED */
5284 ksmbd_debug(SMB
, "file already closed\n");
5285 rsp
->hdr
.Status
= STATUS_FILE_CLOSED
;
5290 "Compound request set FID = %llu:%llu\n",
5292 work
->compound_pfid
);
5293 volatile_id
= work
->compound_fid
;
5295 /* file closed, stored id is not valid anymore */
5296 work
->compound_fid
= KSMBD_NO_FID
;
5297 work
->compound_pfid
= KSMBD_NO_FID
;
5300 volatile_id
= le64_to_cpu(req
->VolatileFileId
);
5302 ksmbd_debug(SMB
, "volatile_id = %llu\n", volatile_id
);
5304 rsp
->StructureSize
= cpu_to_le16(60);
5307 if (req
->Flags
== SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB
) {
5308 fp
= ksmbd_lookup_fd_fast(work
, volatile_id
);
5314 inode
= file_inode(fp
->filp
);
5315 rsp
->Flags
= SMB2_CLOSE_FLAG_POSTQUERY_ATTRIB
;
5316 rsp
->AllocationSize
= S_ISDIR(inode
->i_mode
) ? 0 :
5317 cpu_to_le64(inode
->i_blocks
<< 9);
5318 rsp
->EndOfFile
= cpu_to_le64(inode
->i_size
);
5319 rsp
->Attributes
= fp
->f_ci
->m_fattr
;
5320 rsp
->CreationTime
= cpu_to_le64(fp
->create_time
);
5321 time
= ksmbd_UnixTimeToNT(inode
->i_atime
);
5322 rsp
->LastAccessTime
= cpu_to_le64(time
);
5323 time
= ksmbd_UnixTimeToNT(inode
->i_mtime
);
5324 rsp
->LastWriteTime
= cpu_to_le64(time
);
5325 time
= ksmbd_UnixTimeToNT(inode
->i_ctime
);
5326 rsp
->ChangeTime
= cpu_to_le64(time
);
5327 ksmbd_fd_put(work
, fp
);
5330 rsp
->AllocationSize
= 0;
5332 rsp
->Attributes
= 0;
5333 rsp
->CreationTime
= 0;
5334 rsp
->LastAccessTime
= 0;
5335 rsp
->LastWriteTime
= 0;
5336 rsp
->ChangeTime
= 0;
5339 err
= ksmbd_close_fd(work
, volatile_id
);
5342 if (rsp
->hdr
.Status
== 0)
5343 rsp
->hdr
.Status
= STATUS_FILE_CLOSED
;
5344 smb2_set_err_rsp(work
);
5346 inc_rfc1001_len(rsp_org
, 60);
5353 * smb2_echo() - handler for smb2 echo(ping) command
5354 * @work: smb work containing echo request buffer
5358 int smb2_echo(struct ksmbd_work
*work
)
5360 struct smb2_echo_rsp
*rsp
= work
->response_buf
;
5362 rsp
->StructureSize
= cpu_to_le16(4);
5364 inc_rfc1001_len(rsp
, 4);
5368 static int smb2_rename(struct ksmbd_work
*work
,
5369 struct ksmbd_file
*fp
,
5370 struct user_namespace
*user_ns
,
5371 struct smb2_file_rename_info
*file_info
,
5372 struct nls_table
*local_nls
)
5374 struct ksmbd_share_config
*share
= fp
->tcon
->share_conf
;
5375 char *new_name
= NULL
, *abs_oldname
= NULL
, *old_name
= NULL
;
5376 char *pathname
= NULL
;
5378 bool file_present
= true;
5381 ksmbd_debug(SMB
, "setting FILE_RENAME_INFO\n");
5382 pathname
= kmalloc(PATH_MAX
, GFP_KERNEL
);
5386 abs_oldname
= d_path(&fp
->filp
->f_path
, pathname
, PATH_MAX
);
5387 if (IS_ERR(abs_oldname
)) {
5391 old_name
= strrchr(abs_oldname
, '/');
5392 if (old_name
&& old_name
[1] != '\0') {
5395 ksmbd_debug(SMB
, "can't get last component in path %s\n",
5401 new_name
= smb2_get_name(share
,
5402 file_info
->FileName
,
5403 le32_to_cpu(file_info
->FileNameLength
),
5405 if (IS_ERR(new_name
)) {
5406 rc
= PTR_ERR(new_name
);
5410 if (strchr(new_name
, ':')) {
5412 char *xattr_stream_name
, *stream_name
= NULL
;
5413 size_t xattr_stream_size
;
5416 rc
= parse_stream_name(new_name
, &stream_name
, &s_type
);
5420 len
= strlen(new_name
);
5421 if (len
> 0 && new_name
[len
- 1] != '/') {
5422 pr_err("not allow base filename in rename\n");
5427 rc
= ksmbd_vfs_xattr_stream_name(stream_name
,
5434 rc
= ksmbd_vfs_setxattr(user_ns
,
5435 fp
->filp
->f_path
.dentry
,
5439 pr_err("failed to store stream name in xattr: %d\n",
5448 ksmbd_debug(SMB
, "new name %s\n", new_name
);
5449 rc
= ksmbd_vfs_kern_path(work
, new_name
, LOOKUP_NO_SYMLINKS
, &path
, 1);
5453 file_present
= false;
5458 if (ksmbd_share_veto_filename(share
, new_name
)) {
5460 ksmbd_debug(SMB
, "Can't rename vetoed file: %s\n", new_name
);
5464 if (file_info
->ReplaceIfExists
) {
5466 rc
= ksmbd_vfs_remove_file(work
, new_name
);
5468 if (rc
!= -ENOTEMPTY
)
5470 ksmbd_debug(SMB
, "cannot delete %s, rc %d\n",
5477 strncmp(old_name
, path
.dentry
->d_name
.name
, strlen(old_name
))) {
5480 "cannot rename already existing file\n");
5485 rc
= ksmbd_vfs_fp_rename(work
, fp
, new_name
);
5488 if (!IS_ERR(new_name
))
5493 static int smb2_create_link(struct ksmbd_work
*work
,
5494 struct ksmbd_share_config
*share
,
5495 struct smb2_file_link_info
*file_info
,
5496 unsigned int buf_len
, struct file
*filp
,
5497 struct nls_table
*local_nls
)
5499 char *link_name
= NULL
, *target_name
= NULL
, *pathname
= NULL
;
5501 bool file_present
= true;
5504 if (buf_len
< (u64
)sizeof(struct smb2_file_link_info
) +
5505 le32_to_cpu(file_info
->FileNameLength
))
5508 ksmbd_debug(SMB
, "setting FILE_LINK_INFORMATION\n");
5509 pathname
= kmalloc(PATH_MAX
, GFP_KERNEL
);
5513 link_name
= smb2_get_name(share
,
5514 file_info
->FileName
,
5515 le32_to_cpu(file_info
->FileNameLength
),
5517 if (IS_ERR(link_name
) || S_ISDIR(file_inode(filp
)->i_mode
)) {
5522 ksmbd_debug(SMB
, "link name is %s\n", link_name
);
5523 target_name
= d_path(&filp
->f_path
, pathname
, PATH_MAX
);
5524 if (IS_ERR(target_name
)) {
5529 ksmbd_debug(SMB
, "target name is %s\n", target_name
);
5530 rc
= ksmbd_vfs_kern_path(work
, link_name
, LOOKUP_NO_SYMLINKS
, &path
, 0);
5534 file_present
= false;
5539 if (file_info
->ReplaceIfExists
) {
5541 rc
= ksmbd_vfs_remove_file(work
, link_name
);
5544 ksmbd_debug(SMB
, "cannot delete %s\n",
5552 ksmbd_debug(SMB
, "link already exists\n");
5557 rc
= ksmbd_vfs_link(work
, target_name
, link_name
);
5561 if (!IS_ERR(link_name
))
5567 static int set_file_basic_info(struct ksmbd_file
*fp
,
5568 struct smb2_file_basic_info
*file_info
,
5569 struct ksmbd_share_config
*share
)
5573 struct inode
*inode
;
5574 struct user_namespace
*user_ns
;
5577 if (!(fp
->daccess
& FILE_WRITE_ATTRIBUTES_LE
))
5582 inode
= file_inode(filp
);
5583 user_ns
= file_mnt_user_ns(filp
);
5585 if (file_info
->CreationTime
)
5586 fp
->create_time
= le64_to_cpu(file_info
->CreationTime
);
5588 if (file_info
->LastAccessTime
) {
5589 attrs
.ia_atime
= ksmbd_NTtimeToUnix(file_info
->LastAccessTime
);
5590 attrs
.ia_valid
|= (ATTR_ATIME
| ATTR_ATIME_SET
);
5593 attrs
.ia_valid
|= ATTR_CTIME
;
5594 if (file_info
->ChangeTime
)
5595 attrs
.ia_ctime
= ksmbd_NTtimeToUnix(file_info
->ChangeTime
);
5597 attrs
.ia_ctime
= inode
->i_ctime
;
5599 if (file_info
->LastWriteTime
) {
5600 attrs
.ia_mtime
= ksmbd_NTtimeToUnix(file_info
->LastWriteTime
);
5601 attrs
.ia_valid
|= (ATTR_MTIME
| ATTR_MTIME_SET
);
5604 if (file_info
->Attributes
) {
5605 if (!S_ISDIR(inode
->i_mode
) &&
5606 file_info
->Attributes
& ATTR_DIRECTORY_LE
) {
5607 pr_err("can't change a file to a directory\n");
5611 if (!(S_ISDIR(inode
->i_mode
) && file_info
->Attributes
== ATTR_NORMAL_LE
))
5612 fp
->f_ci
->m_fattr
= file_info
->Attributes
|
5613 (fp
->f_ci
->m_fattr
& ATTR_DIRECTORY_LE
);
5616 if (test_share_config_flag(share
, KSMBD_SHARE_FLAG_STORE_DOS_ATTRS
) &&
5617 (file_info
->CreationTime
|| file_info
->Attributes
)) {
5618 struct xattr_dos_attrib da
= {0};
5621 da
.itime
= fp
->itime
;
5622 da
.create_time
= fp
->create_time
;
5623 da
.attr
= le32_to_cpu(fp
->f_ci
->m_fattr
);
5624 da
.flags
= XATTR_DOSINFO_ATTRIB
| XATTR_DOSINFO_CREATE_TIME
|
5625 XATTR_DOSINFO_ITIME
;
5627 rc
= ksmbd_vfs_set_dos_attrib_xattr(user_ns
,
5628 filp
->f_path
.dentry
, &da
);
5631 "failed to restore file attribute in EA\n");
5635 if (attrs
.ia_valid
) {
5636 struct dentry
*dentry
= filp
->f_path
.dentry
;
5637 struct inode
*inode
= d_inode(dentry
);
5639 if (IS_IMMUTABLE(inode
) || IS_APPEND(inode
))
5643 inode
->i_ctime
= attrs
.ia_ctime
;
5644 attrs
.ia_valid
&= ~ATTR_CTIME
;
5645 rc
= notify_change(user_ns
, dentry
, &attrs
, NULL
);
5646 inode_unlock(inode
);
5651 static int set_file_allocation_info(struct ksmbd_work
*work
,
5652 struct ksmbd_file
*fp
,
5653 struct smb2_file_alloc_info
*file_alloc_info
)
5656 * TODO : It's working fine only when store dos attributes
5657 * is not yes. need to implement a logic which works
5658 * properly with any smb.conf option
5662 struct inode
*inode
;
5665 if (!(fp
->daccess
& FILE_WRITE_DATA_LE
))
5668 alloc_blks
= (le64_to_cpu(file_alloc_info
->AllocationSize
) + 511) >> 9;
5669 inode
= file_inode(fp
->filp
);
5671 if (alloc_blks
> inode
->i_blocks
) {
5672 smb_break_all_levII_oplock(work
, fp
, 1);
5673 rc
= vfs_fallocate(fp
->filp
, FALLOC_FL_KEEP_SIZE
, 0,
5675 if (rc
&& rc
!= -EOPNOTSUPP
) {
5676 pr_err("vfs_fallocate is failed : %d\n", rc
);
5679 } else if (alloc_blks
< inode
->i_blocks
) {
5683 * Allocation size could be smaller than original one
5684 * which means allocated blocks in file should be
5685 * deallocated. use truncate to cut out it, but inode
5686 * size is also updated with truncate offset.
5687 * inode size is retained by backup inode size.
5689 size
= i_size_read(inode
);
5690 rc
= ksmbd_vfs_truncate(work
, fp
, alloc_blks
* 512);
5692 pr_err("truncate failed! filename : %s, err %d\n",
5696 if (size
< alloc_blks
* 512)
5697 i_size_write(inode
, size
);
5702 static int set_end_of_file_info(struct ksmbd_work
*work
, struct ksmbd_file
*fp
,
5703 struct smb2_file_eof_info
*file_eof_info
)
5706 struct inode
*inode
;
5709 if (!(fp
->daccess
& FILE_WRITE_DATA_LE
))
5712 newsize
= le64_to_cpu(file_eof_info
->EndOfFile
);
5713 inode
= file_inode(fp
->filp
);
5716 * If FILE_END_OF_FILE_INFORMATION of set_info_file is called
5717 * on FAT32 shared device, truncate execution time is too long
5718 * and network error could cause from windows client. because
5719 * truncate of some filesystem like FAT32 fill zero data in
5722 if (inode
->i_sb
->s_magic
!= MSDOS_SUPER_MAGIC
) {
5723 ksmbd_debug(SMB
, "filename : %s truncated to newsize %lld\n",
5724 fp
->filename
, newsize
);
5725 rc
= ksmbd_vfs_truncate(work
, fp
, newsize
);
5727 ksmbd_debug(SMB
, "truncate failed! filename : %s err %d\n",
5737 static int set_rename_info(struct ksmbd_work
*work
, struct ksmbd_file
*fp
,
5738 struct smb2_file_rename_info
*rename_info
,
5739 unsigned int buf_len
)
5741 struct user_namespace
*user_ns
;
5742 struct ksmbd_file
*parent_fp
;
5743 struct dentry
*parent
;
5744 struct dentry
*dentry
= fp
->filp
->f_path
.dentry
;
5747 if (!(fp
->daccess
& FILE_DELETE_LE
)) {
5748 pr_err("no right to delete : 0x%x\n", fp
->daccess
);
5752 if (buf_len
< (u64
)sizeof(struct smb2_file_rename_info
) +
5753 le32_to_cpu(rename_info
->FileNameLength
))
5756 user_ns
= file_mnt_user_ns(fp
->filp
);
5757 if (ksmbd_stream_fd(fp
))
5760 parent
= dget_parent(dentry
);
5761 ret
= ksmbd_vfs_lock_parent(user_ns
, parent
, dentry
);
5767 parent_fp
= ksmbd_lookup_fd_inode(d_inode(parent
));
5768 inode_unlock(d_inode(parent
));
5772 if (parent_fp
->daccess
& FILE_DELETE_LE
) {
5773 pr_err("parent dir is opened with delete access\n");
5774 ksmbd_fd_put(work
, parent_fp
);
5777 ksmbd_fd_put(work
, parent_fp
);
5780 return smb2_rename(work
, fp
, user_ns
, rename_info
,
5781 work
->sess
->conn
->local_nls
);
5784 static int set_file_disposition_info(struct ksmbd_file
*fp
,
5785 struct smb2_file_disposition_info
*file_info
)
5787 struct inode
*inode
;
5789 if (!(fp
->daccess
& FILE_DELETE_LE
)) {
5790 pr_err("no right to delete : 0x%x\n", fp
->daccess
);
5794 inode
= file_inode(fp
->filp
);
5795 if (file_info
->DeletePending
) {
5796 if (S_ISDIR(inode
->i_mode
) &&
5797 ksmbd_vfs_empty_dir(fp
) == -ENOTEMPTY
)
5799 ksmbd_set_inode_pending_delete(fp
);
5801 ksmbd_clear_inode_pending_delete(fp
);
5806 static int set_file_position_info(struct ksmbd_file
*fp
,
5807 struct smb2_file_pos_info
*file_info
)
5809 loff_t current_byte_offset
;
5810 unsigned long sector_size
;
5811 struct inode
*inode
;
5813 inode
= file_inode(fp
->filp
);
5814 current_byte_offset
= le64_to_cpu(file_info
->CurrentByteOffset
);
5815 sector_size
= inode
->i_sb
->s_blocksize
;
5817 if (current_byte_offset
< 0 ||
5818 (fp
->coption
== FILE_NO_INTERMEDIATE_BUFFERING_LE
&&
5819 current_byte_offset
& (sector_size
- 1))) {
5820 pr_err("CurrentByteOffset is not valid : %llu\n",
5821 current_byte_offset
);
5825 fp
->filp
->f_pos
= current_byte_offset
;
5829 static int set_file_mode_info(struct ksmbd_file
*fp
,
5830 struct smb2_file_mode_info
*file_info
)
5834 mode
= file_info
->Mode
;
5836 if ((mode
& ~FILE_MODE_INFO_MASK
) ||
5837 (mode
& FILE_SYNCHRONOUS_IO_ALERT_LE
&&
5838 mode
& FILE_SYNCHRONOUS_IO_NONALERT_LE
)) {
5839 pr_err("Mode is not valid : 0x%x\n", le32_to_cpu(mode
));
5844 * TODO : need to implement consideration for
5845 * FILE_SYNCHRONOUS_IO_ALERT and FILE_SYNCHRONOUS_IO_NONALERT
5847 ksmbd_vfs_set_fadvise(fp
->filp
, mode
);
5853 * smb2_set_info_file() - handler for smb2 set info command
5854 * @work: smb work containing set info command buffer
5855 * @fp: ksmbd_file pointer
5856 * @info_class: smb2 set info class
5857 * @share: ksmbd_share_config pointer
5859 * Return: 0 on success, otherwise error
5860 * TODO: need to implement an error handling for STATUS_INFO_LENGTH_MISMATCH
5862 static int smb2_set_info_file(struct ksmbd_work
*work
, struct ksmbd_file
*fp
,
5863 struct smb2_set_info_req
*req
,
5864 struct ksmbd_share_config
*share
)
5866 unsigned int buf_len
= le32_to_cpu(req
->BufferLength
);
5868 switch (req
->FileInfoClass
) {
5869 case FILE_BASIC_INFORMATION
:
5871 if (buf_len
< sizeof(struct smb2_file_basic_info
))
5874 return set_file_basic_info(fp
, (struct smb2_file_basic_info
*)req
->Buffer
, share
);
5876 case FILE_ALLOCATION_INFORMATION
:
5878 if (buf_len
< sizeof(struct smb2_file_alloc_info
))
5881 return set_file_allocation_info(work
, fp
,
5882 (struct smb2_file_alloc_info
*)req
->Buffer
);
5884 case FILE_END_OF_FILE_INFORMATION
:
5886 if (buf_len
< sizeof(struct smb2_file_eof_info
))
5889 return set_end_of_file_info(work
, fp
,
5890 (struct smb2_file_eof_info
*)req
->Buffer
);
5892 case FILE_RENAME_INFORMATION
:
5894 if (!test_tree_conn_flag(work
->tcon
, KSMBD_TREE_CONN_FLAG_WRITABLE
)) {
5896 "User does not have write permission\n");
5900 if (buf_len
< sizeof(struct smb2_file_rename_info
))
5903 return set_rename_info(work
, fp
,
5904 (struct smb2_file_rename_info
*)req
->Buffer
,
5907 case FILE_LINK_INFORMATION
:
5909 if (buf_len
< sizeof(struct smb2_file_link_info
))
5912 return smb2_create_link(work
, work
->tcon
->share_conf
,
5913 (struct smb2_file_link_info
*)req
->Buffer
,
5915 work
->sess
->conn
->local_nls
);
5917 case FILE_DISPOSITION_INFORMATION
:
5919 if (!test_tree_conn_flag(work
->tcon
, KSMBD_TREE_CONN_FLAG_WRITABLE
)) {
5921 "User does not have write permission\n");
5925 if (buf_len
< sizeof(struct smb2_file_disposition_info
))
5928 return set_file_disposition_info(fp
,
5929 (struct smb2_file_disposition_info
*)req
->Buffer
);
5931 case FILE_FULL_EA_INFORMATION
:
5933 if (!(fp
->daccess
& FILE_WRITE_EA_LE
)) {
5934 pr_err("Not permitted to write ext attr: 0x%x\n",
5939 if (buf_len
< sizeof(struct smb2_ea_info
))
5942 return smb2_set_ea((struct smb2_ea_info
*)req
->Buffer
,
5943 buf_len
, &fp
->filp
->f_path
);
5945 case FILE_POSITION_INFORMATION
:
5947 if (buf_len
< sizeof(struct smb2_file_pos_info
))
5950 return set_file_position_info(fp
, (struct smb2_file_pos_info
*)req
->Buffer
);
5952 case FILE_MODE_INFORMATION
:
5954 if (buf_len
< sizeof(struct smb2_file_mode_info
))
5957 return set_file_mode_info(fp
, (struct smb2_file_mode_info
*)req
->Buffer
);
5961 pr_err("Unimplemented Fileinfoclass :%d\n", req
->FileInfoClass
);
5965 static int smb2_set_info_sec(struct ksmbd_file
*fp
, int addition_info
,
5966 char *buffer
, int buf_len
)
5968 struct smb_ntsd
*pntsd
= (struct smb_ntsd
*)buffer
;
5970 fp
->saccess
|= FILE_SHARE_DELETE_LE
;
5972 return set_info_sec(fp
->conn
, fp
->tcon
, &fp
->filp
->f_path
, pntsd
,
5977 * smb2_set_info() - handler for smb2 set info command handler
5978 * @work: smb work containing set info request buffer
5980 * Return: 0 on success, otherwise error
5982 int smb2_set_info(struct ksmbd_work
*work
)
5984 struct smb2_set_info_req
*req
;
5985 struct smb2_set_info_rsp
*rsp
, *rsp_org
;
5986 struct ksmbd_file
*fp
;
5988 unsigned int id
= KSMBD_NO_FID
, pid
= KSMBD_NO_FID
;
5990 ksmbd_debug(SMB
, "Received set info request\n");
5992 rsp_org
= work
->response_buf
;
5993 if (work
->next_smb2_rcv_hdr_off
) {
5994 req
= ksmbd_req_buf_next(work
);
5995 rsp
= ksmbd_resp_buf_next(work
);
5996 if (!has_file_id(le64_to_cpu(req
->VolatileFileId
))) {
5997 ksmbd_debug(SMB
, "Compound request set FID = %llu\n",
5998 work
->compound_fid
);
5999 id
= work
->compound_fid
;
6000 pid
= work
->compound_pfid
;
6003 req
= work
->request_buf
;
6004 rsp
= work
->response_buf
;
6007 if (!has_file_id(id
)) {
6008 id
= le64_to_cpu(req
->VolatileFileId
);
6009 pid
= le64_to_cpu(req
->PersistentFileId
);
6012 fp
= ksmbd_lookup_fd_slow(work
, id
, pid
);
6014 ksmbd_debug(SMB
, "Invalid id for close: %u\n", id
);
6019 switch (req
->InfoType
) {
6020 case SMB2_O_INFO_FILE
:
6021 ksmbd_debug(SMB
, "GOT SMB2_O_INFO_FILE\n");
6022 rc
= smb2_set_info_file(work
, fp
, req
, work
->tcon
->share_conf
);
6024 case SMB2_O_INFO_SECURITY
:
6025 ksmbd_debug(SMB
, "GOT SMB2_O_INFO_SECURITY\n");
6026 if (ksmbd_override_fsids(work
)) {
6030 rc
= smb2_set_info_sec(fp
,
6031 le32_to_cpu(req
->AdditionalInformation
),
6033 le32_to_cpu(req
->BufferLength
));
6034 ksmbd_revert_fsids(work
);
6043 rsp
->StructureSize
= cpu_to_le16(2);
6044 inc_rfc1001_len(rsp_org
, 2);
6045 ksmbd_fd_put(work
, fp
);
6049 if (rc
== -EACCES
|| rc
== -EPERM
|| rc
== -EXDEV
)
6050 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
6051 else if (rc
== -EINVAL
)
6052 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
6053 else if (rc
== -ESHARE
)
6054 rsp
->hdr
.Status
= STATUS_SHARING_VIOLATION
;
6055 else if (rc
== -ENOENT
)
6056 rsp
->hdr
.Status
= STATUS_OBJECT_NAME_INVALID
;
6057 else if (rc
== -EBUSY
|| rc
== -ENOTEMPTY
)
6058 rsp
->hdr
.Status
= STATUS_DIRECTORY_NOT_EMPTY
;
6059 else if (rc
== -EAGAIN
)
6060 rsp
->hdr
.Status
= STATUS_FILE_LOCK_CONFLICT
;
6061 else if (rc
== -EBADF
|| rc
== -ESTALE
)
6062 rsp
->hdr
.Status
= STATUS_INVALID_HANDLE
;
6063 else if (rc
== -EEXIST
)
6064 rsp
->hdr
.Status
= STATUS_OBJECT_NAME_COLLISION
;
6065 else if (rsp
->hdr
.Status
== 0 || rc
== -EOPNOTSUPP
)
6066 rsp
->hdr
.Status
= STATUS_INVALID_INFO_CLASS
;
6067 smb2_set_err_rsp(work
);
6068 ksmbd_fd_put(work
, fp
);
6069 ksmbd_debug(SMB
, "error while processing smb2 query rc = %d\n", rc
);
6074 * smb2_read_pipe() - handler for smb2 read from IPC pipe
6075 * @work: smb work containing read IPC pipe command buffer
6077 * Return: 0 on success, otherwise error
6079 static noinline
int smb2_read_pipe(struct ksmbd_work
*work
)
6081 int nbytes
= 0, err
;
6083 struct ksmbd_rpc_command
*rpc_resp
;
6084 struct smb2_read_req
*req
= work
->request_buf
;
6085 struct smb2_read_rsp
*rsp
= work
->response_buf
;
6087 id
= le64_to_cpu(req
->VolatileFileId
);
6089 inc_rfc1001_len(rsp
, 16);
6090 rpc_resp
= ksmbd_rpc_read(work
->sess
, id
);
6092 if (rpc_resp
->flags
!= KSMBD_RPC_OK
) {
6097 work
->aux_payload_buf
=
6098 kvmalloc(rpc_resp
->payload_sz
, GFP_KERNEL
| __GFP_ZERO
);
6099 if (!work
->aux_payload_buf
) {
6104 memcpy(work
->aux_payload_buf
, rpc_resp
->payload
,
6105 rpc_resp
->payload_sz
);
6107 nbytes
= rpc_resp
->payload_sz
;
6108 work
->resp_hdr_sz
= get_rfc1002_len(rsp
) + 4;
6109 work
->aux_payload_sz
= nbytes
;
6113 rsp
->StructureSize
= cpu_to_le16(17);
6114 rsp
->DataOffset
= 80;
6116 rsp
->DataLength
= cpu_to_le32(nbytes
);
6117 rsp
->DataRemaining
= 0;
6119 inc_rfc1001_len(rsp
, nbytes
);
6123 rsp
->hdr
.Status
= STATUS_UNEXPECTED_IO_ERROR
;
6124 smb2_set_err_rsp(work
);
6129 static ssize_t
smb2_read_rdma_channel(struct ksmbd_work
*work
,
6130 struct smb2_read_req
*req
, void *data_buf
,
6133 struct smb2_buffer_desc_v1
*desc
=
6134 (struct smb2_buffer_desc_v1
*)&req
->Buffer
[0];
6137 if (work
->conn
->dialect
== SMB30_PROT_ID
&&
6138 req
->Channel
!= SMB2_CHANNEL_RDMA_V1
)
6141 if (req
->ReadChannelInfoOffset
== 0 ||
6142 le16_to_cpu(req
->ReadChannelInfoLength
) < sizeof(*desc
))
6145 work
->need_invalidate_rkey
=
6146 (req
->Channel
== SMB2_CHANNEL_RDMA_V1_INVALIDATE
);
6147 work
->remote_key
= le32_to_cpu(desc
->token
);
6149 err
= ksmbd_conn_rdma_write(work
->conn
, data_buf
, length
,
6150 le32_to_cpu(desc
->token
),
6151 le64_to_cpu(desc
->offset
),
6152 le32_to_cpu(desc
->length
));
6160 * smb2_read() - handler for smb2 read from file
6161 * @work: smb work containing read command buffer
6163 * Return: 0 on success, otherwise error
6165 int smb2_read(struct ksmbd_work
*work
)
6167 struct ksmbd_conn
*conn
= work
->conn
;
6168 struct smb2_read_req
*req
;
6169 struct smb2_read_rsp
*rsp
, *rsp_org
;
6170 struct ksmbd_file
*fp
;
6172 size_t length
, mincount
;
6173 ssize_t nbytes
= 0, remain_bytes
= 0;
6176 rsp_org
= work
->response_buf
;
6177 WORK_BUFFERS(work
, req
, rsp
);
6179 if (test_share_config_flag(work
->tcon
->share_conf
,
6180 KSMBD_SHARE_FLAG_PIPE
)) {
6181 ksmbd_debug(SMB
, "IPC pipe read request\n");
6182 return smb2_read_pipe(work
);
6185 fp
= ksmbd_lookup_fd_slow(work
, le64_to_cpu(req
->VolatileFileId
),
6186 le64_to_cpu(req
->PersistentFileId
));
6192 if (!(fp
->daccess
& (FILE_READ_DATA_LE
| FILE_READ_ATTRIBUTES_LE
))) {
6193 pr_err("Not permitted to read : 0x%x\n", fp
->daccess
);
6198 offset
= le64_to_cpu(req
->Offset
);
6199 length
= le32_to_cpu(req
->Length
);
6200 mincount
= le32_to_cpu(req
->MinimumCount
);
6202 if (length
> conn
->vals
->max_read_size
) {
6203 ksmbd_debug(SMB
, "limiting read size to max size(%u)\n",
6204 conn
->vals
->max_read_size
);
6209 ksmbd_debug(SMB
, "filename %pd, offset %lld, len %zu\n",
6210 fp
->filp
->f_path
.dentry
, offset
, length
);
6212 work
->aux_payload_buf
= kvmalloc(length
, GFP_KERNEL
| __GFP_ZERO
);
6213 if (!work
->aux_payload_buf
) {
6218 nbytes
= ksmbd_vfs_read(work
, fp
, length
, &offset
);
6224 if ((nbytes
== 0 && length
!= 0) || nbytes
< mincount
) {
6225 kvfree(work
->aux_payload_buf
);
6226 work
->aux_payload_buf
= NULL
;
6227 rsp
->hdr
.Status
= STATUS_END_OF_FILE
;
6228 smb2_set_err_rsp(work
);
6229 ksmbd_fd_put(work
, fp
);
6233 ksmbd_debug(SMB
, "nbytes %zu, offset %lld mincount %zu\n",
6234 nbytes
, offset
, mincount
);
6236 if (req
->Channel
== SMB2_CHANNEL_RDMA_V1_INVALIDATE
||
6237 req
->Channel
== SMB2_CHANNEL_RDMA_V1
) {
6238 /* write data to the client using rdma channel */
6239 remain_bytes
= smb2_read_rdma_channel(work
, req
,
6240 work
->aux_payload_buf
,
6242 kvfree(work
->aux_payload_buf
);
6243 work
->aux_payload_buf
= NULL
;
6246 if (remain_bytes
< 0) {
6247 err
= (int)remain_bytes
;
6252 rsp
->StructureSize
= cpu_to_le16(17);
6253 rsp
->DataOffset
= 80;
6255 rsp
->DataLength
= cpu_to_le32(nbytes
);
6256 rsp
->DataRemaining
= cpu_to_le32(remain_bytes
);
6258 inc_rfc1001_len(rsp_org
, 16);
6259 work
->resp_hdr_sz
= get_rfc1002_len(rsp_org
) + 4;
6260 work
->aux_payload_sz
= nbytes
;
6261 inc_rfc1001_len(rsp_org
, nbytes
);
6262 ksmbd_fd_put(work
, fp
);
6268 rsp
->hdr
.Status
= STATUS_INVALID_DEVICE_REQUEST
;
6269 else if (err
== -EAGAIN
)
6270 rsp
->hdr
.Status
= STATUS_FILE_LOCK_CONFLICT
;
6271 else if (err
== -ENOENT
)
6272 rsp
->hdr
.Status
= STATUS_FILE_CLOSED
;
6273 else if (err
== -EACCES
)
6274 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
6275 else if (err
== -ESHARE
)
6276 rsp
->hdr
.Status
= STATUS_SHARING_VIOLATION
;
6277 else if (err
== -EINVAL
)
6278 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
6280 rsp
->hdr
.Status
= STATUS_INVALID_HANDLE
;
6282 smb2_set_err_rsp(work
);
6284 ksmbd_fd_put(work
, fp
);
6289 * smb2_write_pipe() - handler for smb2 write on IPC pipe
6290 * @work: smb work containing write IPC pipe command buffer
6292 * Return: 0 on success, otherwise error
6294 static noinline
int smb2_write_pipe(struct ksmbd_work
*work
)
6296 struct smb2_write_req
*req
= work
->request_buf
;
6297 struct smb2_write_rsp
*rsp
= work
->response_buf
;
6298 struct ksmbd_rpc_command
*rpc_resp
;
6300 int err
= 0, ret
= 0;
6304 length
= le32_to_cpu(req
->Length
);
6305 id
= le64_to_cpu(req
->VolatileFileId
);
6307 if (le16_to_cpu(req
->DataOffset
) ==
6308 (offsetof(struct smb2_write_req
, Buffer
) - 4)) {
6309 data_buf
= (char *)&req
->Buffer
[0];
6311 if ((u64
)le16_to_cpu(req
->DataOffset
) + length
> get_rfc1002_len(req
)) {
6312 pr_err("invalid write data offset %u, smb_len %u\n",
6313 le16_to_cpu(req
->DataOffset
),
6314 get_rfc1002_len(req
));
6319 data_buf
= (char *)(((char *)&req
->hdr
.ProtocolId
) +
6320 le16_to_cpu(req
->DataOffset
));
6323 rpc_resp
= ksmbd_rpc_write(work
->sess
, id
, data_buf
, length
);
6325 if (rpc_resp
->flags
== KSMBD_RPC_ENOTIMPLEMENTED
) {
6326 rsp
->hdr
.Status
= STATUS_NOT_SUPPORTED
;
6328 smb2_set_err_rsp(work
);
6331 if (rpc_resp
->flags
!= KSMBD_RPC_OK
) {
6332 rsp
->hdr
.Status
= STATUS_INVALID_HANDLE
;
6333 smb2_set_err_rsp(work
);
6340 rsp
->StructureSize
= cpu_to_le16(17);
6341 rsp
->DataOffset
= 0;
6343 rsp
->DataLength
= cpu_to_le32(length
);
6344 rsp
->DataRemaining
= 0;
6346 inc_rfc1001_len(rsp
, 16);
6350 rsp
->hdr
.Status
= STATUS_INVALID_HANDLE
;
6351 smb2_set_err_rsp(work
);
6357 static ssize_t
smb2_write_rdma_channel(struct ksmbd_work
*work
,
6358 struct smb2_write_req
*req
,
6359 struct ksmbd_file
*fp
,
6360 loff_t offset
, size_t length
, bool sync
)
6362 struct smb2_buffer_desc_v1
*desc
;
6367 desc
= (struct smb2_buffer_desc_v1
*)&req
->Buffer
[0];
6369 if (work
->conn
->dialect
== SMB30_PROT_ID
&&
6370 req
->Channel
!= SMB2_CHANNEL_RDMA_V1
)
6373 if (req
->Length
!= 0 || req
->DataOffset
!= 0)
6376 if (req
->WriteChannelInfoOffset
== 0 ||
6377 le16_to_cpu(req
->WriteChannelInfoLength
) < sizeof(*desc
))
6380 work
->need_invalidate_rkey
=
6381 (req
->Channel
== SMB2_CHANNEL_RDMA_V1_INVALIDATE
);
6382 work
->remote_key
= le32_to_cpu(desc
->token
);
6384 data_buf
= kvmalloc(length
, GFP_KERNEL
| __GFP_ZERO
);
6388 ret
= ksmbd_conn_rdma_read(work
->conn
, data_buf
, length
,
6389 le32_to_cpu(desc
->token
),
6390 le64_to_cpu(desc
->offset
),
6391 le32_to_cpu(desc
->length
));
6397 ret
= ksmbd_vfs_write(work
, fp
, data_buf
, length
, &offset
, sync
, &nbytes
);
6406 * smb2_write() - handler for smb2 write from file
6407 * @work: smb work containing write command buffer
6409 * Return: 0 on success, otherwise error
6411 int smb2_write(struct ksmbd_work
*work
)
6413 struct smb2_write_req
*req
;
6414 struct smb2_write_rsp
*rsp
, *rsp_org
;
6415 struct ksmbd_file
*fp
= NULL
;
6420 bool writethrough
= false;
6423 rsp_org
= work
->response_buf
;
6424 WORK_BUFFERS(work
, req
, rsp
);
6426 if (test_share_config_flag(work
->tcon
->share_conf
, KSMBD_SHARE_FLAG_PIPE
)) {
6427 ksmbd_debug(SMB
, "IPC pipe write request\n");
6428 return smb2_write_pipe(work
);
6431 if (!test_tree_conn_flag(work
->tcon
, KSMBD_TREE_CONN_FLAG_WRITABLE
)) {
6432 ksmbd_debug(SMB
, "User does not have write permission\n");
6437 fp
= ksmbd_lookup_fd_slow(work
, le64_to_cpu(req
->VolatileFileId
),
6438 le64_to_cpu(req
->PersistentFileId
));
6444 if (!(fp
->daccess
& (FILE_WRITE_DATA_LE
| FILE_READ_ATTRIBUTES_LE
))) {
6445 pr_err("Not permitted to write : 0x%x\n", fp
->daccess
);
6450 offset
= le64_to_cpu(req
->Offset
);
6451 length
= le32_to_cpu(req
->Length
);
6453 if (length
> work
->conn
->vals
->max_write_size
) {
6454 ksmbd_debug(SMB
, "limiting write size to max size(%u)\n",
6455 work
->conn
->vals
->max_write_size
);
6460 if (le32_to_cpu(req
->Flags
) & SMB2_WRITEFLAG_WRITE_THROUGH
)
6461 writethrough
= true;
6463 if (req
->Channel
!= SMB2_CHANNEL_RDMA_V1
&&
6464 req
->Channel
!= SMB2_CHANNEL_RDMA_V1_INVALIDATE
) {
6465 if (le16_to_cpu(req
->DataOffset
) ==
6466 (offsetof(struct smb2_write_req
, Buffer
) - 4)) {
6467 data_buf
= (char *)&req
->Buffer
[0];
6469 if ((u64
)le16_to_cpu(req
->DataOffset
) + length
> get_rfc1002_len(req
)) {
6470 pr_err("invalid write data offset %u, smb_len %u\n",
6471 le16_to_cpu(req
->DataOffset
),
6472 get_rfc1002_len(req
));
6477 data_buf
= (char *)(((char *)&req
->hdr
.ProtocolId
) +
6478 le16_to_cpu(req
->DataOffset
));
6481 ksmbd_debug(SMB
, "flags %u\n", le32_to_cpu(req
->Flags
));
6482 if (le32_to_cpu(req
->Flags
) & SMB2_WRITEFLAG_WRITE_THROUGH
)
6483 writethrough
= true;
6485 ksmbd_debug(SMB
, "filename %pd, offset %lld, len %zu\n",
6486 fp
->filp
->f_path
.dentry
, offset
, length
);
6487 err
= ksmbd_vfs_write(work
, fp
, data_buf
, length
, &offset
,
6488 writethrough
, &nbytes
);
6492 /* read data from the client using rdma channel, and
6495 nbytes
= smb2_write_rdma_channel(work
, req
, fp
, offset
,
6496 le32_to_cpu(req
->RemainingBytes
),
6504 rsp
->StructureSize
= cpu_to_le16(17);
6505 rsp
->DataOffset
= 0;
6507 rsp
->DataLength
= cpu_to_le32(nbytes
);
6508 rsp
->DataRemaining
= 0;
6510 inc_rfc1001_len(rsp_org
, 16);
6511 ksmbd_fd_put(work
, fp
);
6516 rsp
->hdr
.Status
= STATUS_FILE_LOCK_CONFLICT
;
6517 else if (err
== -ENOSPC
|| err
== -EFBIG
)
6518 rsp
->hdr
.Status
= STATUS_DISK_FULL
;
6519 else if (err
== -ENOENT
)
6520 rsp
->hdr
.Status
= STATUS_FILE_CLOSED
;
6521 else if (err
== -EACCES
)
6522 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
6523 else if (err
== -ESHARE
)
6524 rsp
->hdr
.Status
= STATUS_SHARING_VIOLATION
;
6525 else if (err
== -EINVAL
)
6526 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
6528 rsp
->hdr
.Status
= STATUS_INVALID_HANDLE
;
6530 smb2_set_err_rsp(work
);
6531 ksmbd_fd_put(work
, fp
);
6536 * smb2_flush() - handler for smb2 flush file - fsync
6537 * @work: smb work containing flush command buffer
6539 * Return: 0 on success, otherwise error
6541 int smb2_flush(struct ksmbd_work
*work
)
6543 struct smb2_flush_req
*req
;
6544 struct smb2_flush_rsp
*rsp
, *rsp_org
;
6547 rsp_org
= work
->response_buf
;
6548 WORK_BUFFERS(work
, req
, rsp
);
6550 ksmbd_debug(SMB
, "SMB2_FLUSH called for fid %llu\n",
6551 le64_to_cpu(req
->VolatileFileId
));
6553 err
= ksmbd_vfs_fsync(work
,
6554 le64_to_cpu(req
->VolatileFileId
),
6555 le64_to_cpu(req
->PersistentFileId
));
6559 rsp
->StructureSize
= cpu_to_le16(4);
6561 inc_rfc1001_len(rsp_org
, 4);
6566 rsp
->hdr
.Status
= STATUS_INVALID_HANDLE
;
6567 smb2_set_err_rsp(work
);
6574 * smb2_cancel() - handler for smb2 cancel command
6575 * @work: smb work containing cancel command buffer
6577 * Return: 0 on success, otherwise error
6579 int smb2_cancel(struct ksmbd_work
*work
)
6581 struct ksmbd_conn
*conn
= work
->conn
;
6582 struct smb2_hdr
*hdr
= work
->request_buf
;
6583 struct smb2_hdr
*chdr
;
6584 struct ksmbd_work
*cancel_work
= NULL
;
6586 struct list_head
*command_list
;
6588 ksmbd_debug(SMB
, "smb2 cancel called on mid %llu, async flags 0x%x\n",
6589 hdr
->MessageId
, hdr
->Flags
);
6591 if (hdr
->Flags
& SMB2_FLAGS_ASYNC_COMMAND
) {
6592 command_list
= &conn
->async_requests
;
6594 spin_lock(&conn
->request_lock
);
6595 list_for_each_entry(cancel_work
, command_list
,
6596 async_request_entry
) {
6597 chdr
= cancel_work
->request_buf
;
6599 if (cancel_work
->async_id
!=
6600 le64_to_cpu(hdr
->Id
.AsyncId
))
6604 "smb2 with AsyncId %llu cancelled command = 0x%x\n",
6605 le64_to_cpu(hdr
->Id
.AsyncId
),
6606 le16_to_cpu(chdr
->Command
));
6610 spin_unlock(&conn
->request_lock
);
6612 command_list
= &conn
->requests
;
6614 spin_lock(&conn
->request_lock
);
6615 list_for_each_entry(cancel_work
, command_list
, request_entry
) {
6616 chdr
= cancel_work
->request_buf
;
6618 if (chdr
->MessageId
!= hdr
->MessageId
||
6619 cancel_work
== work
)
6623 "smb2 with mid %llu cancelled command = 0x%x\n",
6624 le64_to_cpu(hdr
->MessageId
),
6625 le16_to_cpu(chdr
->Command
));
6629 spin_unlock(&conn
->request_lock
);
6633 cancel_work
->state
= KSMBD_WORK_CANCELLED
;
6634 if (cancel_work
->cancel_fn
)
6635 cancel_work
->cancel_fn(cancel_work
->cancel_argv
);
6638 /* For SMB2_CANCEL command itself send no response*/
6639 work
->send_no_response
= 1;
6643 struct file_lock
*smb_flock_init(struct file
*f
)
6645 struct file_lock
*fl
;
6647 fl
= locks_alloc_lock();
6651 locks_init_lock(fl
);
6654 fl
->fl_pid
= current
->tgid
;
6656 fl
->fl_flags
= FL_POSIX
;
6658 fl
->fl_lmops
= NULL
;
6664 static int smb2_set_flock_flags(struct file_lock
*flock
, int flags
)
6668 /* Checking for wrong flag combination during lock request*/
6670 case SMB2_LOCKFLAG_SHARED
:
6671 ksmbd_debug(SMB
, "received shared request\n");
6673 flock
->fl_type
= F_RDLCK
;
6674 flock
->fl_flags
|= FL_SLEEP
;
6676 case SMB2_LOCKFLAG_EXCLUSIVE
:
6677 ksmbd_debug(SMB
, "received exclusive request\n");
6679 flock
->fl_type
= F_WRLCK
;
6680 flock
->fl_flags
|= FL_SLEEP
;
6682 case SMB2_LOCKFLAG_SHARED
| SMB2_LOCKFLAG_FAIL_IMMEDIATELY
:
6684 "received shared & fail immediately request\n");
6686 flock
->fl_type
= F_RDLCK
;
6688 case SMB2_LOCKFLAG_EXCLUSIVE
| SMB2_LOCKFLAG_FAIL_IMMEDIATELY
:
6690 "received exclusive & fail immediately request\n");
6692 flock
->fl_type
= F_WRLCK
;
6694 case SMB2_LOCKFLAG_UNLOCK
:
6695 ksmbd_debug(SMB
, "received unlock request\n");
6696 flock
->fl_type
= F_UNLCK
;
6704 static struct ksmbd_lock
*smb2_lock_init(struct file_lock
*flock
,
6705 unsigned int cmd
, int flags
,
6706 struct list_head
*lock_list
)
6708 struct ksmbd_lock
*lock
;
6710 lock
= kzalloc(sizeof(struct ksmbd_lock
), GFP_KERNEL
);
6716 lock
->start
= flock
->fl_start
;
6717 lock
->end
= flock
->fl_end
;
6718 lock
->flags
= flags
;
6719 if (lock
->start
== lock
->end
)
6721 INIT_LIST_HEAD(&lock
->clist
);
6722 INIT_LIST_HEAD(&lock
->flist
);
6723 INIT_LIST_HEAD(&lock
->llist
);
6724 list_add_tail(&lock
->llist
, lock_list
);
6729 static void smb2_remove_blocked_lock(void **argv
)
6731 struct file_lock
*flock
= (struct file_lock
*)argv
[0];
6733 ksmbd_vfs_posix_lock_unblock(flock
);
6734 wake_up(&flock
->fl_wait
);
6737 static inline bool lock_defer_pending(struct file_lock
*fl
)
6739 /* check pending lock waiters */
6740 return waitqueue_active(&fl
->fl_wait
);
6744 * smb2_lock() - handler for smb2 file lock command
6745 * @work: smb work containing lock command buffer
6747 * Return: 0 on success, otherwise error
6749 int smb2_lock(struct ksmbd_work
*work
)
6751 struct smb2_lock_req
*req
= work
->request_buf
;
6752 struct smb2_lock_rsp
*rsp
= work
->response_buf
;
6753 struct smb2_lock_element
*lock_ele
;
6754 struct ksmbd_file
*fp
= NULL
;
6755 struct file_lock
*flock
= NULL
;
6756 struct file
*filp
= NULL
;
6760 int err
= -EIO
, i
, rc
= 0;
6761 u64 lock_start
, lock_length
;
6762 struct ksmbd_lock
*smb_lock
= NULL
, *cmp_lock
, *tmp
, *tmp2
;
6763 struct ksmbd_conn
*conn
;
6765 LIST_HEAD(lock_list
);
6766 LIST_HEAD(rollback_list
);
6769 ksmbd_debug(SMB
, "Received lock request\n");
6770 fp
= ksmbd_lookup_fd_slow(work
,
6771 le64_to_cpu(req
->VolatileFileId
),
6772 le64_to_cpu(req
->PersistentFileId
));
6774 ksmbd_debug(SMB
, "Invalid file id for lock : %llu\n",
6775 le64_to_cpu(req
->VolatileFileId
));
6781 lock_count
= le16_to_cpu(req
->LockCount
);
6782 lock_ele
= req
->locks
;
6784 ksmbd_debug(SMB
, "lock count is %d\n", lock_count
);
6790 for (i
= 0; i
< lock_count
; i
++) {
6791 flags
= le32_to_cpu(lock_ele
[i
].Flags
);
6793 flock
= smb_flock_init(filp
);
6797 cmd
= smb2_set_flock_flags(flock
, flags
);
6799 lock_start
= le64_to_cpu(lock_ele
[i
].Offset
);
6800 lock_length
= le64_to_cpu(lock_ele
[i
].Length
);
6801 if (lock_start
> U64_MAX
- lock_length
) {
6802 pr_err("Invalid lock range requested\n");
6803 rsp
->hdr
.Status
= STATUS_INVALID_LOCK_RANGE
;
6807 if (lock_start
> OFFSET_MAX
)
6808 flock
->fl_start
= OFFSET_MAX
;
6810 flock
->fl_start
= lock_start
;
6812 lock_length
= le64_to_cpu(lock_ele
[i
].Length
);
6813 if (lock_length
> OFFSET_MAX
- flock
->fl_start
)
6814 lock_length
= OFFSET_MAX
- flock
->fl_start
;
6816 flock
->fl_end
= flock
->fl_start
+ lock_length
;
6818 if (flock
->fl_end
< flock
->fl_start
) {
6820 "the end offset(%llx) is smaller than the start offset(%llx)\n",
6821 flock
->fl_end
, flock
->fl_start
);
6822 rsp
->hdr
.Status
= STATUS_INVALID_LOCK_RANGE
;
6826 /* Check conflict locks in one request */
6827 list_for_each_entry(cmp_lock
, &lock_list
, llist
) {
6828 if (cmp_lock
->fl
->fl_start
<= flock
->fl_start
&&
6829 cmp_lock
->fl
->fl_end
>= flock
->fl_end
) {
6830 if (cmp_lock
->fl
->fl_type
!= F_UNLCK
&&
6831 flock
->fl_type
!= F_UNLCK
) {
6832 pr_err("conflict two locks in one request\n");
6839 smb_lock
= smb2_lock_init(flock
, cmd
, flags
, &lock_list
);
6846 list_for_each_entry_safe(smb_lock
, tmp
, &lock_list
, llist
) {
6847 if (smb_lock
->cmd
< 0) {
6852 if (!(smb_lock
->flags
& SMB2_LOCKFLAG_MASK
)) {
6857 if ((prior_lock
& (SMB2_LOCKFLAG_EXCLUSIVE
| SMB2_LOCKFLAG_SHARED
) &&
6858 smb_lock
->flags
& SMB2_LOCKFLAG_UNLOCK
) ||
6859 (prior_lock
== SMB2_LOCKFLAG_UNLOCK
&&
6860 !(smb_lock
->flags
& SMB2_LOCKFLAG_UNLOCK
))) {
6865 prior_lock
= smb_lock
->flags
;
6867 if (!(smb_lock
->flags
& SMB2_LOCKFLAG_UNLOCK
) &&
6868 !(smb_lock
->flags
& SMB2_LOCKFLAG_FAIL_IMMEDIATELY
))
6872 /* check locks in connection list */
6873 read_lock(&conn_list_lock
);
6874 list_for_each_entry(conn
, &conn_list
, conns_list
) {
6875 spin_lock(&conn
->llist_lock
);
6876 list_for_each_entry_safe(cmp_lock
, tmp2
, &conn
->lock_list
, clist
) {
6877 if (file_inode(cmp_lock
->fl
->fl_file
) !=
6878 file_inode(smb_lock
->fl
->fl_file
))
6881 if (smb_lock
->fl
->fl_type
== F_UNLCK
) {
6882 if (cmp_lock
->fl
->fl_file
== smb_lock
->fl
->fl_file
&&
6883 cmp_lock
->start
== smb_lock
->start
&&
6884 cmp_lock
->end
== smb_lock
->end
&&
6885 !lock_defer_pending(cmp_lock
->fl
)) {
6887 list_del(&cmp_lock
->flist
);
6888 list_del(&cmp_lock
->clist
);
6889 spin_unlock(&conn
->llist_lock
);
6890 read_unlock(&conn_list_lock
);
6892 locks_free_lock(cmp_lock
->fl
);
6899 if (cmp_lock
->fl
->fl_file
== smb_lock
->fl
->fl_file
) {
6900 if (smb_lock
->flags
& SMB2_LOCKFLAG_SHARED
)
6903 if (cmp_lock
->flags
& SMB2_LOCKFLAG_SHARED
)
6907 /* check zero byte lock range */
6908 if (cmp_lock
->zero_len
&& !smb_lock
->zero_len
&&
6909 cmp_lock
->start
> smb_lock
->start
&&
6910 cmp_lock
->start
< smb_lock
->end
) {
6911 spin_unlock(&conn
->llist_lock
);
6912 read_unlock(&conn_list_lock
);
6913 pr_err("previous lock conflict with zero byte lock range\n");
6917 if (smb_lock
->zero_len
&& !cmp_lock
->zero_len
&&
6918 smb_lock
->start
> cmp_lock
->start
&&
6919 smb_lock
->start
< cmp_lock
->end
) {
6920 spin_unlock(&conn
->llist_lock
);
6921 read_unlock(&conn_list_lock
);
6922 pr_err("current lock conflict with zero byte lock range\n");
6926 if (((cmp_lock
->start
<= smb_lock
->start
&&
6927 cmp_lock
->end
> smb_lock
->start
) ||
6928 (cmp_lock
->start
< smb_lock
->end
&&
6929 cmp_lock
->end
>= smb_lock
->end
)) &&
6930 !cmp_lock
->zero_len
&& !smb_lock
->zero_len
) {
6931 spin_unlock(&conn
->llist_lock
);
6932 read_unlock(&conn_list_lock
);
6933 pr_err("Not allow lock operation on exclusive lock range\n");
6937 spin_unlock(&conn
->llist_lock
);
6939 read_unlock(&conn_list_lock
);
6941 if (smb_lock
->fl
->fl_type
== F_UNLCK
&& nolock
) {
6942 pr_err("Try to unlock nolocked range\n");
6943 rsp
->hdr
.Status
= STATUS_RANGE_NOT_LOCKED
;
6948 if (smb_lock
->zero_len
) {
6953 flock
= smb_lock
->fl
;
6954 list_del(&smb_lock
->llist
);
6956 rc
= vfs_lock_file(filp
, smb_lock
->cmd
, flock
, NULL
);
6958 if (flags
& SMB2_LOCKFLAG_UNLOCK
) {
6960 ksmbd_debug(SMB
, "File unlocked\n");
6961 } else if (rc
== -ENOENT
) {
6962 rsp
->hdr
.Status
= STATUS_NOT_LOCKED
;
6965 locks_free_lock(flock
);
6968 if (rc
== FILE_LOCK_DEFERRED
) {
6972 "would have to wait for getting lock\n");
6973 spin_lock(&work
->conn
->llist_lock
);
6974 list_add_tail(&smb_lock
->clist
,
6975 &work
->conn
->lock_list
);
6976 spin_unlock(&work
->conn
->llist_lock
);
6977 list_add(&smb_lock
->llist
, &rollback_list
);
6979 argv
= kmalloc(sizeof(void *), GFP_KERNEL
);
6986 rc
= setup_async_work(work
,
6987 smb2_remove_blocked_lock
,
6993 spin_lock(&fp
->f_lock
);
6994 list_add(&work
->fp_entry
, &fp
->blocked_works
);
6995 spin_unlock(&fp
->f_lock
);
6997 smb2_send_interim_resp(work
, STATUS_PENDING
);
6999 ksmbd_vfs_posix_lock_wait(flock
);
7001 if (work
->state
!= KSMBD_WORK_ACTIVE
) {
7002 list_del(&smb_lock
->llist
);
7003 spin_lock(&work
->conn
->llist_lock
);
7004 list_del(&smb_lock
->clist
);
7005 spin_unlock(&work
->conn
->llist_lock
);
7006 locks_free_lock(flock
);
7008 if (work
->state
== KSMBD_WORK_CANCELLED
) {
7009 spin_lock(&fp
->f_lock
);
7010 list_del(&work
->fp_entry
);
7011 spin_unlock(&fp
->f_lock
);
7015 smb2_send_interim_resp(work
,
7017 work
->send_no_response
= 1;
7020 init_smb2_rsp_hdr(work
);
7021 smb2_set_err_rsp(work
);
7023 STATUS_RANGE_NOT_LOCKED
;
7028 list_del(&smb_lock
->llist
);
7029 spin_lock(&work
->conn
->llist_lock
);
7030 list_del(&smb_lock
->clist
);
7031 spin_unlock(&work
->conn
->llist_lock
);
7033 spin_lock(&fp
->f_lock
);
7034 list_del(&work
->fp_entry
);
7035 spin_unlock(&fp
->f_lock
);
7038 spin_lock(&work
->conn
->llist_lock
);
7039 list_add_tail(&smb_lock
->clist
,
7040 &work
->conn
->lock_list
);
7041 list_add_tail(&smb_lock
->flist
,
7043 spin_unlock(&work
->conn
->llist_lock
);
7044 list_add(&smb_lock
->llist
, &rollback_list
);
7045 ksmbd_debug(SMB
, "successful in taking lock\n");
7052 if (atomic_read(&fp
->f_ci
->op_count
) > 1)
7053 smb_break_all_oplock(work
, fp
);
7055 rsp
->StructureSize
= cpu_to_le16(4);
7056 ksmbd_debug(SMB
, "successful in taking lock\n");
7057 rsp
->hdr
.Status
= STATUS_SUCCESS
;
7059 inc_rfc1001_len(rsp
, 4);
7060 ksmbd_fd_put(work
, fp
);
7064 list_for_each_entry_safe(smb_lock
, tmp
, &lock_list
, llist
) {
7065 locks_free_lock(smb_lock
->fl
);
7066 list_del(&smb_lock
->llist
);
7070 list_for_each_entry_safe(smb_lock
, tmp
, &rollback_list
, llist
) {
7071 struct file_lock
*rlock
= NULL
;
7073 rlock
= smb_flock_init(filp
);
7074 rlock
->fl_type
= F_UNLCK
;
7075 rlock
->fl_start
= smb_lock
->start
;
7076 rlock
->fl_end
= smb_lock
->end
;
7078 rc
= vfs_lock_file(filp
, 0, rlock
, NULL
);
7080 pr_err("rollback unlock fail : %d\n", rc
);
7082 list_del(&smb_lock
->llist
);
7083 spin_lock(&work
->conn
->llist_lock
);
7084 if (!list_empty(&smb_lock
->flist
))
7085 list_del(&smb_lock
->flist
);
7086 list_del(&smb_lock
->clist
);
7087 spin_unlock(&work
->conn
->llist_lock
);
7089 locks_free_lock(smb_lock
->fl
);
7090 locks_free_lock(rlock
);
7094 ksmbd_debug(SMB
, "failed in taking lock(flags : %x), err : %d\n", flags
, err
);
7096 if (!rsp
->hdr
.Status
) {
7098 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
7099 else if (err
== -ENOMEM
)
7100 rsp
->hdr
.Status
= STATUS_INSUFFICIENT_RESOURCES
;
7101 else if (err
== -ENOENT
)
7102 rsp
->hdr
.Status
= STATUS_FILE_CLOSED
;
7104 rsp
->hdr
.Status
= STATUS_LOCK_NOT_GRANTED
;
7107 smb2_set_err_rsp(work
);
7108 ksmbd_fd_put(work
, fp
);
7112 static int fsctl_copychunk(struct ksmbd_work
*work
,
7113 struct copychunk_ioctl_req
*ci_req
,
7114 unsigned int cnt_code
,
7115 unsigned int input_count
,
7116 unsigned long long volatile_id
,
7117 unsigned long long persistent_id
,
7118 struct smb2_ioctl_rsp
*rsp
)
7120 struct copychunk_ioctl_rsp
*ci_rsp
;
7121 struct ksmbd_file
*src_fp
= NULL
, *dst_fp
= NULL
;
7122 struct srv_copychunk
*chunks
;
7123 unsigned int i
, chunk_count
, chunk_count_written
= 0;
7124 unsigned int chunk_size_written
= 0;
7125 loff_t total_size_written
= 0;
7128 ci_rsp
= (struct copychunk_ioctl_rsp
*)&rsp
->Buffer
[0];
7130 rsp
->VolatileFileId
= cpu_to_le64(volatile_id
);
7131 rsp
->PersistentFileId
= cpu_to_le64(persistent_id
);
7132 ci_rsp
->ChunksWritten
=
7133 cpu_to_le32(ksmbd_server_side_copy_max_chunk_count());
7134 ci_rsp
->ChunkBytesWritten
=
7135 cpu_to_le32(ksmbd_server_side_copy_max_chunk_size());
7136 ci_rsp
->TotalBytesWritten
=
7137 cpu_to_le32(ksmbd_server_side_copy_max_total_size());
7139 chunks
= (struct srv_copychunk
*)&ci_req
->Chunks
[0];
7140 chunk_count
= le32_to_cpu(ci_req
->ChunkCount
);
7141 if (chunk_count
== 0)
7143 total_size_written
= 0;
7145 /* verify the SRV_COPYCHUNK_COPY packet */
7146 if (chunk_count
> ksmbd_server_side_copy_max_chunk_count() ||
7147 input_count
< offsetof(struct copychunk_ioctl_req
, Chunks
) +
7148 chunk_count
* sizeof(struct srv_copychunk
)) {
7149 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
7153 for (i
= 0; i
< chunk_count
; i
++) {
7154 if (le32_to_cpu(chunks
[i
].Length
) == 0 ||
7155 le32_to_cpu(chunks
[i
].Length
) > ksmbd_server_side_copy_max_chunk_size())
7157 total_size_written
+= le32_to_cpu(chunks
[i
].Length
);
7160 if (i
< chunk_count
||
7161 total_size_written
> ksmbd_server_side_copy_max_total_size()) {
7162 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
7166 src_fp
= ksmbd_lookup_foreign_fd(work
,
7167 le64_to_cpu(ci_req
->ResumeKey
[0]));
7168 dst_fp
= ksmbd_lookup_fd_slow(work
, volatile_id
, persistent_id
);
7171 src_fp
->persistent_id
!= le64_to_cpu(ci_req
->ResumeKey
[1])) {
7172 rsp
->hdr
.Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
7177 rsp
->hdr
.Status
= STATUS_FILE_CLOSED
;
7182 * FILE_READ_DATA should only be included in
7183 * the FSCTL_COPYCHUNK case
7185 if (cnt_code
== FSCTL_COPYCHUNK
&&
7186 !(dst_fp
->daccess
& (FILE_READ_DATA_LE
| FILE_GENERIC_READ_LE
))) {
7187 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
7191 ret
= ksmbd_vfs_copy_file_ranges(work
, src_fp
, dst_fp
,
7192 chunks
, chunk_count
,
7193 &chunk_count_written
,
7194 &chunk_size_written
,
7195 &total_size_written
);
7198 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
7200 rsp
->hdr
.Status
= STATUS_FILE_LOCK_CONFLICT
;
7201 else if (ret
== -EBADF
)
7202 rsp
->hdr
.Status
= STATUS_INVALID_HANDLE
;
7203 else if (ret
== -EFBIG
|| ret
== -ENOSPC
)
7204 rsp
->hdr
.Status
= STATUS_DISK_FULL
;
7205 else if (ret
== -EINVAL
)
7206 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
7207 else if (ret
== -EISDIR
)
7208 rsp
->hdr
.Status
= STATUS_FILE_IS_A_DIRECTORY
;
7209 else if (ret
== -E2BIG
)
7210 rsp
->hdr
.Status
= STATUS_INVALID_VIEW_SIZE
;
7212 rsp
->hdr
.Status
= STATUS_UNEXPECTED_IO_ERROR
;
7215 ci_rsp
->ChunksWritten
= cpu_to_le32(chunk_count_written
);
7216 ci_rsp
->ChunkBytesWritten
= cpu_to_le32(chunk_size_written
);
7217 ci_rsp
->TotalBytesWritten
= cpu_to_le32(total_size_written
);
7219 ksmbd_fd_put(work
, src_fp
);
7220 ksmbd_fd_put(work
, dst_fp
);
7224 static __be32
idev_ipv4_address(struct in_device
*idev
)
7228 struct in_ifaddr
*ifa
;
7231 in_dev_for_each_ifa_rcu(ifa
, idev
) {
7232 if (ifa
->ifa_flags
& IFA_F_SECONDARY
)
7235 addr
= ifa
->ifa_address
;
7242 static int fsctl_query_iface_info_ioctl(struct ksmbd_conn
*conn
,
7243 struct smb2_ioctl_rsp
*rsp
,
7244 unsigned int out_buf_len
)
7246 struct network_interface_info_ioctl_rsp
*nii_rsp
= NULL
;
7248 struct net_device
*netdev
;
7249 struct sockaddr_storage_rsp
*sockaddr_storage
;
7251 unsigned long long speed
;
7252 struct sockaddr_in6
*csin6
= (struct sockaddr_in6
*)&conn
->peer_addr
;
7255 for_each_netdev(&init_net
, netdev
) {
7257 nbytes
+ sizeof(struct network_interface_info_ioctl_rsp
)) {
7262 if (netdev
->type
== ARPHRD_LOOPBACK
)
7265 flags
= dev_get_flags(netdev
);
7266 if (!(flags
& IFF_RUNNING
))
7269 nii_rsp
= (struct network_interface_info_ioctl_rsp
*)
7270 &rsp
->Buffer
[nbytes
];
7271 nii_rsp
->IfIndex
= cpu_to_le32(netdev
->ifindex
);
7273 nii_rsp
->Capability
= 0;
7274 if (ksmbd_rdma_capable_netdev(netdev
))
7275 nii_rsp
->Capability
|= cpu_to_le32(RDMA_CAPABLE
);
7277 nii_rsp
->Next
= cpu_to_le32(152);
7278 nii_rsp
->Reserved
= 0;
7280 if (netdev
->ethtool_ops
->get_link_ksettings
) {
7281 struct ethtool_link_ksettings cmd
;
7283 netdev
->ethtool_ops
->get_link_ksettings(netdev
, &cmd
);
7284 speed
= cmd
.base
.speed
;
7286 ksmbd_debug(SMB
, "%s %s\n", netdev
->name
,
7287 "speed is unknown, defaulting to 1Gb/sec");
7292 nii_rsp
->LinkSpeed
= cpu_to_le64(speed
);
7294 sockaddr_storage
= (struct sockaddr_storage_rsp
*)
7295 nii_rsp
->SockAddr_Storage
;
7296 memset(sockaddr_storage
, 0, 128);
7298 if (conn
->peer_addr
.ss_family
== PF_INET
||
7299 ipv6_addr_v4mapped(&csin6
->sin6_addr
)) {
7300 struct in_device
*idev
;
7302 sockaddr_storage
->Family
= cpu_to_le16(INTERNETWORK
);
7303 sockaddr_storage
->addr4
.Port
= 0;
7305 idev
= __in_dev_get_rtnl(netdev
);
7308 sockaddr_storage
->addr4
.IPv4address
=
7309 idev_ipv4_address(idev
);
7311 struct inet6_dev
*idev6
;
7312 struct inet6_ifaddr
*ifa
;
7313 __u8
*ipv6_addr
= sockaddr_storage
->addr6
.IPv6address
;
7315 sockaddr_storage
->Family
= cpu_to_le16(INTERNETWORKV6
);
7316 sockaddr_storage
->addr6
.Port
= 0;
7317 sockaddr_storage
->addr6
.FlowInfo
= 0;
7319 idev6
= __in6_dev_get(netdev
);
7323 list_for_each_entry(ifa
, &idev6
->addr_list
, if_list
) {
7324 if (ifa
->flags
& (IFA_F_TENTATIVE
|
7327 memcpy(ipv6_addr
, ifa
->addr
.s6_addr
, 16);
7330 sockaddr_storage
->addr6
.ScopeId
= 0;
7333 nbytes
+= sizeof(struct network_interface_info_ioctl_rsp
);
7337 /* zero if this is last one */
7341 rsp
->PersistentFileId
= cpu_to_le64(SMB2_NO_FID
);
7342 rsp
->VolatileFileId
= cpu_to_le64(SMB2_NO_FID
);
7346 static int fsctl_validate_negotiate_info(struct ksmbd_conn
*conn
,
7347 struct validate_negotiate_info_req
*neg_req
,
7348 struct validate_negotiate_info_rsp
*neg_rsp
,
7349 unsigned int in_buf_len
)
7354 if (in_buf_len
< offsetof(struct validate_negotiate_info_req
, Dialects
) +
7355 le16_to_cpu(neg_req
->DialectCount
) * sizeof(__le16
))
7358 dialect
= ksmbd_lookup_dialect_by_id(neg_req
->Dialects
,
7359 neg_req
->DialectCount
);
7360 if (dialect
== BAD_PROT_ID
|| dialect
!= conn
->dialect
) {
7365 if (strncmp(neg_req
->Guid
, conn
->ClientGUID
, SMB2_CLIENT_GUID_SIZE
)) {
7370 if (le16_to_cpu(neg_req
->SecurityMode
) != conn
->cli_sec_mode
) {
7375 if (le32_to_cpu(neg_req
->Capabilities
) != conn
->cli_cap
) {
7380 neg_rsp
->Capabilities
= cpu_to_le32(conn
->vals
->capabilities
);
7381 memset(neg_rsp
->Guid
, 0, SMB2_CLIENT_GUID_SIZE
);
7382 neg_rsp
->SecurityMode
= cpu_to_le16(conn
->srv_sec_mode
);
7383 neg_rsp
->Dialect
= cpu_to_le16(conn
->dialect
);
7388 static int fsctl_query_allocated_ranges(struct ksmbd_work
*work
, u64 id
,
7389 struct file_allocated_range_buffer
*qar_req
,
7390 struct file_allocated_range_buffer
*qar_rsp
,
7391 unsigned int in_count
, unsigned int *out_count
)
7393 struct ksmbd_file
*fp
;
7394 loff_t start
, length
;
7401 fp
= ksmbd_lookup_fd_fast(work
, id
);
7405 start
= le64_to_cpu(qar_req
->file_offset
);
7406 length
= le64_to_cpu(qar_req
->length
);
7408 ret
= ksmbd_vfs_fqar_lseek(fp
, start
, length
,
7409 qar_rsp
, in_count
, out_count
);
7410 if (ret
&& ret
!= -E2BIG
)
7413 ksmbd_fd_put(work
, fp
);
7417 static int fsctl_pipe_transceive(struct ksmbd_work
*work
, u64 id
,
7418 unsigned int out_buf_len
,
7419 struct smb2_ioctl_req
*req
,
7420 struct smb2_ioctl_rsp
*rsp
)
7422 struct ksmbd_rpc_command
*rpc_resp
;
7423 char *data_buf
= (char *)&req
->Buffer
[0];
7426 rpc_resp
= ksmbd_rpc_ioctl(work
->sess
, id
, data_buf
,
7427 le32_to_cpu(req
->InputCount
));
7429 if (rpc_resp
->flags
== KSMBD_RPC_SOME_NOT_MAPPED
) {
7431 * set STATUS_SOME_NOT_MAPPED response
7432 * for unknown domain sid.
7434 rsp
->hdr
.Status
= STATUS_SOME_NOT_MAPPED
;
7435 } else if (rpc_resp
->flags
== KSMBD_RPC_ENOTIMPLEMENTED
) {
7436 rsp
->hdr
.Status
= STATUS_NOT_SUPPORTED
;
7438 } else if (rpc_resp
->flags
!= KSMBD_RPC_OK
) {
7439 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
7443 nbytes
= rpc_resp
->payload_sz
;
7444 if (rpc_resp
->payload_sz
> out_buf_len
) {
7445 rsp
->hdr
.Status
= STATUS_BUFFER_OVERFLOW
;
7446 nbytes
= out_buf_len
;
7449 if (!rpc_resp
->payload_sz
) {
7451 STATUS_UNEXPECTED_IO_ERROR
;
7455 memcpy((char *)rsp
->Buffer
, rpc_resp
->payload
, nbytes
);
7462 static inline int fsctl_set_sparse(struct ksmbd_work
*work
, u64 id
,
7463 struct file_sparse
*sparse
)
7465 struct ksmbd_file
*fp
;
7466 struct user_namespace
*user_ns
;
7470 fp
= ksmbd_lookup_fd_fast(work
, id
);
7473 user_ns
= file_mnt_user_ns(fp
->filp
);
7475 old_fattr
= fp
->f_ci
->m_fattr
;
7476 if (sparse
->SetSparse
)
7477 fp
->f_ci
->m_fattr
|= ATTR_SPARSE_FILE_LE
;
7479 fp
->f_ci
->m_fattr
&= ~ATTR_SPARSE_FILE_LE
;
7481 if (fp
->f_ci
->m_fattr
!= old_fattr
&&
7482 test_share_config_flag(work
->tcon
->share_conf
,
7483 KSMBD_SHARE_FLAG_STORE_DOS_ATTRS
)) {
7484 struct xattr_dos_attrib da
;
7486 ret
= ksmbd_vfs_get_dos_attrib_xattr(user_ns
,
7487 fp
->filp
->f_path
.dentry
, &da
);
7491 da
.attr
= le32_to_cpu(fp
->f_ci
->m_fattr
);
7492 ret
= ksmbd_vfs_set_dos_attrib_xattr(user_ns
,
7493 fp
->filp
->f_path
.dentry
, &da
);
7495 fp
->f_ci
->m_fattr
= old_fattr
;
7499 ksmbd_fd_put(work
, fp
);
7503 static int fsctl_request_resume_key(struct ksmbd_work
*work
,
7504 struct smb2_ioctl_req
*req
,
7505 struct resume_key_ioctl_rsp
*key_rsp
)
7507 struct ksmbd_file
*fp
;
7509 fp
= ksmbd_lookup_fd_slow(work
,
7510 le64_to_cpu(req
->VolatileFileId
),
7511 le64_to_cpu(req
->PersistentFileId
));
7515 memset(key_rsp
, 0, sizeof(*key_rsp
));
7516 key_rsp
->ResumeKey
[0] = req
->VolatileFileId
;
7517 key_rsp
->ResumeKey
[1] = req
->PersistentFileId
;
7518 ksmbd_fd_put(work
, fp
);
7524 * smb2_ioctl() - handler for smb2 ioctl command
7525 * @work: smb work containing ioctl command buffer
7527 * Return: 0 on success, otherwise error
7529 int smb2_ioctl(struct ksmbd_work
*work
)
7531 struct smb2_ioctl_req
*req
;
7532 struct smb2_ioctl_rsp
*rsp
, *rsp_org
;
7533 unsigned int cnt_code
, nbytes
= 0, out_buf_len
, in_buf_len
;
7534 u64 id
= KSMBD_NO_FID
;
7535 struct ksmbd_conn
*conn
= work
->conn
;
7538 rsp_org
= work
->response_buf
;
7539 if (work
->next_smb2_rcv_hdr_off
) {
7540 req
= ksmbd_req_buf_next(work
);
7541 rsp
= ksmbd_resp_buf_next(work
);
7542 if (!has_file_id(le64_to_cpu(req
->VolatileFileId
))) {
7543 ksmbd_debug(SMB
, "Compound request set FID = %llu\n",
7544 work
->compound_fid
);
7545 id
= work
->compound_fid
;
7548 req
= work
->request_buf
;
7549 rsp
= work
->response_buf
;
7552 if (!has_file_id(id
))
7553 id
= le64_to_cpu(req
->VolatileFileId
);
7555 if (req
->Flags
!= cpu_to_le32(SMB2_0_IOCTL_IS_FSCTL
)) {
7556 rsp
->hdr
.Status
= STATUS_NOT_SUPPORTED
;
7560 cnt_code
= le32_to_cpu(req
->CntCode
);
7561 ret
= smb2_calc_max_out_buf_len(work
, 48,
7562 le32_to_cpu(req
->MaxOutputResponse
));
7564 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
7567 out_buf_len
= (unsigned int)ret
;
7568 in_buf_len
= le32_to_cpu(req
->InputCount
);
7571 case FSCTL_DFS_GET_REFERRALS
:
7572 case FSCTL_DFS_GET_REFERRALS_EX
:
7573 /* Not support DFS yet */
7574 rsp
->hdr
.Status
= STATUS_FS_DRIVER_REQUIRED
;
7576 case FSCTL_CREATE_OR_GET_OBJECT_ID
:
7578 struct file_object_buf_type1_ioctl_rsp
*obj_buf
;
7580 nbytes
= sizeof(struct file_object_buf_type1_ioctl_rsp
);
7581 obj_buf
= (struct file_object_buf_type1_ioctl_rsp
*)
7585 * TODO: This is dummy implementation to pass smbtorture
7586 * Need to check correct response later
7588 memset(obj_buf
->ObjectId
, 0x0, 16);
7589 memset(obj_buf
->BirthVolumeId
, 0x0, 16);
7590 memset(obj_buf
->BirthObjectId
, 0x0, 16);
7591 memset(obj_buf
->DomainId
, 0x0, 16);
7595 case FSCTL_PIPE_TRANSCEIVE
:
7596 out_buf_len
= min_t(u32
, KSMBD_IPC_MAX_PAYLOAD
, out_buf_len
);
7597 nbytes
= fsctl_pipe_transceive(work
, id
, out_buf_len
, req
, rsp
);
7599 case FSCTL_VALIDATE_NEGOTIATE_INFO
:
7600 if (conn
->dialect
< SMB30_PROT_ID
) {
7605 if (in_buf_len
< sizeof(struct validate_negotiate_info_req
))
7608 if (out_buf_len
< sizeof(struct validate_negotiate_info_rsp
))
7611 ret
= fsctl_validate_negotiate_info(conn
,
7612 (struct validate_negotiate_info_req
*)&req
->Buffer
[0],
7613 (struct validate_negotiate_info_rsp
*)&rsp
->Buffer
[0],
7618 nbytes
= sizeof(struct validate_negotiate_info_rsp
);
7619 rsp
->PersistentFileId
= cpu_to_le64(SMB2_NO_FID
);
7620 rsp
->VolatileFileId
= cpu_to_le64(SMB2_NO_FID
);
7622 case FSCTL_QUERY_NETWORK_INTERFACE_INFO
:
7623 ret
= fsctl_query_iface_info_ioctl(conn
, rsp
, out_buf_len
);
7628 case FSCTL_REQUEST_RESUME_KEY
:
7629 if (out_buf_len
< sizeof(struct resume_key_ioctl_rsp
)) {
7634 ret
= fsctl_request_resume_key(work
, req
,
7635 (struct resume_key_ioctl_rsp
*)&rsp
->Buffer
[0]);
7638 rsp
->PersistentFileId
= req
->PersistentFileId
;
7639 rsp
->VolatileFileId
= req
->VolatileFileId
;
7640 nbytes
= sizeof(struct resume_key_ioctl_rsp
);
7642 case FSCTL_COPYCHUNK
:
7643 case FSCTL_COPYCHUNK_WRITE
:
7644 if (!test_tree_conn_flag(work
->tcon
, KSMBD_TREE_CONN_FLAG_WRITABLE
)) {
7646 "User does not have write permission\n");
7651 if (in_buf_len
< sizeof(struct copychunk_ioctl_req
)) {
7656 if (out_buf_len
< sizeof(struct copychunk_ioctl_rsp
)) {
7661 nbytes
= sizeof(struct copychunk_ioctl_rsp
);
7662 rsp
->VolatileFileId
= req
->VolatileFileId
;
7663 rsp
->PersistentFileId
= req
->PersistentFileId
;
7664 fsctl_copychunk(work
,
7665 (struct copychunk_ioctl_req
*)&req
->Buffer
[0],
7666 le32_to_cpu(req
->CntCode
),
7667 le32_to_cpu(req
->InputCount
),
7668 le64_to_cpu(req
->VolatileFileId
),
7669 le64_to_cpu(req
->PersistentFileId
),
7672 case FSCTL_SET_SPARSE
:
7673 if (in_buf_len
< sizeof(struct file_sparse
)) {
7678 ret
= fsctl_set_sparse(work
, id
,
7679 (struct file_sparse
*)&req
->Buffer
[0]);
7683 case FSCTL_SET_ZERO_DATA
:
7685 struct file_zero_data_information
*zero_data
;
7686 struct ksmbd_file
*fp
;
7687 loff_t off
, len
, bfz
;
7689 if (!test_tree_conn_flag(work
->tcon
, KSMBD_TREE_CONN_FLAG_WRITABLE
)) {
7691 "User does not have write permission\n");
7696 if (in_buf_len
< sizeof(struct file_zero_data_information
)) {
7702 (struct file_zero_data_information
*)&req
->Buffer
[0];
7704 off
= le64_to_cpu(zero_data
->FileOffset
);
7705 bfz
= le64_to_cpu(zero_data
->BeyondFinalZero
);
7713 fp
= ksmbd_lookup_fd_fast(work
, id
);
7719 ret
= ksmbd_vfs_zero_data(work
, fp
, off
, len
);
7720 ksmbd_fd_put(work
, fp
);
7726 case FSCTL_QUERY_ALLOCATED_RANGES
:
7727 if (in_buf_len
< sizeof(struct file_allocated_range_buffer
)) {
7732 ret
= fsctl_query_allocated_ranges(work
, id
,
7733 (struct file_allocated_range_buffer
*)&req
->Buffer
[0],
7734 (struct file_allocated_range_buffer
*)&rsp
->Buffer
[0],
7736 sizeof(struct file_allocated_range_buffer
), &nbytes
);
7737 if (ret
== -E2BIG
) {
7738 rsp
->hdr
.Status
= STATUS_BUFFER_OVERFLOW
;
7739 } else if (ret
< 0) {
7744 nbytes
*= sizeof(struct file_allocated_range_buffer
);
7746 case FSCTL_GET_REPARSE_POINT
:
7748 struct reparse_data_buffer
*reparse_ptr
;
7749 struct ksmbd_file
*fp
;
7751 reparse_ptr
= (struct reparse_data_buffer
*)&rsp
->Buffer
[0];
7752 fp
= ksmbd_lookup_fd_fast(work
, id
);
7754 pr_err("not found fp!!\n");
7759 reparse_ptr
->ReparseTag
=
7760 smb2_get_reparse_tag_special_file(file_inode(fp
->filp
)->i_mode
);
7761 reparse_ptr
->ReparseDataLength
= 0;
7762 ksmbd_fd_put(work
, fp
);
7763 nbytes
= sizeof(struct reparse_data_buffer
);
7766 case FSCTL_DUPLICATE_EXTENTS_TO_FILE
:
7768 struct ksmbd_file
*fp_in
, *fp_out
= NULL
;
7769 struct duplicate_extents_to_file
*dup_ext
;
7770 loff_t src_off
, dst_off
, length
, cloned
;
7772 if (in_buf_len
< sizeof(struct duplicate_extents_to_file
)) {
7777 dup_ext
= (struct duplicate_extents_to_file
*)&req
->Buffer
[0];
7779 fp_in
= ksmbd_lookup_fd_slow(work
, dup_ext
->VolatileFileHandle
,
7780 dup_ext
->PersistentFileHandle
);
7782 pr_err("not found file handle in duplicate extent to file\n");
7787 fp_out
= ksmbd_lookup_fd_fast(work
, id
);
7789 pr_err("not found fp\n");
7794 src_off
= le64_to_cpu(dup_ext
->SourceFileOffset
);
7795 dst_off
= le64_to_cpu(dup_ext
->TargetFileOffset
);
7796 length
= le64_to_cpu(dup_ext
->ByteCount
);
7798 * XXX: It is not clear if FSCTL_DUPLICATE_EXTENTS_TO_FILE
7799 * should fall back to vfs_copy_file_range(). This could be
7800 * beneficial when re-exporting nfs/smb mount, but note that
7801 * this can result in partial copy that returns an error status.
7802 * If/when FSCTL_DUPLICATE_EXTENTS_TO_FILE_EX is implemented,
7803 * fall back to vfs_copy_file_range(), should be avoided when
7804 * the flag DUPLICATE_EXTENTS_DATA_EX_SOURCE_ATOMIC is set.
7806 cloned
= vfs_clone_file_range(fp_in
->filp
, src_off
,
7807 fp_out
->filp
, dst_off
, length
, 0);
7808 if (cloned
== -EXDEV
|| cloned
== -EOPNOTSUPP
) {
7811 } else if (cloned
!= length
) {
7812 cloned
= vfs_copy_file_range(fp_in
->filp
, src_off
,
7813 fp_out
->filp
, dst_off
,
7815 if (cloned
!= length
) {
7824 ksmbd_fd_put(work
, fp_in
);
7825 ksmbd_fd_put(work
, fp_out
);
7831 ksmbd_debug(SMB
, "not implemented yet ioctl command 0x%x\n",
7837 rsp
->CntCode
= cpu_to_le32(cnt_code
);
7838 rsp
->InputCount
= cpu_to_le32(0);
7839 rsp
->InputOffset
= cpu_to_le32(112);
7840 rsp
->OutputOffset
= cpu_to_le32(112);
7841 rsp
->OutputCount
= cpu_to_le32(nbytes
);
7842 rsp
->StructureSize
= cpu_to_le16(49);
7843 rsp
->Reserved
= cpu_to_le16(0);
7844 rsp
->Flags
= cpu_to_le32(0);
7845 rsp
->Reserved2
= cpu_to_le32(0);
7846 inc_rfc1001_len(rsp_org
, 48 + nbytes
);
7852 rsp
->hdr
.Status
= STATUS_ACCESS_DENIED
;
7853 else if (ret
== -ENOENT
)
7854 rsp
->hdr
.Status
= STATUS_OBJECT_NAME_NOT_FOUND
;
7855 else if (ret
== -EOPNOTSUPP
)
7856 rsp
->hdr
.Status
= STATUS_NOT_SUPPORTED
;
7857 else if (ret
== -ENOSPC
)
7858 rsp
->hdr
.Status
= STATUS_BUFFER_TOO_SMALL
;
7859 else if (ret
< 0 || rsp
->hdr
.Status
== 0)
7860 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
7861 smb2_set_err_rsp(work
);
7866 * smb20_oplock_break_ack() - handler for smb2.0 oplock break command
7867 * @work: smb work containing oplock break command buffer
7871 static void smb20_oplock_break_ack(struct ksmbd_work
*work
)
7873 struct smb2_oplock_break
*req
= work
->request_buf
;
7874 struct smb2_oplock_break
*rsp
= work
->response_buf
;
7875 struct ksmbd_file
*fp
;
7876 struct oplock_info
*opinfo
= NULL
;
7879 u64 volatile_id
, persistent_id
;
7880 char req_oplevel
= 0, rsp_oplevel
= 0;
7881 unsigned int oplock_change_type
;
7883 volatile_id
= le64_to_cpu(req
->VolatileFid
);
7884 persistent_id
= le64_to_cpu(req
->PersistentFid
);
7885 req_oplevel
= req
->OplockLevel
;
7886 ksmbd_debug(OPLOCK
, "v_id %llu, p_id %llu request oplock level %d\n",
7887 volatile_id
, persistent_id
, req_oplevel
);
7889 fp
= ksmbd_lookup_fd_slow(work
, volatile_id
, persistent_id
);
7891 rsp
->hdr
.Status
= STATUS_FILE_CLOSED
;
7892 smb2_set_err_rsp(work
);
7896 opinfo
= opinfo_get(fp
);
7898 pr_err("unexpected null oplock_info\n");
7899 rsp
->hdr
.Status
= STATUS_INVALID_OPLOCK_PROTOCOL
;
7900 smb2_set_err_rsp(work
);
7901 ksmbd_fd_put(work
, fp
);
7905 if (opinfo
->level
== SMB2_OPLOCK_LEVEL_NONE
) {
7906 rsp
->hdr
.Status
= STATUS_INVALID_OPLOCK_PROTOCOL
;
7910 if (opinfo
->op_state
== OPLOCK_STATE_NONE
) {
7911 ksmbd_debug(SMB
, "unexpected oplock state 0x%x\n", opinfo
->op_state
);
7912 rsp
->hdr
.Status
= STATUS_UNSUCCESSFUL
;
7916 if ((opinfo
->level
== SMB2_OPLOCK_LEVEL_EXCLUSIVE
||
7917 opinfo
->level
== SMB2_OPLOCK_LEVEL_BATCH
) &&
7918 (req_oplevel
!= SMB2_OPLOCK_LEVEL_II
&&
7919 req_oplevel
!= SMB2_OPLOCK_LEVEL_NONE
)) {
7920 err
= STATUS_INVALID_OPLOCK_PROTOCOL
;
7921 oplock_change_type
= OPLOCK_WRITE_TO_NONE
;
7922 } else if (opinfo
->level
== SMB2_OPLOCK_LEVEL_II
&&
7923 req_oplevel
!= SMB2_OPLOCK_LEVEL_NONE
) {
7924 err
= STATUS_INVALID_OPLOCK_PROTOCOL
;
7925 oplock_change_type
= OPLOCK_READ_TO_NONE
;
7926 } else if (req_oplevel
== SMB2_OPLOCK_LEVEL_II
||
7927 req_oplevel
== SMB2_OPLOCK_LEVEL_NONE
) {
7928 err
= STATUS_INVALID_DEVICE_STATE
;
7929 if ((opinfo
->level
== SMB2_OPLOCK_LEVEL_EXCLUSIVE
||
7930 opinfo
->level
== SMB2_OPLOCK_LEVEL_BATCH
) &&
7931 req_oplevel
== SMB2_OPLOCK_LEVEL_II
) {
7932 oplock_change_type
= OPLOCK_WRITE_TO_READ
;
7933 } else if ((opinfo
->level
== SMB2_OPLOCK_LEVEL_EXCLUSIVE
||
7934 opinfo
->level
== SMB2_OPLOCK_LEVEL_BATCH
) &&
7935 req_oplevel
== SMB2_OPLOCK_LEVEL_NONE
) {
7936 oplock_change_type
= OPLOCK_WRITE_TO_NONE
;
7937 } else if (opinfo
->level
== SMB2_OPLOCK_LEVEL_II
&&
7938 req_oplevel
== SMB2_OPLOCK_LEVEL_NONE
) {
7939 oplock_change_type
= OPLOCK_READ_TO_NONE
;
7941 oplock_change_type
= 0;
7944 oplock_change_type
= 0;
7947 switch (oplock_change_type
) {
7948 case OPLOCK_WRITE_TO_READ
:
7949 ret
= opinfo_write_to_read(opinfo
);
7950 rsp_oplevel
= SMB2_OPLOCK_LEVEL_II
;
7952 case OPLOCK_WRITE_TO_NONE
:
7953 ret
= opinfo_write_to_none(opinfo
);
7954 rsp_oplevel
= SMB2_OPLOCK_LEVEL_NONE
;
7956 case OPLOCK_READ_TO_NONE
:
7957 ret
= opinfo_read_to_none(opinfo
);
7958 rsp_oplevel
= SMB2_OPLOCK_LEVEL_NONE
;
7961 pr_err("unknown oplock change 0x%x -> 0x%x\n",
7962 opinfo
->level
, rsp_oplevel
);
7966 rsp
->hdr
.Status
= err
;
7971 ksmbd_fd_put(work
, fp
);
7972 opinfo
->op_state
= OPLOCK_STATE_NONE
;
7973 wake_up_interruptible_all(&opinfo
->oplock_q
);
7975 rsp
->StructureSize
= cpu_to_le16(24);
7976 rsp
->OplockLevel
= rsp_oplevel
;
7979 rsp
->VolatileFid
= cpu_to_le64(volatile_id
);
7980 rsp
->PersistentFid
= cpu_to_le64(persistent_id
);
7981 inc_rfc1001_len(rsp
, 24);
7985 opinfo
->op_state
= OPLOCK_STATE_NONE
;
7986 wake_up_interruptible_all(&opinfo
->oplock_q
);
7989 ksmbd_fd_put(work
, fp
);
7990 smb2_set_err_rsp(work
);
7993 static int check_lease_state(struct lease
*lease
, __le32 req_state
)
7995 if ((lease
->new_state
==
7996 (SMB2_LEASE_READ_CACHING_LE
| SMB2_LEASE_HANDLE_CACHING_LE
)) &&
7997 !(req_state
& SMB2_LEASE_WRITE_CACHING_LE
)) {
7998 lease
->new_state
= req_state
;
8002 if (lease
->new_state
== req_state
)
8009 * smb21_lease_break_ack() - handler for smb2.1 lease break command
8010 * @work: smb work containing lease break command buffer
8014 static void smb21_lease_break_ack(struct ksmbd_work
*work
)
8016 struct ksmbd_conn
*conn
= work
->conn
;
8017 struct smb2_lease_ack
*req
= work
->request_buf
;
8018 struct smb2_lease_ack
*rsp
= work
->response_buf
;
8019 struct oplock_info
*opinfo
;
8022 unsigned int lease_change_type
;
8024 struct lease
*lease
;
8026 ksmbd_debug(OPLOCK
, "smb21 lease break, lease state(0x%x)\n",
8027 le32_to_cpu(req
->LeaseState
));
8028 opinfo
= lookup_lease_in_table(conn
, req
->LeaseKey
);
8030 ksmbd_debug(OPLOCK
, "file not opened\n");
8031 smb2_set_err_rsp(work
);
8032 rsp
->hdr
.Status
= STATUS_UNSUCCESSFUL
;
8035 lease
= opinfo
->o_lease
;
8037 if (opinfo
->op_state
== OPLOCK_STATE_NONE
) {
8038 pr_err("unexpected lease break state 0x%x\n",
8040 rsp
->hdr
.Status
= STATUS_UNSUCCESSFUL
;
8044 if (check_lease_state(lease
, req
->LeaseState
)) {
8045 rsp
->hdr
.Status
= STATUS_REQUEST_NOT_ACCEPTED
;
8047 "req lease state: 0x%x, expected state: 0x%x\n",
8048 req
->LeaseState
, lease
->new_state
);
8052 if (!atomic_read(&opinfo
->breaking_cnt
)) {
8053 rsp
->hdr
.Status
= STATUS_UNSUCCESSFUL
;
8057 /* check for bad lease state */
8058 if (req
->LeaseState
&
8059 (~(SMB2_LEASE_READ_CACHING_LE
| SMB2_LEASE_HANDLE_CACHING_LE
))) {
8060 err
= STATUS_INVALID_OPLOCK_PROTOCOL
;
8061 if (lease
->state
& SMB2_LEASE_WRITE_CACHING_LE
)
8062 lease_change_type
= OPLOCK_WRITE_TO_NONE
;
8064 lease_change_type
= OPLOCK_READ_TO_NONE
;
8065 ksmbd_debug(OPLOCK
, "handle bad lease state 0x%x -> 0x%x\n",
8066 le32_to_cpu(lease
->state
),
8067 le32_to_cpu(req
->LeaseState
));
8068 } else if (lease
->state
== SMB2_LEASE_READ_CACHING_LE
&&
8069 req
->LeaseState
!= SMB2_LEASE_NONE_LE
) {
8070 err
= STATUS_INVALID_OPLOCK_PROTOCOL
;
8071 lease_change_type
= OPLOCK_READ_TO_NONE
;
8072 ksmbd_debug(OPLOCK
, "handle bad lease state 0x%x -> 0x%x\n",
8073 le32_to_cpu(lease
->state
),
8074 le32_to_cpu(req
->LeaseState
));
8076 /* valid lease state changes */
8077 err
= STATUS_INVALID_DEVICE_STATE
;
8078 if (req
->LeaseState
== SMB2_LEASE_NONE_LE
) {
8079 if (lease
->state
& SMB2_LEASE_WRITE_CACHING_LE
)
8080 lease_change_type
= OPLOCK_WRITE_TO_NONE
;
8082 lease_change_type
= OPLOCK_READ_TO_NONE
;
8083 } else if (req
->LeaseState
& SMB2_LEASE_READ_CACHING_LE
) {
8084 if (lease
->state
& SMB2_LEASE_WRITE_CACHING_LE
)
8085 lease_change_type
= OPLOCK_WRITE_TO_READ
;
8087 lease_change_type
= OPLOCK_READ_HANDLE_TO_READ
;
8089 lease_change_type
= 0;
8093 switch (lease_change_type
) {
8094 case OPLOCK_WRITE_TO_READ
:
8095 ret
= opinfo_write_to_read(opinfo
);
8097 case OPLOCK_READ_HANDLE_TO_READ
:
8098 ret
= opinfo_read_handle_to_read(opinfo
);
8100 case OPLOCK_WRITE_TO_NONE
:
8101 ret
= opinfo_write_to_none(opinfo
);
8103 case OPLOCK_READ_TO_NONE
:
8104 ret
= opinfo_read_to_none(opinfo
);
8107 ksmbd_debug(OPLOCK
, "unknown lease change 0x%x -> 0x%x\n",
8108 le32_to_cpu(lease
->state
),
8109 le32_to_cpu(req
->LeaseState
));
8112 lease_state
= lease
->state
;
8113 opinfo
->op_state
= OPLOCK_STATE_NONE
;
8114 wake_up_interruptible_all(&opinfo
->oplock_q
);
8115 atomic_dec(&opinfo
->breaking_cnt
);
8116 wake_up_interruptible_all(&opinfo
->oplock_brk
);
8120 rsp
->hdr
.Status
= err
;
8124 rsp
->StructureSize
= cpu_to_le16(36);
8127 memcpy(rsp
->LeaseKey
, req
->LeaseKey
, 16);
8128 rsp
->LeaseState
= lease_state
;
8129 rsp
->LeaseDuration
= 0;
8130 inc_rfc1001_len(rsp
, 36);
8134 opinfo
->op_state
= OPLOCK_STATE_NONE
;
8135 wake_up_interruptible_all(&opinfo
->oplock_q
);
8136 atomic_dec(&opinfo
->breaking_cnt
);
8137 wake_up_interruptible_all(&opinfo
->oplock_brk
);
8140 smb2_set_err_rsp(work
);
8144 * smb2_oplock_break() - dispatcher for smb2.0 and 2.1 oplock/lease break
8145 * @work: smb work containing oplock/lease break command buffer
8149 int smb2_oplock_break(struct ksmbd_work
*work
)
8151 struct smb2_oplock_break
*req
= work
->request_buf
;
8152 struct smb2_oplock_break
*rsp
= work
->response_buf
;
8154 switch (le16_to_cpu(req
->StructureSize
)) {
8155 case OP_BREAK_STRUCT_SIZE_20
:
8156 smb20_oplock_break_ack(work
);
8158 case OP_BREAK_STRUCT_SIZE_21
:
8159 smb21_lease_break_ack(work
);
8162 ksmbd_debug(OPLOCK
, "invalid break cmd %d\n",
8163 le16_to_cpu(req
->StructureSize
));
8164 rsp
->hdr
.Status
= STATUS_INVALID_PARAMETER
;
8165 smb2_set_err_rsp(work
);
8172 * smb2_notify() - handler for smb2 notify request
8173 * @work: smb work containing notify command buffer
8177 int smb2_notify(struct ksmbd_work
*work
)
8179 struct smb2_notify_req
*req
;
8180 struct smb2_notify_rsp
*rsp
;
8182 WORK_BUFFERS(work
, req
, rsp
);
8184 if (work
->next_smb2_rcv_hdr_off
&& req
->hdr
.NextCommand
) {
8185 rsp
->hdr
.Status
= STATUS_INTERNAL_ERROR
;
8186 smb2_set_err_rsp(work
);
8190 smb2_set_err_rsp(work
);
8191 rsp
->hdr
.Status
= STATUS_NOT_IMPLEMENTED
;
8196 * smb2_is_sign_req() - handler for checking packet signing status
8197 * @work: smb work containing notify command buffer
8198 * @command: SMB2 command id
8200 * Return: true if packed is signed, false otherwise
8202 bool smb2_is_sign_req(struct ksmbd_work
*work
, unsigned int command
)
8204 struct smb2_hdr
*rcv_hdr2
= work
->request_buf
;
8206 if ((rcv_hdr2
->Flags
& SMB2_FLAGS_SIGNED
) &&
8207 command
!= SMB2_NEGOTIATE_HE
&&
8208 command
!= SMB2_SESSION_SETUP_HE
&&
8209 command
!= SMB2_OPLOCK_BREAK_HE
)
8216 * smb2_check_sign_req() - handler for req packet sign processing
8217 * @work: smb work containing notify command buffer
8219 * Return: 1 on success, 0 otherwise
8221 int smb2_check_sign_req(struct ksmbd_work
*work
)
8223 struct smb2_hdr
*hdr
, *hdr_org
;
8224 char signature_req
[SMB2_SIGNATURE_SIZE
];
8225 char signature
[SMB2_HMACSHA256_SIZE
];
8229 hdr_org
= hdr
= work
->request_buf
;
8230 if (work
->next_smb2_rcv_hdr_off
)
8231 hdr
= ksmbd_req_buf_next(work
);
8233 if (!hdr
->NextCommand
&& !work
->next_smb2_rcv_hdr_off
)
8234 len
= be32_to_cpu(hdr_org
->smb2_buf_length
);
8235 else if (hdr
->NextCommand
)
8236 len
= le32_to_cpu(hdr
->NextCommand
);
8238 len
= be32_to_cpu(hdr_org
->smb2_buf_length
) -
8239 work
->next_smb2_rcv_hdr_off
;
8241 memcpy(signature_req
, hdr
->Signature
, SMB2_SIGNATURE_SIZE
);
8242 memset(hdr
->Signature
, 0, SMB2_SIGNATURE_SIZE
);
8244 iov
[0].iov_base
= (char *)&hdr
->ProtocolId
;
8245 iov
[0].iov_len
= len
;
8247 if (ksmbd_sign_smb2_pdu(work
->conn
, work
->sess
->sess_key
, iov
, 1,
8251 if (memcmp(signature
, signature_req
, SMB2_SIGNATURE_SIZE
)) {
8252 pr_err("bad smb2 signature\n");
8260 * smb2_set_sign_rsp() - handler for rsp packet sign processing
8261 * @work: smb work containing notify command buffer
8264 void smb2_set_sign_rsp(struct ksmbd_work
*work
)
8266 struct smb2_hdr
*hdr
, *hdr_org
;
8267 struct smb2_hdr
*req_hdr
;
8268 char signature
[SMB2_HMACSHA256_SIZE
];
8273 hdr_org
= hdr
= work
->response_buf
;
8274 if (work
->next_smb2_rsp_hdr_off
)
8275 hdr
= ksmbd_resp_buf_next(work
);
8277 req_hdr
= ksmbd_req_buf_next(work
);
8279 if (!work
->next_smb2_rsp_hdr_off
) {
8280 len
= get_rfc1002_len(hdr_org
);
8281 if (req_hdr
->NextCommand
)
8282 len
= ALIGN(len
, 8);
8284 len
= get_rfc1002_len(hdr_org
) - work
->next_smb2_rsp_hdr_off
;
8285 len
= ALIGN(len
, 8);
8288 if (req_hdr
->NextCommand
)
8289 hdr
->NextCommand
= cpu_to_le32(len
);
8291 hdr
->Flags
|= SMB2_FLAGS_SIGNED
;
8292 memset(hdr
->Signature
, 0, SMB2_SIGNATURE_SIZE
);
8294 iov
[0].iov_base
= (char *)&hdr
->ProtocolId
;
8295 iov
[0].iov_len
= len
;
8297 if (work
->aux_payload_sz
) {
8298 iov
[0].iov_len
-= work
->aux_payload_sz
;
8300 iov
[1].iov_base
= work
->aux_payload_buf
;
8301 iov
[1].iov_len
= work
->aux_payload_sz
;
8305 if (!ksmbd_sign_smb2_pdu(work
->conn
, work
->sess
->sess_key
, iov
, n_vec
,
8307 memcpy(hdr
->Signature
, signature
, SMB2_SIGNATURE_SIZE
);
8311 * smb3_check_sign_req() - handler for req packet sign processing
8312 * @work: smb work containing notify command buffer
8314 * Return: 1 on success, 0 otherwise
8316 int smb3_check_sign_req(struct ksmbd_work
*work
)
8318 struct ksmbd_conn
*conn
= work
->conn
;
8320 struct smb2_hdr
*hdr
, *hdr_org
;
8321 struct channel
*chann
;
8322 char signature_req
[SMB2_SIGNATURE_SIZE
];
8323 char signature
[SMB2_CMACAES_SIZE
];
8327 hdr_org
= hdr
= work
->request_buf
;
8328 if (work
->next_smb2_rcv_hdr_off
)
8329 hdr
= ksmbd_req_buf_next(work
);
8331 if (!hdr
->NextCommand
&& !work
->next_smb2_rcv_hdr_off
)
8332 len
= be32_to_cpu(hdr_org
->smb2_buf_length
);
8333 else if (hdr
->NextCommand
)
8334 len
= le32_to_cpu(hdr
->NextCommand
);
8336 len
= be32_to_cpu(hdr_org
->smb2_buf_length
) -
8337 work
->next_smb2_rcv_hdr_off
;
8339 if (le16_to_cpu(hdr
->Command
) == SMB2_SESSION_SETUP_HE
) {
8340 signing_key
= work
->sess
->smb3signingkey
;
8342 chann
= lookup_chann_list(work
->sess
, conn
);
8345 signing_key
= chann
->smb3signingkey
;
8349 pr_err("SMB3 signing key is not generated\n");
8353 memcpy(signature_req
, hdr
->Signature
, SMB2_SIGNATURE_SIZE
);
8354 memset(hdr
->Signature
, 0, SMB2_SIGNATURE_SIZE
);
8355 iov
[0].iov_base
= (char *)&hdr
->ProtocolId
;
8356 iov
[0].iov_len
= len
;
8358 if (ksmbd_sign_smb3_pdu(conn
, signing_key
, iov
, 1, signature
))
8361 if (memcmp(signature
, signature_req
, SMB2_SIGNATURE_SIZE
)) {
8362 pr_err("bad smb2 signature\n");
8370 * smb3_set_sign_rsp() - handler for rsp packet sign processing
8371 * @work: smb work containing notify command buffer
8374 void smb3_set_sign_rsp(struct ksmbd_work
*work
)
8376 struct ksmbd_conn
*conn
= work
->conn
;
8377 struct smb2_hdr
*req_hdr
;
8378 struct smb2_hdr
*hdr
, *hdr_org
;
8379 struct channel
*chann
;
8380 char signature
[SMB2_CMACAES_SIZE
];
8386 hdr_org
= hdr
= work
->response_buf
;
8387 if (work
->next_smb2_rsp_hdr_off
)
8388 hdr
= ksmbd_resp_buf_next(work
);
8390 req_hdr
= ksmbd_req_buf_next(work
);
8392 if (!work
->next_smb2_rsp_hdr_off
) {
8393 len
= get_rfc1002_len(hdr_org
);
8394 if (req_hdr
->NextCommand
)
8395 len
= ALIGN(len
, 8);
8397 len
= get_rfc1002_len(hdr_org
) - work
->next_smb2_rsp_hdr_off
;
8398 len
= ALIGN(len
, 8);
8401 if (conn
->binding
== false &&
8402 le16_to_cpu(hdr
->Command
) == SMB2_SESSION_SETUP_HE
) {
8403 signing_key
= work
->sess
->smb3signingkey
;
8405 chann
= lookup_chann_list(work
->sess
, work
->conn
);
8408 signing_key
= chann
->smb3signingkey
;
8414 if (req_hdr
->NextCommand
)
8415 hdr
->NextCommand
= cpu_to_le32(len
);
8417 hdr
->Flags
|= SMB2_FLAGS_SIGNED
;
8418 memset(hdr
->Signature
, 0, SMB2_SIGNATURE_SIZE
);
8419 iov
[0].iov_base
= (char *)&hdr
->ProtocolId
;
8420 iov
[0].iov_len
= len
;
8421 if (work
->aux_payload_sz
) {
8422 iov
[0].iov_len
-= work
->aux_payload_sz
;
8423 iov
[1].iov_base
= work
->aux_payload_buf
;
8424 iov
[1].iov_len
= work
->aux_payload_sz
;
8428 if (!ksmbd_sign_smb3_pdu(conn
, signing_key
, iov
, n_vec
, signature
))
8429 memcpy(hdr
->Signature
, signature
, SMB2_SIGNATURE_SIZE
);
8433 * smb3_preauth_hash_rsp() - handler for computing preauth hash on response
8434 * @work: smb work containing response buffer
8437 void smb3_preauth_hash_rsp(struct ksmbd_work
*work
)
8439 struct ksmbd_conn
*conn
= work
->conn
;
8440 struct ksmbd_session
*sess
= work
->sess
;
8441 struct smb2_hdr
*req
, *rsp
;
8443 if (conn
->dialect
!= SMB311_PROT_ID
)
8446 WORK_BUFFERS(work
, req
, rsp
);
8448 if (le16_to_cpu(req
->Command
) == SMB2_NEGOTIATE_HE
&&
8450 ksmbd_gen_preauth_integrity_hash(conn
, (char *)rsp
,
8451 conn
->preauth_info
->Preauth_HashValue
);
8453 if (le16_to_cpu(rsp
->Command
) == SMB2_SESSION_SETUP_HE
&& sess
) {
8456 if (conn
->binding
) {
8457 struct preauth_session
*preauth_sess
;
8459 preauth_sess
= ksmbd_preauth_session_lookup(conn
, sess
->id
);
8462 hash_value
= preauth_sess
->Preauth_HashValue
;
8464 hash_value
= sess
->Preauth_HashValue
;
8468 ksmbd_gen_preauth_integrity_hash(conn
, (char *)rsp
,
8473 static void fill_transform_hdr(struct smb2_transform_hdr
*tr_hdr
, char *old_buf
,
8476 struct smb2_hdr
*hdr
= (struct smb2_hdr
*)old_buf
;
8477 unsigned int orig_len
= get_rfc1002_len(old_buf
);
8479 memset(tr_hdr
, 0, sizeof(struct smb2_transform_hdr
));
8480 tr_hdr
->ProtocolId
= SMB2_TRANSFORM_PROTO_NUM
;
8481 tr_hdr
->OriginalMessageSize
= cpu_to_le32(orig_len
);
8482 tr_hdr
->Flags
= cpu_to_le16(0x01);
8483 if (cipher_type
== SMB2_ENCRYPTION_AES128_GCM
||
8484 cipher_type
== SMB2_ENCRYPTION_AES256_GCM
)
8485 get_random_bytes(&tr_hdr
->Nonce
, SMB3_AES_GCM_NONCE
);
8487 get_random_bytes(&tr_hdr
->Nonce
, SMB3_AES_CCM_NONCE
);
8488 memcpy(&tr_hdr
->SessionId
, &hdr
->SessionId
, 8);
8489 inc_rfc1001_len(tr_hdr
, sizeof(struct smb2_transform_hdr
) - 4);
8490 inc_rfc1001_len(tr_hdr
, orig_len
);
8493 int smb3_encrypt_resp(struct ksmbd_work
*work
)
8495 char *buf
= work
->response_buf
;
8496 struct smb2_transform_hdr
*tr_hdr
;
8499 int buf_size
= 0, rq_nvec
= 2 + (work
->aux_payload_sz
? 1 : 0);
8501 if (ARRAY_SIZE(iov
) < rq_nvec
)
8504 tr_hdr
= kzalloc(sizeof(struct smb2_transform_hdr
), GFP_KERNEL
);
8508 /* fill transform header */
8509 fill_transform_hdr(tr_hdr
, buf
, work
->conn
->cipher_type
);
8511 iov
[0].iov_base
= tr_hdr
;
8512 iov
[0].iov_len
= sizeof(struct smb2_transform_hdr
);
8513 buf_size
+= iov
[0].iov_len
- 4;
8515 iov
[1].iov_base
= buf
+ 4;
8516 iov
[1].iov_len
= get_rfc1002_len(buf
);
8517 if (work
->aux_payload_sz
) {
8518 iov
[1].iov_len
= work
->resp_hdr_sz
- 4;
8520 iov
[2].iov_base
= work
->aux_payload_buf
;
8521 iov
[2].iov_len
= work
->aux_payload_sz
;
8522 buf_size
+= iov
[2].iov_len
;
8524 buf_size
+= iov
[1].iov_len
;
8525 work
->resp_hdr_sz
= iov
[1].iov_len
;
8527 rc
= ksmbd_crypt_message(work
->conn
, iov
, rq_nvec
, 1);
8531 memmove(buf
, iov
[1].iov_base
, iov
[1].iov_len
);
8532 tr_hdr
->smb2_buf_length
= cpu_to_be32(buf_size
);
8533 work
->tr_buf
= tr_hdr
;
8538 bool smb3_is_transform_hdr(void *buf
)
8540 struct smb2_transform_hdr
*trhdr
= buf
;
8542 return trhdr
->ProtocolId
== SMB2_TRANSFORM_PROTO_NUM
;
8545 int smb3_decrypt_req(struct ksmbd_work
*work
)
8547 struct ksmbd_conn
*conn
= work
->conn
;
8548 struct ksmbd_session
*sess
;
8549 char *buf
= work
->request_buf
;
8550 struct smb2_hdr
*hdr
;
8551 unsigned int pdu_length
= get_rfc1002_len(buf
);
8553 int buf_data_size
= pdu_length
+ 4 -
8554 sizeof(struct smb2_transform_hdr
);
8555 struct smb2_transform_hdr
*tr_hdr
= (struct smb2_transform_hdr
*)buf
;
8558 if (buf_data_size
< sizeof(struct smb2_hdr
)) {
8559 pr_err("Transform message is too small (%u)\n",
8561 return -ECONNABORTED
;
8564 if (buf_data_size
< le32_to_cpu(tr_hdr
->OriginalMessageSize
)) {
8565 pr_err("Transform message is broken\n");
8566 return -ECONNABORTED
;
8569 sess
= ksmbd_session_lookup_all(conn
, le64_to_cpu(tr_hdr
->SessionId
));
8571 pr_err("invalid session id(%llx) in transform header\n",
8572 le64_to_cpu(tr_hdr
->SessionId
));
8573 return -ECONNABORTED
;
8576 iov
[0].iov_base
= buf
;
8577 iov
[0].iov_len
= sizeof(struct smb2_transform_hdr
);
8578 iov
[1].iov_base
= buf
+ sizeof(struct smb2_transform_hdr
);
8579 iov
[1].iov_len
= buf_data_size
;
8580 rc
= ksmbd_crypt_message(conn
, iov
, 2, 0);
8584 memmove(buf
+ 4, iov
[1].iov_base
, buf_data_size
);
8585 hdr
= (struct smb2_hdr
*)buf
;
8586 hdr
->smb2_buf_length
= cpu_to_be32(buf_data_size
);
8591 bool smb3_11_final_sess_setup_resp(struct ksmbd_work
*work
)
8593 struct ksmbd_conn
*conn
= work
->conn
;
8594 struct smb2_hdr
*rsp
= work
->response_buf
;
8596 if (conn
->dialect
< SMB30_PROT_ID
)
8599 if (work
->next_smb2_rcv_hdr_off
)
8600 rsp
= ksmbd_resp_buf_next(work
);
8602 if (le16_to_cpu(rsp
->Command
) == SMB2_SESSION_SETUP_HE
&&
8603 rsp
->Status
== STATUS_SUCCESS
)