0001
0002
0003
0004
0005
0006
0007 #include "smb_common.h"
0008 #include "server.h"
0009 #include "misc.h"
0010 #include "smbstatus.h"
0011 #include "connection.h"
0012 #include "ksmbd_work.h"
0013 #include "mgmt/user_session.h"
0014 #include "mgmt/user_config.h"
0015 #include "mgmt/tree_connect.h"
0016 #include "mgmt/share_config.h"
0017
0018
0019 static const char basechars[43] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_-!@#$%";
0020 #define MANGLE_BASE (sizeof(basechars) / sizeof(char) - 1)
0021 #define MAGIC_CHAR '~'
0022 #define PERIOD '.'
0023 #define mangle(V) ((char)(basechars[(V) % MANGLE_BASE]))
0024
0025 struct smb_protocol {
0026 int index;
0027 char *name;
0028 char *prot;
0029 __u16 prot_id;
0030 };
0031
0032 static struct smb_protocol smb1_protos[] = {
0033 {
0034 SMB21_PROT,
0035 "\2SMB 2.1",
0036 "SMB2_10",
0037 SMB21_PROT_ID
0038 },
0039 {
0040 SMB2X_PROT,
0041 "\2SMB 2.???",
0042 "SMB2_22",
0043 SMB2X_PROT_ID
0044 },
0045 };
0046
0047 static struct smb_protocol smb2_protos[] = {
0048 {
0049 SMB21_PROT,
0050 "\2SMB 2.1",
0051 "SMB2_10",
0052 SMB21_PROT_ID
0053 },
0054 {
0055 SMB30_PROT,
0056 "\2SMB 3.0",
0057 "SMB3_00",
0058 SMB30_PROT_ID
0059 },
0060 {
0061 SMB302_PROT,
0062 "\2SMB 3.02",
0063 "SMB3_02",
0064 SMB302_PROT_ID
0065 },
0066 {
0067 SMB311_PROT,
0068 "\2SMB 3.1.1",
0069 "SMB3_11",
0070 SMB311_PROT_ID
0071 },
0072 };
0073
0074 unsigned int ksmbd_server_side_copy_max_chunk_count(void)
0075 {
0076 return 256;
0077 }
0078
0079 unsigned int ksmbd_server_side_copy_max_chunk_size(void)
0080 {
0081 return (2U << 30) - 1;
0082 }
0083
0084 unsigned int ksmbd_server_side_copy_max_total_size(void)
0085 {
0086 return (2U << 30) - 1;
0087 }
0088
0089 inline int ksmbd_min_protocol(void)
0090 {
0091 return SMB21_PROT;
0092 }
0093
0094 inline int ksmbd_max_protocol(void)
0095 {
0096 return SMB311_PROT;
0097 }
0098
0099 int ksmbd_lookup_protocol_idx(char *str)
0100 {
0101 int offt = ARRAY_SIZE(smb1_protos) - 1;
0102 int len = strlen(str);
0103
0104 while (offt >= 0) {
0105 if (!strncmp(str, smb1_protos[offt].prot, len)) {
0106 ksmbd_debug(SMB, "selected %s dialect idx = %d\n",
0107 smb1_protos[offt].prot, offt);
0108 return smb1_protos[offt].index;
0109 }
0110 offt--;
0111 }
0112
0113 offt = ARRAY_SIZE(smb2_protos) - 1;
0114 while (offt >= 0) {
0115 if (!strncmp(str, smb2_protos[offt].prot, len)) {
0116 ksmbd_debug(SMB, "selected %s dialect idx = %d\n",
0117 smb2_protos[offt].prot, offt);
0118 return smb2_protos[offt].index;
0119 }
0120 offt--;
0121 }
0122 return -1;
0123 }
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133 int ksmbd_verify_smb_message(struct ksmbd_work *work)
0134 {
0135 struct smb2_hdr *smb2_hdr = ksmbd_req_buf_next(work);
0136 struct smb_hdr *hdr;
0137
0138 if (smb2_hdr->ProtocolId == SMB2_PROTO_NUMBER)
0139 return ksmbd_smb2_check_message(work);
0140
0141 hdr = work->request_buf;
0142 if (*(__le32 *)hdr->Protocol == SMB1_PROTO_NUMBER &&
0143 hdr->Command == SMB_COM_NEGOTIATE) {
0144 work->conn->outstanding_credits++;
0145 return 0;
0146 }
0147
0148 return -EINVAL;
0149 }
0150
0151
0152
0153
0154
0155
0156
0157 bool ksmbd_smb_request(struct ksmbd_conn *conn)
0158 {
0159 return conn->request_buf[0] == 0;
0160 }
0161
0162 static bool supported_protocol(int idx)
0163 {
0164 if (idx == SMB2X_PROT &&
0165 (server_conf.min_protocol >= SMB21_PROT ||
0166 server_conf.max_protocol <= SMB311_PROT))
0167 return true;
0168
0169 return (server_conf.min_protocol <= idx &&
0170 idx <= server_conf.max_protocol);
0171 }
0172
0173 static char *next_dialect(char *dialect, int *next_off, int bcount)
0174 {
0175 dialect = dialect + *next_off;
0176 *next_off = strnlen(dialect, bcount);
0177 if (dialect[*next_off] != '\0')
0178 return NULL;
0179 return dialect;
0180 }
0181
0182 static int ksmbd_lookup_dialect_by_name(char *cli_dialects, __le16 byte_count)
0183 {
0184 int i, seq_num, bcount, next;
0185 char *dialect;
0186
0187 for (i = ARRAY_SIZE(smb1_protos) - 1; i >= 0; i--) {
0188 seq_num = 0;
0189 next = 0;
0190 dialect = cli_dialects;
0191 bcount = le16_to_cpu(byte_count);
0192 do {
0193 dialect = next_dialect(dialect, &next, bcount);
0194 if (!dialect)
0195 break;
0196 ksmbd_debug(SMB, "client requested dialect %s\n",
0197 dialect);
0198 if (!strcmp(dialect, smb1_protos[i].name)) {
0199 if (supported_protocol(smb1_protos[i].index)) {
0200 ksmbd_debug(SMB,
0201 "selected %s dialect\n",
0202 smb1_protos[i].name);
0203 if (smb1_protos[i].index == SMB1_PROT)
0204 return seq_num;
0205 return smb1_protos[i].prot_id;
0206 }
0207 }
0208 seq_num++;
0209 bcount -= (++next);
0210 } while (bcount > 0);
0211 }
0212
0213 return BAD_PROT_ID;
0214 }
0215
0216 int ksmbd_lookup_dialect_by_id(__le16 *cli_dialects, __le16 dialects_count)
0217 {
0218 int i;
0219 int count;
0220
0221 for (i = ARRAY_SIZE(smb2_protos) - 1; i >= 0; i--) {
0222 count = le16_to_cpu(dialects_count);
0223 while (--count >= 0) {
0224 ksmbd_debug(SMB, "client requested dialect 0x%x\n",
0225 le16_to_cpu(cli_dialects[count]));
0226 if (le16_to_cpu(cli_dialects[count]) !=
0227 smb2_protos[i].prot_id)
0228 continue;
0229
0230 if (supported_protocol(smb2_protos[i].index)) {
0231 ksmbd_debug(SMB, "selected %s dialect\n",
0232 smb2_protos[i].name);
0233 return smb2_protos[i].prot_id;
0234 }
0235 }
0236 }
0237
0238 return BAD_PROT_ID;
0239 }
0240
0241 static int ksmbd_negotiate_smb_dialect(void *buf)
0242 {
0243 int smb_buf_length = get_rfc1002_len(buf);
0244 __le32 proto = ((struct smb2_hdr *)smb2_get_msg(buf))->ProtocolId;
0245
0246 if (proto == SMB2_PROTO_NUMBER) {
0247 struct smb2_negotiate_req *req;
0248 int smb2_neg_size =
0249 offsetof(struct smb2_negotiate_req, Dialects);
0250
0251 req = (struct smb2_negotiate_req *)smb2_get_msg(buf);
0252 if (smb2_neg_size > smb_buf_length)
0253 goto err_out;
0254
0255 if (smb2_neg_size + le16_to_cpu(req->DialectCount) * sizeof(__le16) >
0256 smb_buf_length)
0257 goto err_out;
0258
0259 return ksmbd_lookup_dialect_by_id(req->Dialects,
0260 req->DialectCount);
0261 }
0262
0263 proto = *(__le32 *)((struct smb_hdr *)buf)->Protocol;
0264 if (proto == SMB1_PROTO_NUMBER) {
0265 struct smb_negotiate_req *req;
0266
0267 req = (struct smb_negotiate_req *)buf;
0268 if (le16_to_cpu(req->ByteCount) < 2)
0269 goto err_out;
0270
0271 if (offsetof(struct smb_negotiate_req, DialectsArray) - 4 +
0272 le16_to_cpu(req->ByteCount) > smb_buf_length) {
0273 goto err_out;
0274 }
0275
0276 return ksmbd_lookup_dialect_by_name(req->DialectsArray,
0277 req->ByteCount);
0278 }
0279
0280 err_out:
0281 return BAD_PROT_ID;
0282 }
0283
0284 int ksmbd_init_smb_server(struct ksmbd_work *work)
0285 {
0286 struct ksmbd_conn *conn = work->conn;
0287
0288 if (conn->need_neg == false)
0289 return 0;
0290
0291 init_smb3_11_server(conn);
0292
0293 if (conn->ops->get_cmd_val(work) != SMB_COM_NEGOTIATE)
0294 conn->need_neg = false;
0295 return 0;
0296 }
0297
0298 int ksmbd_populate_dot_dotdot_entries(struct ksmbd_work *work, int info_level,
0299 struct ksmbd_file *dir,
0300 struct ksmbd_dir_info *d_info,
0301 char *search_pattern,
0302 int (*fn)(struct ksmbd_conn *, int,
0303 struct ksmbd_dir_info *,
0304 struct ksmbd_kstat *))
0305 {
0306 int i, rc = 0;
0307 struct ksmbd_conn *conn = work->conn;
0308 struct user_namespace *user_ns = file_mnt_user_ns(dir->filp);
0309
0310 for (i = 0; i < 2; i++) {
0311 struct kstat kstat;
0312 struct ksmbd_kstat ksmbd_kstat;
0313 struct dentry *dentry;
0314
0315 if (!dir->dot_dotdot[i]) {
0316 if (i == 0) {
0317 d_info->name = ".";
0318 d_info->name_len = 1;
0319 dentry = dir->filp->f_path.dentry;
0320 } else {
0321 d_info->name = "..";
0322 d_info->name_len = 2;
0323 dentry = dir->filp->f_path.dentry->d_parent;
0324 }
0325
0326 if (!match_pattern(d_info->name, d_info->name_len,
0327 search_pattern)) {
0328 dir->dot_dotdot[i] = 1;
0329 continue;
0330 }
0331
0332 ksmbd_kstat.kstat = &kstat;
0333 ksmbd_vfs_fill_dentry_attrs(work,
0334 user_ns,
0335 dentry,
0336 &ksmbd_kstat);
0337 rc = fn(conn, info_level, d_info, &ksmbd_kstat);
0338 if (rc)
0339 break;
0340 if (d_info->out_buf_len <= 0)
0341 break;
0342
0343 dir->dot_dotdot[i] = 1;
0344 if (d_info->flags & SMB2_RETURN_SINGLE_ENTRY) {
0345 d_info->out_buf_len = 0;
0346 break;
0347 }
0348 }
0349 }
0350
0351 return rc;
0352 }
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364 int ksmbd_extract_shortname(struct ksmbd_conn *conn, const char *longname,
0365 char *shortname)
0366 {
0367 const char *p;
0368 char base[9], extension[4];
0369 char out[13] = {0};
0370 int baselen = 0;
0371 int extlen = 0, len = 0;
0372 unsigned int csum = 0;
0373 const unsigned char *ptr;
0374 bool dot_present = true;
0375
0376 p = longname;
0377 if ((*p == '.') || (!(strcmp(p, "..")))) {
0378
0379 return 0;
0380 }
0381
0382 p = strrchr(longname, '.');
0383 if (p == longname) {
0384 strscpy(extension, "___", strlen("___"));
0385 } else {
0386 if (p) {
0387 p++;
0388 while (*p && extlen < 3) {
0389 if (*p != '.')
0390 extension[extlen++] = toupper(*p);
0391 p++;
0392 }
0393 extension[extlen] = '\0';
0394 } else {
0395 dot_present = false;
0396 }
0397 }
0398
0399 p = longname;
0400 if (*p == '.') {
0401 p++;
0402 longname++;
0403 }
0404 while (*p && (baselen < 5)) {
0405 if (*p != '.')
0406 base[baselen++] = toupper(*p);
0407 p++;
0408 }
0409
0410 base[baselen] = MAGIC_CHAR;
0411 memcpy(out, base, baselen + 1);
0412
0413 ptr = longname;
0414 len = strlen(longname);
0415 for (; len > 0; len--, ptr++)
0416 csum += *ptr;
0417
0418 csum = csum % (MANGLE_BASE * MANGLE_BASE);
0419 out[baselen + 1] = mangle(csum / MANGLE_BASE);
0420 out[baselen + 2] = mangle(csum);
0421 out[baselen + 3] = PERIOD;
0422
0423 if (dot_present)
0424 memcpy(&out[baselen + 4], extension, 4);
0425 else
0426 out[baselen + 4] = '\0';
0427 smbConvertToUTF16((__le16 *)shortname, out, PATH_MAX,
0428 conn->local_nls, 0);
0429 len = strlen(out) * 2;
0430 return len;
0431 }
0432
0433 static int __smb2_negotiate(struct ksmbd_conn *conn)
0434 {
0435 return (conn->dialect >= SMB21_PROT_ID &&
0436 conn->dialect <= SMB311_PROT_ID);
0437 }
0438
0439 static int smb_handle_negotiate(struct ksmbd_work *work)
0440 {
0441 struct smb_negotiate_rsp *neg_rsp = work->response_buf;
0442
0443 ksmbd_debug(SMB, "Unsupported SMB protocol\n");
0444 neg_rsp->hdr.Status.CifsError = STATUS_INVALID_LOGON_TYPE;
0445 return -EINVAL;
0446 }
0447
0448 int ksmbd_smb_negotiate_common(struct ksmbd_work *work, unsigned int command)
0449 {
0450 struct ksmbd_conn *conn = work->conn;
0451 int ret;
0452
0453 conn->dialect =
0454 ksmbd_negotiate_smb_dialect(work->request_buf);
0455 ksmbd_debug(SMB, "conn->dialect 0x%x\n", conn->dialect);
0456
0457 if (command == SMB2_NEGOTIATE_HE) {
0458 struct smb2_hdr *smb2_hdr = smb2_get_msg(work->request_buf);
0459
0460 if (smb2_hdr->ProtocolId != SMB2_PROTO_NUMBER) {
0461 ksmbd_debug(SMB, "Downgrade to SMB1 negotiation\n");
0462 command = SMB_COM_NEGOTIATE;
0463 }
0464 }
0465
0466 if (command == SMB2_NEGOTIATE_HE && __smb2_negotiate(conn)) {
0467 ret = smb2_handle_negotiate(work);
0468 init_smb2_neg_rsp(work);
0469 return ret;
0470 }
0471
0472 if (command == SMB_COM_NEGOTIATE) {
0473 if (__smb2_negotiate(conn)) {
0474 conn->need_neg = true;
0475 init_smb3_11_server(conn);
0476 init_smb2_neg_rsp(work);
0477 ksmbd_debug(SMB, "Upgrade to SMB2 negotiation\n");
0478 return 0;
0479 }
0480 return smb_handle_negotiate(work);
0481 }
0482
0483 pr_err("Unknown SMB negotiation command: %u\n", command);
0484 return -EINVAL;
0485 }
0486
0487 enum SHARED_MODE_ERRORS {
0488 SHARE_DELETE_ERROR,
0489 SHARE_READ_ERROR,
0490 SHARE_WRITE_ERROR,
0491 FILE_READ_ERROR,
0492 FILE_WRITE_ERROR,
0493 FILE_DELETE_ERROR,
0494 };
0495
0496 static const char * const shared_mode_errors[] = {
0497 "Current access mode does not permit SHARE_DELETE",
0498 "Current access mode does not permit SHARE_READ",
0499 "Current access mode does not permit SHARE_WRITE",
0500 "Desired access mode does not permit FILE_READ",
0501 "Desired access mode does not permit FILE_WRITE",
0502 "Desired access mode does not permit FILE_DELETE",
0503 };
0504
0505 static void smb_shared_mode_error(int error, struct ksmbd_file *prev_fp,
0506 struct ksmbd_file *curr_fp)
0507 {
0508 ksmbd_debug(SMB, "%s\n", shared_mode_errors[error]);
0509 ksmbd_debug(SMB, "Current mode: 0x%x Desired mode: 0x%x\n",
0510 prev_fp->saccess, curr_fp->daccess);
0511 }
0512
0513 int ksmbd_smb_check_shared_mode(struct file *filp, struct ksmbd_file *curr_fp)
0514 {
0515 int rc = 0;
0516 struct ksmbd_file *prev_fp;
0517
0518
0519
0520
0521
0522 read_lock(&curr_fp->f_ci->m_lock);
0523 list_for_each_entry(prev_fp, &curr_fp->f_ci->m_fp_list, node) {
0524 if (file_inode(filp) != file_inode(prev_fp->filp))
0525 continue;
0526
0527 if (filp == prev_fp->filp)
0528 continue;
0529
0530 if (ksmbd_stream_fd(prev_fp) && ksmbd_stream_fd(curr_fp))
0531 if (strcmp(prev_fp->stream.name, curr_fp->stream.name))
0532 continue;
0533
0534 if (prev_fp->attrib_only != curr_fp->attrib_only)
0535 continue;
0536
0537 if (!(prev_fp->saccess & FILE_SHARE_DELETE_LE) &&
0538 curr_fp->daccess & FILE_DELETE_LE) {
0539 smb_shared_mode_error(SHARE_DELETE_ERROR,
0540 prev_fp,
0541 curr_fp);
0542 rc = -EPERM;
0543 break;
0544 }
0545
0546
0547
0548
0549
0550 if (ksmbd_stream_fd(prev_fp) && !ksmbd_stream_fd(curr_fp))
0551 continue;
0552
0553 if (!(prev_fp->saccess & FILE_SHARE_READ_LE) &&
0554 curr_fp->daccess & (FILE_EXECUTE_LE | FILE_READ_DATA_LE)) {
0555 smb_shared_mode_error(SHARE_READ_ERROR,
0556 prev_fp,
0557 curr_fp);
0558 rc = -EPERM;
0559 break;
0560 }
0561
0562 if (!(prev_fp->saccess & FILE_SHARE_WRITE_LE) &&
0563 curr_fp->daccess & (FILE_WRITE_DATA_LE | FILE_APPEND_DATA_LE)) {
0564 smb_shared_mode_error(SHARE_WRITE_ERROR,
0565 prev_fp,
0566 curr_fp);
0567 rc = -EPERM;
0568 break;
0569 }
0570
0571 if (prev_fp->daccess & (FILE_EXECUTE_LE | FILE_READ_DATA_LE) &&
0572 !(curr_fp->saccess & FILE_SHARE_READ_LE)) {
0573 smb_shared_mode_error(FILE_READ_ERROR,
0574 prev_fp,
0575 curr_fp);
0576 rc = -EPERM;
0577 break;
0578 }
0579
0580 if (prev_fp->daccess & (FILE_WRITE_DATA_LE | FILE_APPEND_DATA_LE) &&
0581 !(curr_fp->saccess & FILE_SHARE_WRITE_LE)) {
0582 smb_shared_mode_error(FILE_WRITE_ERROR,
0583 prev_fp,
0584 curr_fp);
0585 rc = -EPERM;
0586 break;
0587 }
0588
0589 if (prev_fp->daccess & FILE_DELETE_LE &&
0590 !(curr_fp->saccess & FILE_SHARE_DELETE_LE)) {
0591 smb_shared_mode_error(FILE_DELETE_ERROR,
0592 prev_fp,
0593 curr_fp);
0594 rc = -EPERM;
0595 break;
0596 }
0597 }
0598 read_unlock(&curr_fp->f_ci->m_lock);
0599
0600 return rc;
0601 }
0602
0603 bool is_asterisk(char *p)
0604 {
0605 return p && p[0] == '*';
0606 }
0607
0608 int ksmbd_override_fsids(struct ksmbd_work *work)
0609 {
0610 struct ksmbd_session *sess = work->sess;
0611 struct ksmbd_share_config *share = work->tcon->share_conf;
0612 struct cred *cred;
0613 struct group_info *gi;
0614 unsigned int uid;
0615 unsigned int gid;
0616
0617 uid = user_uid(sess->user);
0618 gid = user_gid(sess->user);
0619 if (share->force_uid != KSMBD_SHARE_INVALID_UID)
0620 uid = share->force_uid;
0621 if (share->force_gid != KSMBD_SHARE_INVALID_GID)
0622 gid = share->force_gid;
0623
0624 cred = prepare_kernel_cred(NULL);
0625 if (!cred)
0626 return -ENOMEM;
0627
0628 cred->fsuid = make_kuid(current_user_ns(), uid);
0629 cred->fsgid = make_kgid(current_user_ns(), gid);
0630
0631 gi = groups_alloc(0);
0632 if (!gi) {
0633 abort_creds(cred);
0634 return -ENOMEM;
0635 }
0636 set_groups(cred, gi);
0637 put_group_info(gi);
0638
0639 if (!uid_eq(cred->fsuid, GLOBAL_ROOT_UID))
0640 cred->cap_effective = cap_drop_fs_set(cred->cap_effective);
0641
0642 WARN_ON(work->saved_cred);
0643 work->saved_cred = override_creds(cred);
0644 if (!work->saved_cred) {
0645 abort_creds(cred);
0646 return -EINVAL;
0647 }
0648 return 0;
0649 }
0650
0651 void ksmbd_revert_fsids(struct ksmbd_work *work)
0652 {
0653 const struct cred *cred;
0654
0655 WARN_ON(!work->saved_cred);
0656
0657 cred = current_cred();
0658 revert_creds(work->saved_cred);
0659 put_cred(cred);
0660 work->saved_cred = NULL;
0661 }
0662
0663 __le32 smb_map_generic_desired_access(__le32 daccess)
0664 {
0665 if (daccess & FILE_GENERIC_READ_LE) {
0666 daccess |= cpu_to_le32(GENERIC_READ_FLAGS);
0667 daccess &= ~FILE_GENERIC_READ_LE;
0668 }
0669
0670 if (daccess & FILE_GENERIC_WRITE_LE) {
0671 daccess |= cpu_to_le32(GENERIC_WRITE_FLAGS);
0672 daccess &= ~FILE_GENERIC_WRITE_LE;
0673 }
0674
0675 if (daccess & FILE_GENERIC_EXECUTE_LE) {
0676 daccess |= cpu_to_le32(GENERIC_EXECUTE_FLAGS);
0677 daccess &= ~FILE_GENERIC_EXECUTE_LE;
0678 }
0679
0680 if (daccess & FILE_GENERIC_ALL_LE) {
0681 daccess |= cpu_to_le32(GENERIC_ALL_FLAGS);
0682 daccess &= ~FILE_GENERIC_ALL_LE;
0683 }
0684
0685 return daccess;
0686 }