Lines 798-813
Link Here
|
798 |
} |
798 |
} |
799 |
case CIFS_NEGFLAVOR_UNENCAP: |
799 |
case CIFS_NEGFLAVOR_UNENCAP: |
800 |
switch (requested) { |
800 |
switch (requested) { |
|
|
801 |
case NTLM: |
801 |
case NTLMv2: |
802 |
case NTLMv2: |
802 |
return requested; |
803 |
return requested; |
803 |
case Unspecified: |
804 |
case Unspecified: |
804 |
if (global_secflags & CIFSSEC_MAY_NTLMV2) |
805 |
if (global_secflags & CIFSSEC_MAY_NTLMV2) |
805 |
return NTLMv2; |
806 |
return NTLMv2; |
|
|
807 |
if (global_secflags & CIFSSEC_MAY_NTLM) |
808 |
return NTLM; |
806 |
break; |
809 |
break; |
807 |
default: |
810 |
default: |
808 |
break; |
811 |
break; |
809 |
} |
812 |
} |
810 |
fallthrough; |
813 |
fallthrough; /* to attempt LANMAN authentication next */ |
|
|
814 |
case CIFS_NEGFLAVOR_LANMAN: |
815 |
switch (requested) { |
816 |
case LANMAN: |
817 |
return requested; |
818 |
case Unspecified: |
819 |
if (global_secflags & CIFSSEC_MAY_LANMAN) |
820 |
return LANMAN; |
821 |
fallthrough; |
822 |
default: |
823 |
return Unspecified; |
824 |
} |
811 |
default: |
825 |
default: |
812 |
return Unspecified; |
826 |
return Unspecified; |
813 |
} |
827 |
} |
Lines 932-937
Link Here
|
932 |
return rc; |
946 |
return rc; |
933 |
} |
947 |
} |
934 |
|
948 |
|
|
|
949 |
/* |
950 |
* LANMAN and plaintext are less secure and off by default. |
951 |
* So we make this explicitly be turned on in kconfig (in the |
952 |
* build) and turned on at runtime (changed from the default) |
953 |
* in proc/fs/cifs or via mount parm. Unfortunately this is |
954 |
* needed for old Win (e.g. Win95), some obscure NAS and OS/2 |
955 |
*/ |
956 |
#ifdef CONFIG_CIFS_WEAK_PW_HASH |
957 |
static void |
958 |
sess_auth_lanman(struct sess_data *sess_data) |
959 |
{ |
960 |
int rc = 0; |
961 |
struct smb_hdr *smb_buf; |
962 |
SESSION_SETUP_ANDX *pSMB; |
963 |
char *bcc_ptr; |
964 |
struct cifs_ses *ses = sess_data->ses; |
965 |
char lnm_session_key[CIFS_AUTH_RESP_SIZE]; |
966 |
__u16 bytes_remaining; |
967 |
|
968 |
/* lanman 2 style sessionsetup */ |
969 |
/* wct = 10 */ |
970 |
rc = sess_alloc_buffer(sess_data, 10); |
971 |
if (rc) |
972 |
goto out; |
973 |
|
974 |
pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base; |
975 |
bcc_ptr = sess_data->iov[2].iov_base; |
976 |
(void)cifs_ssetup_hdr(ses, pSMB); |
977 |
|
978 |
pSMB->req.hdr.Flags2 &= ~SMBFLG2_UNICODE; |
979 |
|
980 |
if (ses->user_name != NULL) { |
981 |
/* no capabilities flags in old lanman negotiation */ |
982 |
pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE); |
983 |
|
984 |
/* Calculate hash with password and copy into bcc_ptr. |
985 |
* Encryption Key (stored as in cryptkey) gets used if the |
986 |
* security mode bit in Negotiate Protocol response states |
987 |
* to use challenge/response method (i.e. Password bit is 1). |
988 |
*/ |
989 |
rc = calc_lanman_hash(ses->password, ses->server->cryptkey, |
990 |
ses->server->sec_mode & SECMODE_PW_ENCRYPT ? |
991 |
true : false, lnm_session_key); |
992 |
if (rc) |
993 |
goto out; |
994 |
|
995 |
memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE); |
996 |
bcc_ptr += CIFS_AUTH_RESP_SIZE; |
997 |
} else { |
998 |
pSMB->old_req.PasswordLength = 0; |
999 |
} |
1000 |
|
1001 |
/* |
1002 |
* can not sign if LANMAN negotiated so no need |
1003 |
* to calculate signing key? but what if server |
1004 |
* changed to do higher than lanman dialect and |
1005 |
* we reconnected would we ever calc signing_key? |
1006 |
*/ |
1007 |
|
1008 |
cifs_dbg(FYI, "Negotiating LANMAN setting up strings\n"); |
1009 |
/* Unicode not allowed for LANMAN dialects */ |
1010 |
ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp); |
1011 |
|
1012 |
sess_data->iov[2].iov_len = (long) bcc_ptr - |
1013 |
(long) sess_data->iov[2].iov_base; |
1014 |
|
1015 |
rc = sess_sendreceive(sess_data); |
1016 |
if (rc) |
1017 |
goto out; |
1018 |
|
1019 |
pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base; |
1020 |
smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base; |
1021 |
|
1022 |
/* lanman response has a word count of 3 */ |
1023 |
if (smb_buf->WordCount != 3) { |
1024 |
rc = -EIO; |
1025 |
cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount); |
1026 |
goto out; |
1027 |
} |
1028 |
|
1029 |
if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN) |
1030 |
cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */ |
1031 |
|
1032 |
ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */ |
1033 |
cifs_dbg(FYI, "UID = %llu\n", ses->Suid); |
1034 |
|
1035 |
bytes_remaining = get_bcc(smb_buf); |
1036 |
bcc_ptr = pByteArea(smb_buf); |
1037 |
|
1038 |
/* BB check if Unicode and decode strings */ |
1039 |
if (bytes_remaining == 0) { |
1040 |
/* no string area to decode, do nothing */ |
1041 |
} else if (smb_buf->Flags2 & SMBFLG2_UNICODE) { |
1042 |
/* unicode string area must be word-aligned */ |
1043 |
if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) { |
1044 |
++bcc_ptr; |
1045 |
--bytes_remaining; |
1046 |
} |
1047 |
decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses, |
1048 |
sess_data->nls_cp); |
1049 |
} else { |
1050 |
decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses, |
1051 |
sess_data->nls_cp); |
1052 |
} |
1053 |
|
1054 |
rc = sess_establish_session(sess_data); |
1055 |
out: |
1056 |
sess_data->result = rc; |
1057 |
sess_data->func = NULL; |
1058 |
sess_free_buffer(sess_data); |
1059 |
} |
1060 |
|
1061 |
#endif |
1062 |
|
1063 |
static void |
1064 |
sess_auth_ntlm(struct sess_data *sess_data) |
1065 |
{ |
1066 |
int rc = 0; |
1067 |
struct smb_hdr *smb_buf; |
1068 |
SESSION_SETUP_ANDX *pSMB; |
1069 |
char *bcc_ptr; |
1070 |
struct cifs_ses *ses = sess_data->ses; |
1071 |
__u32 capabilities; |
1072 |
__u16 bytes_remaining; |
1073 |
|
1074 |
/* old style NTLM sessionsetup */ |
1075 |
/* wct = 13 */ |
1076 |
rc = sess_alloc_buffer(sess_data, 13); |
1077 |
if (rc) |
1078 |
goto out; |
1079 |
|
1080 |
pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base; |
1081 |
bcc_ptr = sess_data->iov[2].iov_base; |
1082 |
capabilities = cifs_ssetup_hdr(ses, pSMB); |
1083 |
|
1084 |
pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities); |
1085 |
if (ses->user_name != NULL) { |
1086 |
pSMB->req_no_secext.CaseInsensitivePasswordLength = |
1087 |
cpu_to_le16(CIFS_AUTH_RESP_SIZE); |
1088 |
pSMB->req_no_secext.CaseSensitivePasswordLength = |
1089 |
cpu_to_le16(CIFS_AUTH_RESP_SIZE); |
1090 |
|
1091 |
/* calculate ntlm response and session key */ |
1092 |
rc = setup_ntlm_response(ses, sess_data->nls_cp); |
1093 |
if (rc) { |
1094 |
cifs_dbg(VFS, "Error %d during NTLM authentication\n", |
1095 |
rc); |
1096 |
goto out; |
1097 |
} |
1098 |
|
1099 |
/* copy ntlm response */ |
1100 |
memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE, |
1101 |
CIFS_AUTH_RESP_SIZE); |
1102 |
bcc_ptr += CIFS_AUTH_RESP_SIZE; |
1103 |
memcpy(bcc_ptr, ses->auth_key.response + CIFS_SESS_KEY_SIZE, |
1104 |
CIFS_AUTH_RESP_SIZE); |
1105 |
bcc_ptr += CIFS_AUTH_RESP_SIZE; |
1106 |
} else { |
1107 |
pSMB->req_no_secext.CaseInsensitivePasswordLength = 0; |
1108 |
pSMB->req_no_secext.CaseSensitivePasswordLength = 0; |
1109 |
} |
1110 |
|
1111 |
if (ses->capabilities & CAP_UNICODE) { |
1112 |
/* unicode strings must be word aligned */ |
1113 |
if (sess_data->iov[0].iov_len % 2) { |
1114 |
*bcc_ptr = 0; |
1115 |
bcc_ptr++; |
1116 |
} |
1117 |
unicode_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp); |
1118 |
} else { |
1119 |
ascii_ssetup_strings(&bcc_ptr, ses, sess_data->nls_cp); |
1120 |
} |
1121 |
|
1122 |
|
1123 |
sess_data->iov[2].iov_len = (long) bcc_ptr - |
1124 |
(long) sess_data->iov[2].iov_base; |
1125 |
|
1126 |
rc = sess_sendreceive(sess_data); |
1127 |
if (rc) |
1128 |
goto out; |
1129 |
|
1130 |
pSMB = (SESSION_SETUP_ANDX *)sess_data->iov[0].iov_base; |
1131 |
smb_buf = (struct smb_hdr *)sess_data->iov[0].iov_base; |
1132 |
|
1133 |
if (smb_buf->WordCount != 3) { |
1134 |
rc = -EIO; |
1135 |
cifs_dbg(VFS, "bad word count %d\n", smb_buf->WordCount); |
1136 |
goto out; |
1137 |
} |
1138 |
|
1139 |
if (le16_to_cpu(pSMB->resp.Action) & GUEST_LOGIN) |
1140 |
cifs_dbg(FYI, "Guest login\n"); /* BB mark SesInfo struct? */ |
1141 |
|
1142 |
ses->Suid = smb_buf->Uid; /* UID left in wire format (le) */ |
1143 |
cifs_dbg(FYI, "UID = %llu\n", ses->Suid); |
1144 |
|
1145 |
bytes_remaining = get_bcc(smb_buf); |
1146 |
bcc_ptr = pByteArea(smb_buf); |
1147 |
|
1148 |
/* BB check if Unicode and decode strings */ |
1149 |
if (bytes_remaining == 0) { |
1150 |
/* no string area to decode, do nothing */ |
1151 |
} else if (smb_buf->Flags2 & SMBFLG2_UNICODE) { |
1152 |
/* unicode string area must be word-aligned */ |
1153 |
if (((unsigned long) bcc_ptr - (unsigned long) smb_buf) % 2) { |
1154 |
++bcc_ptr; |
1155 |
--bytes_remaining; |
1156 |
} |
1157 |
decode_unicode_ssetup(&bcc_ptr, bytes_remaining, ses, |
1158 |
sess_data->nls_cp); |
1159 |
} else { |
1160 |
decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses, |
1161 |
sess_data->nls_cp); |
1162 |
} |
1163 |
|
1164 |
rc = sess_establish_session(sess_data); |
1165 |
out: |
1166 |
sess_data->result = rc; |
1167 |
sess_data->func = NULL; |
1168 |
sess_free_buffer(sess_data); |
1169 |
kfree(ses->auth_key.response); |
1170 |
ses->auth_key.response = NULL; |
1171 |
} |
1172 |
|
935 |
static void |
1173 |
static void |
936 |
sess_auth_ntlmv2(struct sess_data *sess_data) |
1174 |
sess_auth_ntlmv2(struct sess_data *sess_data) |
937 |
{ |
1175 |
{ |
Lines 1436-1441
Link Here
|
1436 |
} |
1674 |
} |
1437 |
|
1675 |
|
1438 |
switch (type) { |
1676 |
switch (type) { |
|
|
1677 |
case LANMAN: |
1678 |
/* LANMAN and plaintext are less secure and off by default. |
1679 |
* So we make this explicitly be turned on in kconfig (in the |
1680 |
* build) and turned on at runtime (changed from the default) |
1681 |
* in proc/fs/cifs or via mount parm. Unfortunately this is |
1682 |
* needed for old Win (e.g. Win95), some obscure NAS and OS/2 */ |
1683 |
#ifdef CONFIG_CIFS_WEAK_PW_HASH |
1684 |
sess_data->func = sess_auth_lanman; |
1685 |
break; |
1686 |
#else |
1687 |
return -EOPNOTSUPP; |
1688 |
#endif |
1689 |
case NTLM: |
1690 |
sess_data->func = sess_auth_ntlm; |
1691 |
break; |
1439 |
case NTLMv2: |
1692 |
case NTLMv2: |
1440 |
sess_data->func = sess_auth_ntlmv2; |
1693 |
sess_data->func = sess_auth_ntlmv2; |
1441 |
break; |
1694 |
break; |