smb2ops.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * Copyright (C) 2016 Namjae Jeon <linkinjeon@kernel.org>
  4. * Copyright (C) 2018 Samsung Electronics Co., Ltd.
  5. */
  6. #include <linux/slab.h>
  7. #include "glob.h"
  8. #include "auth.h"
  9. #include "connection.h"
  10. #include "smb_common.h"
  11. #include "server.h"
  12. static struct smb_version_values smb21_server_values = {
  13. .version_string = SMB21_VERSION_STRING,
  14. .protocol_id = SMB21_PROT_ID,
  15. .capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
  16. .max_read_size = SMB21_DEFAULT_IOSIZE,
  17. .max_write_size = SMB21_DEFAULT_IOSIZE,
  18. .max_trans_size = SMB21_DEFAULT_IOSIZE,
  19. .max_credits = SMB2_MAX_CREDITS,
  20. .large_lock_type = 0,
  21. .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE,
  22. .shared_lock_type = SMB2_LOCKFLAG_SHARED,
  23. .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
  24. .header_size = sizeof(struct smb2_hdr),
  25. .max_header_size = MAX_SMB2_HDR_SIZE,
  26. .read_rsp_size = sizeof(struct smb2_read_rsp),
  27. .lock_cmd = SMB2_LOCK,
  28. .cap_unix = 0,
  29. .cap_nt_find = SMB2_NT_FIND,
  30. .cap_large_files = SMB2_LARGE_FILES,
  31. .create_lease_size = sizeof(struct create_lease),
  32. .create_durable_size = sizeof(struct create_durable_rsp),
  33. .create_mxac_size = sizeof(struct create_mxac_rsp),
  34. .create_disk_id_size = sizeof(struct create_disk_id_rsp),
  35. .create_posix_size = sizeof(struct create_posix_rsp),
  36. };
  37. static struct smb_version_values smb30_server_values = {
  38. .version_string = SMB30_VERSION_STRING,
  39. .protocol_id = SMB30_PROT_ID,
  40. .capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
  41. .max_read_size = SMB3_DEFAULT_IOSIZE,
  42. .max_write_size = SMB3_DEFAULT_IOSIZE,
  43. .max_trans_size = SMB3_DEFAULT_TRANS_SIZE,
  44. .max_credits = SMB2_MAX_CREDITS,
  45. .large_lock_type = 0,
  46. .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE,
  47. .shared_lock_type = SMB2_LOCKFLAG_SHARED,
  48. .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
  49. .header_size = sizeof(struct smb2_hdr),
  50. .max_header_size = MAX_SMB2_HDR_SIZE,
  51. .read_rsp_size = sizeof(struct smb2_read_rsp),
  52. .lock_cmd = SMB2_LOCK,
  53. .cap_unix = 0,
  54. .cap_nt_find = SMB2_NT_FIND,
  55. .cap_large_files = SMB2_LARGE_FILES,
  56. .create_lease_size = sizeof(struct create_lease_v2),
  57. .create_durable_size = sizeof(struct create_durable_rsp),
  58. .create_durable_v2_size = sizeof(struct create_durable_v2_rsp),
  59. .create_mxac_size = sizeof(struct create_mxac_rsp),
  60. .create_disk_id_size = sizeof(struct create_disk_id_rsp),
  61. .create_posix_size = sizeof(struct create_posix_rsp),
  62. };
  63. static struct smb_version_values smb302_server_values = {
  64. .version_string = SMB302_VERSION_STRING,
  65. .protocol_id = SMB302_PROT_ID,
  66. .capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
  67. .max_read_size = SMB3_DEFAULT_IOSIZE,
  68. .max_write_size = SMB3_DEFAULT_IOSIZE,
  69. .max_trans_size = SMB3_DEFAULT_TRANS_SIZE,
  70. .max_credits = SMB2_MAX_CREDITS,
  71. .large_lock_type = 0,
  72. .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE,
  73. .shared_lock_type = SMB2_LOCKFLAG_SHARED,
  74. .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
  75. .header_size = sizeof(struct smb2_hdr),
  76. .max_header_size = MAX_SMB2_HDR_SIZE,
  77. .read_rsp_size = sizeof(struct smb2_read_rsp),
  78. .lock_cmd = SMB2_LOCK,
  79. .cap_unix = 0,
  80. .cap_nt_find = SMB2_NT_FIND,
  81. .cap_large_files = SMB2_LARGE_FILES,
  82. .create_lease_size = sizeof(struct create_lease_v2),
  83. .create_durable_size = sizeof(struct create_durable_rsp),
  84. .create_durable_v2_size = sizeof(struct create_durable_v2_rsp),
  85. .create_mxac_size = sizeof(struct create_mxac_rsp),
  86. .create_disk_id_size = sizeof(struct create_disk_id_rsp),
  87. .create_posix_size = sizeof(struct create_posix_rsp),
  88. };
  89. static struct smb_version_values smb311_server_values = {
  90. .version_string = SMB311_VERSION_STRING,
  91. .protocol_id = SMB311_PROT_ID,
  92. .capabilities = SMB2_GLOBAL_CAP_LARGE_MTU,
  93. .max_read_size = SMB3_DEFAULT_IOSIZE,
  94. .max_write_size = SMB3_DEFAULT_IOSIZE,
  95. .max_trans_size = SMB3_DEFAULT_TRANS_SIZE,
  96. .max_credits = SMB2_MAX_CREDITS,
  97. .large_lock_type = 0,
  98. .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE,
  99. .shared_lock_type = SMB2_LOCKFLAG_SHARED,
  100. .unlock_lock_type = SMB2_LOCKFLAG_UNLOCK,
  101. .header_size = sizeof(struct smb2_hdr),
  102. .max_header_size = MAX_SMB2_HDR_SIZE,
  103. .read_rsp_size = sizeof(struct smb2_read_rsp),
  104. .lock_cmd = SMB2_LOCK,
  105. .cap_unix = 0,
  106. .cap_nt_find = SMB2_NT_FIND,
  107. .cap_large_files = SMB2_LARGE_FILES,
  108. .create_lease_size = sizeof(struct create_lease_v2),
  109. .create_durable_size = sizeof(struct create_durable_rsp),
  110. .create_durable_v2_size = sizeof(struct create_durable_v2_rsp),
  111. .create_mxac_size = sizeof(struct create_mxac_rsp),
  112. .create_disk_id_size = sizeof(struct create_disk_id_rsp),
  113. .create_posix_size = sizeof(struct create_posix_rsp),
  114. };
  115. static struct smb_version_ops smb2_0_server_ops = {
  116. .get_cmd_val = get_smb2_cmd_val,
  117. .init_rsp_hdr = init_smb2_rsp_hdr,
  118. .set_rsp_status = set_smb2_rsp_status,
  119. .allocate_rsp_buf = smb2_allocate_rsp_buf,
  120. .set_rsp_credits = smb2_set_rsp_credits,
  121. .check_user_session = smb2_check_user_session,
  122. .get_ksmbd_tcon = smb2_get_ksmbd_tcon,
  123. .is_sign_req = smb2_is_sign_req,
  124. .check_sign_req = smb2_check_sign_req,
  125. .set_sign_rsp = smb2_set_sign_rsp
  126. };
  127. static struct smb_version_ops smb3_0_server_ops = {
  128. .get_cmd_val = get_smb2_cmd_val,
  129. .init_rsp_hdr = init_smb2_rsp_hdr,
  130. .set_rsp_status = set_smb2_rsp_status,
  131. .allocate_rsp_buf = smb2_allocate_rsp_buf,
  132. .set_rsp_credits = smb2_set_rsp_credits,
  133. .check_user_session = smb2_check_user_session,
  134. .get_ksmbd_tcon = smb2_get_ksmbd_tcon,
  135. .is_sign_req = smb2_is_sign_req,
  136. .check_sign_req = smb3_check_sign_req,
  137. .set_sign_rsp = smb3_set_sign_rsp,
  138. .generate_signingkey = ksmbd_gen_smb30_signingkey,
  139. .generate_encryptionkey = ksmbd_gen_smb30_encryptionkey,
  140. .is_transform_hdr = smb3_is_transform_hdr,
  141. .decrypt_req = smb3_decrypt_req,
  142. .encrypt_resp = smb3_encrypt_resp
  143. };
  144. static struct smb_version_ops smb3_11_server_ops = {
  145. .get_cmd_val = get_smb2_cmd_val,
  146. .init_rsp_hdr = init_smb2_rsp_hdr,
  147. .set_rsp_status = set_smb2_rsp_status,
  148. .allocate_rsp_buf = smb2_allocate_rsp_buf,
  149. .set_rsp_credits = smb2_set_rsp_credits,
  150. .check_user_session = smb2_check_user_session,
  151. .get_ksmbd_tcon = smb2_get_ksmbd_tcon,
  152. .is_sign_req = smb2_is_sign_req,
  153. .check_sign_req = smb3_check_sign_req,
  154. .set_sign_rsp = smb3_set_sign_rsp,
  155. .generate_signingkey = ksmbd_gen_smb311_signingkey,
  156. .generate_encryptionkey = ksmbd_gen_smb311_encryptionkey,
  157. .is_transform_hdr = smb3_is_transform_hdr,
  158. .decrypt_req = smb3_decrypt_req,
  159. .encrypt_resp = smb3_encrypt_resp
  160. };
  161. static struct smb_version_cmds smb2_0_server_cmds[NUMBER_OF_SMB2_COMMANDS] = {
  162. [SMB2_NEGOTIATE_HE] = { .proc = smb2_negotiate_request, },
  163. [SMB2_SESSION_SETUP_HE] = { .proc = smb2_sess_setup, },
  164. [SMB2_TREE_CONNECT_HE] = { .proc = smb2_tree_connect,},
  165. [SMB2_TREE_DISCONNECT_HE] = { .proc = smb2_tree_disconnect,},
  166. [SMB2_LOGOFF_HE] = { .proc = smb2_session_logoff,},
  167. [SMB2_CREATE_HE] = { .proc = smb2_open},
  168. [SMB2_QUERY_INFO_HE] = { .proc = smb2_query_info},
  169. [SMB2_QUERY_DIRECTORY_HE] = { .proc = smb2_query_dir},
  170. [SMB2_CLOSE_HE] = { .proc = smb2_close},
  171. [SMB2_ECHO_HE] = { .proc = smb2_echo},
  172. [SMB2_SET_INFO_HE] = { .proc = smb2_set_info},
  173. [SMB2_READ_HE] = { .proc = smb2_read},
  174. [SMB2_WRITE_HE] = { .proc = smb2_write},
  175. [SMB2_FLUSH_HE] = { .proc = smb2_flush},
  176. [SMB2_CANCEL_HE] = { .proc = smb2_cancel},
  177. [SMB2_LOCK_HE] = { .proc = smb2_lock},
  178. [SMB2_IOCTL_HE] = { .proc = smb2_ioctl},
  179. [SMB2_OPLOCK_BREAK_HE] = { .proc = smb2_oplock_break},
  180. [SMB2_CHANGE_NOTIFY_HE] = { .proc = smb2_notify},
  181. };
  182. /**
  183. * init_smb2_1_server() - initialize a smb server connection with smb2.1
  184. * command dispatcher
  185. * @conn: connection instance
  186. */
  187. void init_smb2_1_server(struct ksmbd_conn *conn)
  188. {
  189. conn->vals = &smb21_server_values;
  190. conn->ops = &smb2_0_server_ops;
  191. conn->cmds = smb2_0_server_cmds;
  192. conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds);
  193. conn->signing_algorithm = SIGNING_ALG_HMAC_SHA256_LE;
  194. if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
  195. conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING;
  196. }
  197. /**
  198. * init_smb3_0_server() - initialize a smb server connection with smb3.0
  199. * command dispatcher
  200. * @conn: connection instance
  201. */
  202. void init_smb3_0_server(struct ksmbd_conn *conn)
  203. {
  204. conn->vals = &smb30_server_values;
  205. conn->ops = &smb3_0_server_ops;
  206. conn->cmds = smb2_0_server_cmds;
  207. conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds);
  208. conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
  209. if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
  210. conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING |
  211. SMB2_GLOBAL_CAP_DIRECTORY_LEASING;
  212. if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION &&
  213. conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION)
  214. conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
  215. if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION ||
  216. (!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF) &&
  217. conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION))
  218. conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
  219. if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
  220. conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
  221. }
  222. /**
  223. * init_smb3_02_server() - initialize a smb server connection with smb3.02
  224. * command dispatcher
  225. * @conn: connection instance
  226. */
  227. void init_smb3_02_server(struct ksmbd_conn *conn)
  228. {
  229. conn->vals = &smb302_server_values;
  230. conn->ops = &smb3_0_server_ops;
  231. conn->cmds = smb2_0_server_cmds;
  232. conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds);
  233. conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
  234. if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
  235. conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING |
  236. SMB2_GLOBAL_CAP_DIRECTORY_LEASING;
  237. if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION ||
  238. (!(server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_ENCRYPTION_OFF) &&
  239. conn->cli_cap & SMB2_GLOBAL_CAP_ENCRYPTION))
  240. conn->vals->capabilities |= SMB2_GLOBAL_CAP_ENCRYPTION;
  241. if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
  242. conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
  243. if (server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE)
  244. conn->vals->capabilities |= SMB2_GLOBAL_CAP_PERSISTENT_HANDLES;
  245. }
  246. /**
  247. * init_smb3_11_server() - initialize a smb server connection with smb3.11
  248. * command dispatcher
  249. * @conn: connection instance
  250. */
  251. int init_smb3_11_server(struct ksmbd_conn *conn)
  252. {
  253. conn->vals = &smb311_server_values;
  254. conn->ops = &smb3_11_server_ops;
  255. conn->cmds = smb2_0_server_cmds;
  256. conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds);
  257. conn->signing_algorithm = SIGNING_ALG_AES_CMAC_LE;
  258. if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES)
  259. conn->vals->capabilities |= SMB2_GLOBAL_CAP_LEASING |
  260. SMB2_GLOBAL_CAP_DIRECTORY_LEASING;
  261. if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB3_MULTICHANNEL)
  262. conn->vals->capabilities |= SMB2_GLOBAL_CAP_MULTI_CHANNEL;
  263. if (server_conf.flags & KSMBD_GLOBAL_FLAG_DURABLE_HANDLE)
  264. conn->vals->capabilities |= SMB2_GLOBAL_CAP_PERSISTENT_HANDLES;
  265. INIT_LIST_HEAD(&conn->preauth_sess_table);
  266. return 0;
  267. }
  268. void init_smb2_max_read_size(unsigned int sz)
  269. {
  270. sz = clamp_val(sz, SMB3_MIN_IOSIZE, SMB3_MAX_IOSIZE);
  271. smb21_server_values.max_read_size = sz;
  272. smb30_server_values.max_read_size = sz;
  273. smb302_server_values.max_read_size = sz;
  274. smb311_server_values.max_read_size = sz;
  275. }
  276. void init_smb2_max_write_size(unsigned int sz)
  277. {
  278. sz = clamp_val(sz, SMB3_MIN_IOSIZE, SMB3_MAX_IOSIZE);
  279. smb21_server_values.max_write_size = sz;
  280. smb30_server_values.max_write_size = sz;
  281. smb302_server_values.max_write_size = sz;
  282. smb311_server_values.max_write_size = sz;
  283. }
  284. void init_smb2_max_trans_size(unsigned int sz)
  285. {
  286. sz = clamp_val(sz, SMB3_MIN_IOSIZE, SMB3_MAX_IOSIZE);
  287. smb21_server_values.max_trans_size = sz;
  288. smb30_server_values.max_trans_size = sz;
  289. smb302_server_values.max_trans_size = sz;
  290. smb311_server_values.max_trans_size = sz;
  291. }
  292. void init_smb2_max_credits(unsigned int sz)
  293. {
  294. smb21_server_values.max_credits = sz;
  295. smb30_server_values.max_credits = sz;
  296. smb302_server_values.max_credits = sz;
  297. smb311_server_values.max_credits = sz;
  298. }