@@ -1594,7 +1594,7 @@ static int krb5_authenticate(struct ksmbd_work *work,
15941594 struct ksmbd_conn * conn = work -> conn ;
15951595 struct ksmbd_session * sess = work -> sess ;
15961596 char * in_blob , * out_blob ;
1597- struct channel * chann = NULL ;
1597+ struct channel * chann = NULL , * old ;
15981598 u64 prev_sess_id ;
15991599 int in_len , out_len ;
16001600 int retval ;
@@ -1621,11 +1621,24 @@ static int krb5_authenticate(struct ksmbd_work *work,
16211621
16221622 rsp -> SecurityBufferLength = cpu_to_le16 (out_len );
16231623
1624- if ((conn -> sign || server_conf .enforced_signing ) ||
1624+ /*
1625+ * If session state is SMB2_SESSION_VALID, We can assume
1626+ * that it is reauthentication. And the user/password
1627+ * has been verified, so return it here.
1628+ */
1629+ if (sess -> state == SMB2_SESSION_VALID ) {
1630+ if (conn -> binding )
1631+ goto binding_session ;
1632+ return 0 ;
1633+ }
1634+
1635+ if ((rsp -> SessionFlags != SMB2_SESSION_FLAG_IS_GUEST_LE &&
1636+ (conn -> sign || server_conf .enforced_signing )) ||
16251637 (req -> SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED ))
16261638 sess -> sign = true;
16271639
1628- if (smb3_encryption_negotiated (conn )) {
1640+ if (smb3_encryption_negotiated (conn ) &&
1641+ !(req -> Flags & SMB2_SESSION_REQ_FLAG_BINDING )) {
16291642 retval = conn -> ops -> generate_encryptionkey (conn , sess );
16301643 if (retval ) {
16311644 ksmbd_debug (SMB ,
@@ -1638,6 +1651,7 @@ static int krb5_authenticate(struct ksmbd_work *work,
16381651 sess -> sign = false;
16391652 }
16401653
1654+ binding_session :
16411655 if (conn -> dialect >= SMB30_PROT_ID ) {
16421656 chann = lookup_chann_list (sess , conn );
16431657 if (!chann ) {
@@ -1646,7 +1660,12 @@ static int krb5_authenticate(struct ksmbd_work *work,
16461660 return - ENOMEM ;
16471661
16481662 chann -> conn = conn ;
1649- xa_store (& sess -> ksmbd_chann_list , (long )conn , chann , KSMBD_DEFAULT_GFP );
1663+ old = xa_store (& sess -> ksmbd_chann_list , (long )conn ,
1664+ chann , KSMBD_DEFAULT_GFP );
1665+ if (xa_is_err (old )) {
1666+ kfree (chann );
1667+ return xa_err (old );
1668+ }
16501669 }
16511670 }
16521671
@@ -1833,8 +1852,6 @@ int smb2_sess_setup(struct ksmbd_work *work)
18331852 ksmbd_conn_set_good (conn );
18341853 sess -> state = SMB2_SESSION_VALID ;
18351854 }
1836- kfree (sess -> Preauth_HashValue );
1837- sess -> Preauth_HashValue = NULL ;
18381855 } else if (conn -> preferred_auth_mech == KSMBD_AUTH_NTLMSSP ) {
18391856 if (negblob -> MessageType == NtLmNegotiate ) {
18401857 rc = ntlm_negotiate (work , negblob , negblob_len , rsp );
@@ -1861,8 +1878,6 @@ int smb2_sess_setup(struct ksmbd_work *work)
18611878 kfree (preauth_sess );
18621879 }
18631880 }
1864- kfree (sess -> Preauth_HashValue );
1865- sess -> Preauth_HashValue = NULL ;
18661881 } else {
18671882 pr_info_ratelimited ("Unknown NTLMSSP message type : 0x%x\n" ,
18681883 le32_to_cpu (negblob -> MessageType ));
@@ -2581,7 +2596,7 @@ static void smb2_update_xattrs(struct ksmbd_tree_connect *tcon,
25812596 }
25822597}
25832598
2584- static int smb2_creat (struct ksmbd_work * work , struct path * parent_path ,
2599+ static int smb2_creat (struct ksmbd_work * work ,
25852600 struct path * path , char * name , int open_flags ,
25862601 umode_t posix_mode , bool is_dir )
25872602{
@@ -2610,7 +2625,7 @@ static int smb2_creat(struct ksmbd_work *work, struct path *parent_path,
26102625 return rc ;
26112626 }
26122627
2613- rc = ksmbd_vfs_kern_path_locked (work , name , 0 , parent_path , path , 0 );
2628+ rc = ksmbd_vfs_kern_path (work , name , 0 , path , 0 );
26142629 if (rc ) {
26152630 pr_err ("cannot get linux path (%s), err = %d\n" ,
26162631 name , rc );
@@ -2860,7 +2875,7 @@ int smb2_open(struct ksmbd_work *work)
28602875 struct ksmbd_tree_connect * tcon = work -> tcon ;
28612876 struct smb2_create_req * req ;
28622877 struct smb2_create_rsp * rsp ;
2863- struct path path , parent_path ;
2878+ struct path path ;
28642879 struct ksmbd_share_config * share = tcon -> share_conf ;
28652880 struct ksmbd_file * fp = NULL ;
28662881 struct file * filp = NULL ;
@@ -3116,8 +3131,8 @@ int smb2_open(struct ksmbd_work *work)
31163131 goto err_out2 ;
31173132 }
31183133
3119- rc = ksmbd_vfs_kern_path_locked (work , name , LOOKUP_NO_SYMLINKS ,
3120- & parent_path , & path , 1 );
3134+ rc = ksmbd_vfs_kern_path (work , name , LOOKUP_NO_SYMLINKS ,
3135+ & path , 1 );
31213136 if (!rc ) {
31223137 file_present = true;
31233138
@@ -3238,7 +3253,7 @@ int smb2_open(struct ksmbd_work *work)
32383253
32393254 /*create file if not present */
32403255 if (!file_present ) {
3241- rc = smb2_creat (work , & parent_path , & path , name , open_flags ,
3256+ rc = smb2_creat (work , & path , name , open_flags ,
32423257 posix_mode ,
32433258 req -> CreateOptions & FILE_DIRECTORY_FILE_LE );
32443259 if (rc ) {
@@ -3443,7 +3458,7 @@ int smb2_open(struct ksmbd_work *work)
34433458 }
34443459
34453460 if (file_present || created )
3446- ksmbd_vfs_kern_path_unlock ( & parent_path , & path );
3461+ path_put ( & path );
34473462
34483463 if (!S_ISDIR (file_inode (filp )-> i_mode ) && open_flags & O_TRUNC &&
34493464 !fp -> attrib_only && !stream_name ) {
@@ -3724,7 +3739,7 @@ int smb2_open(struct ksmbd_work *work)
37243739
37253740err_out :
37263741 if (rc && (file_present || created ))
3727- ksmbd_vfs_kern_path_unlock ( & parent_path , & path );
3742+ path_put ( & path );
37283743
37293744err_out1 :
37303745 ksmbd_revert_fsids (work );
@@ -4108,20 +4123,6 @@ struct smb2_query_dir_private {
41084123 int info_level ;
41094124};
41104125
4111- static void lock_dir (struct ksmbd_file * dir_fp )
4112- {
4113- struct dentry * dir = dir_fp -> filp -> f_path .dentry ;
4114-
4115- inode_lock_nested (d_inode (dir ), I_MUTEX_PARENT );
4116- }
4117-
4118- static void unlock_dir (struct ksmbd_file * dir_fp )
4119- {
4120- struct dentry * dir = dir_fp -> filp -> f_path .dentry ;
4121-
4122- inode_unlock (d_inode (dir ));
4123- }
4124-
41254126static int process_query_dir_entries (struct smb2_query_dir_private * priv )
41264127{
41274128 struct mnt_idmap * idmap = file_mnt_idmap (priv -> dir_fp -> filp );
@@ -4136,12 +4137,10 @@ static int process_query_dir_entries(struct smb2_query_dir_private *priv)
41364137 if (dentry_name (priv -> d_info , priv -> info_level ))
41374138 return - EINVAL ;
41384139
4139- lock_dir (priv -> dir_fp );
4140- dent = lookup_one (idmap ,
4141- & QSTR_LEN (priv -> d_info -> name ,
4142- priv -> d_info -> name_len ),
4143- priv -> dir_fp -> filp -> f_path .dentry );
4144- unlock_dir (priv -> dir_fp );
4140+ dent = lookup_one_unlocked (idmap ,
4141+ & QSTR_LEN (priv -> d_info -> name ,
4142+ priv -> d_info -> name_len ),
4143+ priv -> dir_fp -> filp -> f_path .dentry );
41454144
41464145 if (IS_ERR (dent )) {
41474146 ksmbd_debug (SMB , "Cannot lookup `%s' [%ld]\n" ,
@@ -6052,8 +6051,7 @@ static int smb2_create_link(struct ksmbd_work *work,
60526051 struct nls_table * local_nls )
60536052{
60546053 char * link_name = NULL , * target_name = NULL , * pathname = NULL ;
6055- struct path path , parent_path ;
6056- bool file_present = false;
6054+ struct path path ;
60576055 int rc ;
60586056
60596057 if (buf_len < (u64 )sizeof (struct smb2_file_link_info ) +
@@ -6082,37 +6080,30 @@ static int smb2_create_link(struct ksmbd_work *work,
60826080
60836081 ksmbd_debug (SMB , "target name is %s\n" , target_name );
60846082 rc = ksmbd_vfs_kern_path_locked (work , link_name , LOOKUP_NO_SYMLINKS ,
6085- & parent_path , & path , 0 );
6083+ & path , 0 );
60866084 if (rc ) {
60876085 if (rc != - ENOENT )
60886086 goto out ;
6089- } else
6090- file_present = true;
6091-
6092- if (file_info -> ReplaceIfExists ) {
6093- if (file_present ) {
6087+ } else {
6088+ if (file_info -> ReplaceIfExists ) {
60946089 rc = ksmbd_vfs_remove_file (work , & path );
60956090 if (rc ) {
60966091 rc = - EINVAL ;
60976092 ksmbd_debug (SMB , "cannot delete %s\n" ,
60986093 link_name );
60996094 goto out ;
61006095 }
6101- }
6102- } else {
6103- if (file_present ) {
6096+ } else {
61046097 rc = - EEXIST ;
61056098 ksmbd_debug (SMB , "link already exists\n" );
61066099 goto out ;
61076100 }
6101+ ksmbd_vfs_kern_path_unlock (& path );
61086102 }
6109-
61106103 rc = ksmbd_vfs_link (work , target_name , link_name );
61116104 if (rc )
61126105 rc = - EINVAL ;
61136106out :
6114- if (file_present )
6115- ksmbd_vfs_kern_path_unlock (& parent_path , & path );
61166107
61176108 if (!IS_ERR (link_name ))
61186109 kfree (link_name );
0 commit comments