Skip to content

Commit

Permalink
Merge pull request #66 from namjaejeon/cifsd-for-next
Browse files Browse the repository at this point in the history
ksmbd-fixes
  • Loading branch information
smfrench authored Aug 20, 2021
2 parents 456af43 + a9a27d4 commit e7a10ed
Show file tree
Hide file tree
Showing 10 changed files with 128 additions and 85 deletions.
3 changes: 2 additions & 1 deletion Documentation/filesystems/cifs/ksmbd.rst
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ SMB3 encryption(CCM, GCM) Supported. (CCM and GCM128 supported, GCM256 in
progress)
SMB direct(RDMA) Partially Supported. SMB3 Multi-channel is
required to connect to Windows client.
SMB3 Multi-channel In Progress.
SMB3 Multi-channel Partially Supported. Planned to implement
replay/retry mechanisms for future.
SMB3.1.1 POSIX extension Supported.
ACLs Partially Supported. only DACLs available, SACLs
(auditing) is planned for the future. For
Expand Down
1 change: 1 addition & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -9945,6 +9945,7 @@ M: Steve French <[email protected]>
M: Hyunchul Lee <[email protected]>
L: [email protected]
S: Maintained
T: git git://git.samba.org/ksmbd.git
F: fs/ksmbd/

KERNEL UNIT TESTING FRAMEWORK (KUnit)
Expand Down
1 change: 0 additions & 1 deletion fs/ksmbd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ config SMB_SERVER
select CRYPTO_GCM
select ASN1
select OID_REGISTRY
select FS_POSIX_ACL
default n
help
Choose Y here if you want to allow SMB3 compliant clients
Expand Down
50 changes: 27 additions & 23 deletions fs/ksmbd/smb2pdu.c
Original file line number Diff line number Diff line change
Expand Up @@ -58,18 +58,18 @@ static void __wbuf(struct ksmbd_work *work, void **req, void **rsp)
*
* Return: 1 if valid session id, otherwise 0
*/
static inline int check_session_id(struct ksmbd_conn *conn, u64 id)
static inline bool check_session_id(struct ksmbd_conn *conn, u64 id)
{
struct ksmbd_session *sess;

if (id == 0 || id == -1)
return 0;
return false;

sess = ksmbd_session_lookup_all(conn, id);
if (sess)
return 1;
return true;
pr_err("Invalid user session id: %llu\n", id);
return 0;
return false;
}

struct channel *lookup_chann_list(struct ksmbd_session *sess, struct ksmbd_conn *conn)
Expand All @@ -85,10 +85,11 @@ struct channel *lookup_chann_list(struct ksmbd_session *sess, struct ksmbd_conn
}

/**
* smb2_get_ksmbd_tcon() - get tree connection information for a tree id
* smb2_get_ksmbd_tcon() - get tree connection information using a tree id.
* @work: smb work
*
* Return: matching tree connection on success, otherwise error
* Return: 0 if there is a tree connection matched or these are
* skipable commands, otherwise error
*/
int smb2_get_ksmbd_tcon(struct ksmbd_work *work)
{
Expand All @@ -105,14 +106,14 @@ int smb2_get_ksmbd_tcon(struct ksmbd_work *work)

if (xa_empty(&work->sess->tree_conns)) {
ksmbd_debug(SMB, "NO tree connected\n");
return -1;
return -ENOENT;
}

tree_id = le32_to_cpu(req_hdr->Id.SyncId.TreeId);
work->tcon = ksmbd_tree_conn_lookup(work->sess, tree_id);
if (!work->tcon) {
pr_err("Invalid tid %d\n", tree_id);
return -1;
return -EINVAL;
}

return 1;
Expand Down Expand Up @@ -145,45 +146,45 @@ void smb2_set_err_rsp(struct ksmbd_work *work)
* is_smb2_neg_cmd() - is it smb2 negotiation command
* @work: smb work containing smb header
*
* Return: 1 if smb2 negotiation command, otherwise 0
* Return: true if smb2 negotiation command, otherwise false
*/
int is_smb2_neg_cmd(struct ksmbd_work *work)
bool is_smb2_neg_cmd(struct ksmbd_work *work)
{
struct smb2_hdr *hdr = work->request_buf;

/* is it SMB2 header ? */
if (hdr->ProtocolId != SMB2_PROTO_NUMBER)
return 0;
return false;

/* make sure it is request not response message */
if (hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR)
return 0;
return false;

if (hdr->Command != SMB2_NEGOTIATE)
return 0;
return false;

return 1;
return true;
}

/**
* is_smb2_rsp() - is it smb2 response
* @work: smb work containing smb response buffer
*
* Return: 1 if smb2 response, otherwise 0
* Return: true if smb2 response, otherwise false
*/
int is_smb2_rsp(struct ksmbd_work *work)
bool is_smb2_rsp(struct ksmbd_work *work)
{
struct smb2_hdr *hdr = work->response_buf;

/* is it SMB2 header ? */
if (hdr->ProtocolId != SMB2_PROTO_NUMBER)
return 0;
return false;

/* make sure it is response not request message */
if (!(hdr->Flags & SMB2_FLAGS_SERVER_TO_REDIR))
return 0;
return false;

return 1;
return true;
}

/**
Expand Down Expand Up @@ -2385,11 +2386,14 @@ static void ksmbd_acls_fattr(struct smb_fattr *fattr, struct inode *inode)
fattr->cf_uid = inode->i_uid;
fattr->cf_gid = inode->i_gid;
fattr->cf_mode = inode->i_mode;
fattr->cf_acls = NULL;
fattr->cf_dacls = NULL;

fattr->cf_acls = get_acl(inode, ACL_TYPE_ACCESS);
if (S_ISDIR(inode->i_mode))
fattr->cf_dacls = get_acl(inode, ACL_TYPE_DEFAULT);
if (IS_ENABLED(CONFIG_FS_POSIX_ACL)) {
fattr->cf_acls = get_acl(inode, ACL_TYPE_ACCESS);
if (S_ISDIR(inode->i_mode))
fattr->cf_dacls = get_acl(inode, ACL_TYPE_DEFAULT);
}
}

/**
Expand Down Expand Up @@ -8291,7 +8295,7 @@ int smb3_encrypt_resp(struct ksmbd_work *work)
return rc;
}

int smb3_is_transform_hdr(void *buf)
bool smb3_is_transform_hdr(void *buf)
{
struct smb2_transform_hdr *trhdr = buf;

Expand Down
6 changes: 3 additions & 3 deletions fs/ksmbd/smb2pdu.h
Original file line number Diff line number Diff line change
Expand Up @@ -1638,8 +1638,8 @@ void init_smb2_max_read_size(unsigned int sz);
void init_smb2_max_write_size(unsigned int sz);
void init_smb2_max_trans_size(unsigned int sz);

int is_smb2_neg_cmd(struct ksmbd_work *work);
int is_smb2_rsp(struct ksmbd_work *work);
bool is_smb2_neg_cmd(struct ksmbd_work *work);
bool is_smb2_rsp(struct ksmbd_work *work);

u16 get_smb2_cmd_val(struct ksmbd_work *work);
void set_smb2_rsp_status(struct ksmbd_work *work, __le32 err);
Expand All @@ -1664,7 +1664,7 @@ void smb2_send_interim_resp(struct ksmbd_work *work, __le32 status);
struct channel *lookup_chann_list(struct ksmbd_session *sess,
struct ksmbd_conn *conn);
void smb3_preauth_hash_rsp(struct ksmbd_work *work);
int smb3_is_transform_hdr(void *buf);
bool smb3_is_transform_hdr(void *buf);
int smb3_decrypt_req(struct ksmbd_work *work);
int smb3_encrypt_resp(struct ksmbd_work *work);
bool smb3_11_final_sess_setup_resp(struct ksmbd_work *work);
Expand Down
53 changes: 36 additions & 17 deletions fs/ksmbd/smb_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ struct smb_protocol {
__u16 prot_id;
};

static struct smb_protocol smb_protos[] = {
static struct smb_protocol smb1_protos[] = {
{
SMB21_PROT,
"\2SMB 2.1",
Expand All @@ -43,6 +43,15 @@ static struct smb_protocol smb_protos[] = {
"SMB2_22",
SMB2X_PROT_ID
},
};

static struct smb_protocol smb2_protos[] = {
{
SMB21_PROT,
"\2SMB 2.1",
"SMB2_10",
SMB21_PROT_ID
},
{
SMB30_PROT,
"\2SMB 3.0",
Expand Down Expand Up @@ -90,14 +99,24 @@ inline int ksmbd_max_protocol(void)

int ksmbd_lookup_protocol_idx(char *str)
{
int offt = ARRAY_SIZE(smb_protos) - 1;
int offt = ARRAY_SIZE(smb1_protos) - 1;
int len = strlen(str);

while (offt >= 0) {
if (!strncmp(str, smb_protos[offt].prot, len)) {
if (!strncmp(str, smb1_protos[offt].prot, len)) {
ksmbd_debug(SMB, "selected %s dialect idx = %d\n",
smb1_protos[offt].prot, offt);
return smb1_protos[offt].index;
}
offt--;
}

offt = ARRAY_SIZE(smb2_protos) - 1;
while (offt >= 0) {
if (!strncmp(str, smb2_protos[offt].prot, len)) {
ksmbd_debug(SMB, "selected %s dialect idx = %d\n",
smb_protos[offt].prot, offt);
return smb_protos[offt].index;
smb2_protos[offt].prot, offt);
return smb2_protos[offt].index;
}
offt--;
}
Expand Down Expand Up @@ -169,7 +188,7 @@ static int ksmbd_lookup_dialect_by_name(char *cli_dialects, __le16 byte_count)
int i, seq_num, bcount, next;
char *dialect;

for (i = ARRAY_SIZE(smb_protos) - 1; i >= 0; i--) {
for (i = ARRAY_SIZE(smb1_protos) - 1; i >= 0; i--) {
seq_num = 0;
next = 0;
dialect = cli_dialects;
Expand All @@ -178,14 +197,14 @@ static int ksmbd_lookup_dialect_by_name(char *cli_dialects, __le16 byte_count)
dialect = next_dialect(dialect, &next);
ksmbd_debug(SMB, "client requested dialect %s\n",
dialect);
if (!strcmp(dialect, smb_protos[i].name)) {
if (supported_protocol(smb_protos[i].index)) {
if (!strcmp(dialect, smb1_protos[i].name)) {
if (supported_protocol(smb1_protos[i].index)) {
ksmbd_debug(SMB,
"selected %s dialect\n",
smb_protos[i].name);
if (smb_protos[i].index == SMB1_PROT)
smb1_protos[i].name);
if (smb1_protos[i].index == SMB1_PROT)
return seq_num;
return smb_protos[i].prot_id;
return smb1_protos[i].prot_id;
}
}
seq_num++;
Expand All @@ -201,27 +220,27 @@ int ksmbd_lookup_dialect_by_id(__le16 *cli_dialects, __le16 dialects_count)
int i;
int count;

for (i = ARRAY_SIZE(smb_protos) - 1; i >= 0; i--) {
for (i = ARRAY_SIZE(smb2_protos) - 1; i >= 0; i--) {
count = le16_to_cpu(dialects_count);
while (--count >= 0) {
ksmbd_debug(SMB, "client requested dialect 0x%x\n",
le16_to_cpu(cli_dialects[count]));
if (le16_to_cpu(cli_dialects[count]) !=
smb_protos[i].prot_id)
smb2_protos[i].prot_id)
continue;

if (supported_protocol(smb_protos[i].index)) {
if (supported_protocol(smb2_protos[i].index)) {
ksmbd_debug(SMB, "selected %s dialect\n",
smb_protos[i].name);
return smb_protos[i].prot_id;
smb2_protos[i].name);
return smb2_protos[i].prot_id;
}
}
}

return BAD_PROT_ID;
}

int ksmbd_negotiate_smb_dialect(void *buf)
static int ksmbd_negotiate_smb_dialect(void *buf)
{
__le32 proto;

Expand Down
3 changes: 1 addition & 2 deletions fs/ksmbd/smb_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,7 @@ struct smb_version_ops {
void (*set_sign_rsp)(struct ksmbd_work *work);
int (*generate_signingkey)(struct ksmbd_session *sess, struct ksmbd_conn *conn);
int (*generate_encryptionkey)(struct ksmbd_session *sess);
int (*is_transform_hdr)(void *buf);
bool (*is_transform_hdr)(void *buf);
int (*decrypt_req)(struct ksmbd_work *work);
int (*encrypt_resp)(struct ksmbd_work *work);
};
Expand All @@ -498,7 +498,6 @@ bool ksmbd_smb_request(struct ksmbd_conn *conn);

int ksmbd_lookup_dialect_by_id(__le16 *cli_dialects, __le16 dialects_count);

int ksmbd_negotiate_smb_dialect(void *buf);
int ksmbd_init_smb_server(struct ksmbd_work *work);

bool ksmbd_pdu_size_has_room(unsigned int pdu);
Expand Down
Loading

0 comments on commit e7a10ed

Please sign in to comment.