@@ -1594,7 +1594,7 @@ static int krb5_authenticate(struct ksmbd_work *work,
1594
1594
struct ksmbd_conn * conn = work -> conn ;
1595
1595
struct ksmbd_session * sess = work -> sess ;
1596
1596
char * in_blob , * out_blob ;
1597
- struct channel * chann = NULL ;
1597
+ struct channel * chann = NULL , * old ;
1598
1598
u64 prev_sess_id ;
1599
1599
int in_len , out_len ;
1600
1600
int retval ;
@@ -1621,11 +1621,24 @@ static int krb5_authenticate(struct ksmbd_work *work,
1621
1621
1622
1622
rsp -> SecurityBufferLength = cpu_to_le16 (out_len );
1623
1623
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 )) ||
1625
1637
(req -> SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED ))
1626
1638
sess -> sign = true;
1627
1639
1628
- if (smb3_encryption_negotiated (conn )) {
1640
+ if (smb3_encryption_negotiated (conn ) &&
1641
+ !(req -> Flags & SMB2_SESSION_REQ_FLAG_BINDING )) {
1629
1642
retval = conn -> ops -> generate_encryptionkey (conn , sess );
1630
1643
if (retval ) {
1631
1644
ksmbd_debug (SMB ,
@@ -1638,6 +1651,7 @@ static int krb5_authenticate(struct ksmbd_work *work,
1638
1651
sess -> sign = false;
1639
1652
}
1640
1653
1654
+ binding_session :
1641
1655
if (conn -> dialect >= SMB30_PROT_ID ) {
1642
1656
chann = lookup_chann_list (sess , conn );
1643
1657
if (!chann ) {
@@ -1646,7 +1660,12 @@ static int krb5_authenticate(struct ksmbd_work *work,
1646
1660
return - ENOMEM ;
1647
1661
1648
1662
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
+ }
1650
1669
}
1651
1670
}
1652
1671
@@ -1833,8 +1852,6 @@ int smb2_sess_setup(struct ksmbd_work *work)
1833
1852
ksmbd_conn_set_good (conn );
1834
1853
sess -> state = SMB2_SESSION_VALID ;
1835
1854
}
1836
- kfree (sess -> Preauth_HashValue );
1837
- sess -> Preauth_HashValue = NULL ;
1838
1855
} else if (conn -> preferred_auth_mech == KSMBD_AUTH_NTLMSSP ) {
1839
1856
if (negblob -> MessageType == NtLmNegotiate ) {
1840
1857
rc = ntlm_negotiate (work , negblob , negblob_len , rsp );
@@ -1861,8 +1878,6 @@ int smb2_sess_setup(struct ksmbd_work *work)
1861
1878
kfree (preauth_sess );
1862
1879
}
1863
1880
}
1864
- kfree (sess -> Preauth_HashValue );
1865
- sess -> Preauth_HashValue = NULL ;
1866
1881
} else {
1867
1882
pr_info_ratelimited ("Unknown NTLMSSP message type : 0x%x\n" ,
1868
1883
le32_to_cpu (negblob -> MessageType ));
@@ -2581,7 +2596,7 @@ static void smb2_update_xattrs(struct ksmbd_tree_connect *tcon,
2581
2596
}
2582
2597
}
2583
2598
2584
- static int smb2_creat (struct ksmbd_work * work , struct path * parent_path ,
2599
+ static int smb2_creat (struct ksmbd_work * work ,
2585
2600
struct path * path , char * name , int open_flags ,
2586
2601
umode_t posix_mode , bool is_dir )
2587
2602
{
@@ -2610,7 +2625,7 @@ static int smb2_creat(struct ksmbd_work *work, struct path *parent_path,
2610
2625
return rc ;
2611
2626
}
2612
2627
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 );
2614
2629
if (rc ) {
2615
2630
pr_err ("cannot get linux path (%s), err = %d\n" ,
2616
2631
name , rc );
@@ -2860,7 +2875,7 @@ int smb2_open(struct ksmbd_work *work)
2860
2875
struct ksmbd_tree_connect * tcon = work -> tcon ;
2861
2876
struct smb2_create_req * req ;
2862
2877
struct smb2_create_rsp * rsp ;
2863
- struct path path , parent_path ;
2878
+ struct path path ;
2864
2879
struct ksmbd_share_config * share = tcon -> share_conf ;
2865
2880
struct ksmbd_file * fp = NULL ;
2866
2881
struct file * filp = NULL ;
@@ -3116,8 +3131,8 @@ int smb2_open(struct ksmbd_work *work)
3116
3131
goto err_out2 ;
3117
3132
}
3118
3133
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 );
3121
3136
if (!rc ) {
3122
3137
file_present = true;
3123
3138
@@ -3238,7 +3253,7 @@ int smb2_open(struct ksmbd_work *work)
3238
3253
3239
3254
/*create file if not present */
3240
3255
if (!file_present ) {
3241
- rc = smb2_creat (work , & parent_path , & path , name , open_flags ,
3256
+ rc = smb2_creat (work , & path , name , open_flags ,
3242
3257
posix_mode ,
3243
3258
req -> CreateOptions & FILE_DIRECTORY_FILE_LE );
3244
3259
if (rc ) {
@@ -3443,7 +3458,7 @@ int smb2_open(struct ksmbd_work *work)
3443
3458
}
3444
3459
3445
3460
if (file_present || created )
3446
- ksmbd_vfs_kern_path_unlock ( & parent_path , & path );
3461
+ path_put ( & path );
3447
3462
3448
3463
if (!S_ISDIR (file_inode (filp )-> i_mode ) && open_flags & O_TRUNC &&
3449
3464
!fp -> attrib_only && !stream_name ) {
@@ -3724,7 +3739,7 @@ int smb2_open(struct ksmbd_work *work)
3724
3739
3725
3740
err_out :
3726
3741
if (rc && (file_present || created ))
3727
- ksmbd_vfs_kern_path_unlock ( & parent_path , & path );
3742
+ path_put ( & path );
3728
3743
3729
3744
err_out1 :
3730
3745
ksmbd_revert_fsids (work );
@@ -4108,20 +4123,6 @@ struct smb2_query_dir_private {
4108
4123
int info_level ;
4109
4124
};
4110
4125
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
-
4125
4126
static int process_query_dir_entries (struct smb2_query_dir_private * priv )
4126
4127
{
4127
4128
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)
4136
4137
if (dentry_name (priv -> d_info , priv -> info_level ))
4137
4138
return - EINVAL ;
4138
4139
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 );
4145
4144
4146
4145
if (IS_ERR (dent )) {
4147
4146
ksmbd_debug (SMB , "Cannot lookup `%s' [%ld]\n" ,
@@ -6052,8 +6051,7 @@ static int smb2_create_link(struct ksmbd_work *work,
6052
6051
struct nls_table * local_nls )
6053
6052
{
6054
6053
char * link_name = NULL , * target_name = NULL , * pathname = NULL ;
6055
- struct path path , parent_path ;
6056
- bool file_present = false;
6054
+ struct path path ;
6057
6055
int rc ;
6058
6056
6059
6057
if (buf_len < (u64 )sizeof (struct smb2_file_link_info ) +
@@ -6082,37 +6080,30 @@ static int smb2_create_link(struct ksmbd_work *work,
6082
6080
6083
6081
ksmbd_debug (SMB , "target name is %s\n" , target_name );
6084
6082
rc = ksmbd_vfs_kern_path_locked (work , link_name , LOOKUP_NO_SYMLINKS ,
6085
- & parent_path , & path , 0 );
6083
+ & path , 0 );
6086
6084
if (rc ) {
6087
6085
if (rc != - ENOENT )
6088
6086
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 ) {
6094
6089
rc = ksmbd_vfs_remove_file (work , & path );
6095
6090
if (rc ) {
6096
6091
rc = - EINVAL ;
6097
6092
ksmbd_debug (SMB , "cannot delete %s\n" ,
6098
6093
link_name );
6099
6094
goto out ;
6100
6095
}
6101
- }
6102
- } else {
6103
- if (file_present ) {
6096
+ } else {
6104
6097
rc = - EEXIST ;
6105
6098
ksmbd_debug (SMB , "link already exists\n" );
6106
6099
goto out ;
6107
6100
}
6101
+ ksmbd_vfs_kern_path_unlock (& path );
6108
6102
}
6109
-
6110
6103
rc = ksmbd_vfs_link (work , target_name , link_name );
6111
6104
if (rc )
6112
6105
rc = - EINVAL ;
6113
6106
out :
6114
- if (file_present )
6115
- ksmbd_vfs_kern_path_unlock (& parent_path , & path );
6116
6107
6117
6108
if (!IS_ERR (link_name ))
6118
6109
kfree (link_name );
0 commit comments