Implement support for mixed case passwords.

Obtained from:	Darwin
MFC after:	2 weeks
This commit is contained in:
Boris Popov 2002-09-16 10:50:38 +00:00
parent e2a70cff10
commit 70f9b9d94f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=103396
2 changed files with 77 additions and 7 deletions

View File

@ -273,6 +273,7 @@ struct smb_vc {
#define vc_maxmux vc_sopt.sv_maxmux
#define vc_flags obj.co_flags
#define SMB_UNICODE_STRINGS(vcp) ((vcp)->vc_hflags2 & SMB_FLAGS2_UNICODE)
/*
* smb_share structure describes connection to the given SMB share (tree).

View File

@ -266,7 +266,11 @@ smb_smb_ssnsetup(struct smb_vc *vcp, struct smb_cred *scred)
u_int16_t tw, tw1;*/
smb_uniptr unipp, ntencpass = NULL;
char *pp, *up, *pbuf, *encpass;
int error, plen, uniplen, ulen;
int error, plen, uniplen, ulen, upper;
upper = 0;
again:
vcp->vc_smbuid = SMB_UID_UNKNOWN;
@ -279,13 +283,34 @@ smb_smb_ssnsetup(struct smb_vc *vcp, struct smb_cred *scred)
pbuf = malloc(SMB_MAXPASSWORDLEN + 1, M_SMBTEMP, M_WAITOK);
encpass = malloc(24, M_SMBTEMP, M_WAITOK);
if (vcp->vc_sopt.sv_sm & SMB_SM_USER) {
iconv_convstr(vcp->vc_toupper, pbuf, smb_vc_getpass(vcp));
iconv_convstr(vcp->vc_toserver, pbuf, pbuf);
/*
* We try w/o uppercasing first so Samba mixed case
* passwords work. If that fails we come back and try
* uppercasing to satisfy OS/2 and Windows for Workgroups.
*/
if (upper++) {
iconv_convstr(vcp->vc_toupper, pbuf,
smb_vc_getpass(vcp)/*, SMB_MAXPASSWORDLEN*/);
} else {
strncpy(pbuf, smb_vc_getpass(vcp), SMB_MAXPASSWORDLEN);
pbuf[SMB_MAXPASSWORDLEN] = '\0';
}
if (!SMB_UNICODE_STRINGS(vcp))
iconv_convstr(vcp->vc_toserver, pbuf, pbuf/*,
SMB_MAXPASSWORDLEN*/);
if (vcp->vc_sopt.sv_sm & SMB_SM_ENCRYPT) {
uniplen = plen = 24;
smb_encrypt(pbuf, vcp->vc_ch, encpass);
ntencpass = malloc(uniplen, M_SMBTEMP, M_WAITOK);
iconv_convstr(vcp->vc_toserver, pbuf, smb_vc_getpass(vcp));
if (SMB_UNICODE_STRINGS(vcp)) {
strncpy(pbuf, smb_vc_getpass(vcp),
SMB_MAXPASSWORDLEN);
pbuf[SMB_MAXPASSWORDLEN] = '\0';
} else
iconv_convstr(vcp->vc_toserver, pbuf,
smb_vc_getpass(vcp)/*,
SMB_MAXPASSWORDLEN*/);
smb_ntencrypt(pbuf, vcp->vc_ch, (u_char*)ntencpass);
pp = encpass;
unipp = ntencpass;
@ -320,6 +345,12 @@ smb_smb_ssnsetup(struct smb_vc *vcp, struct smb_cred *scred)
mbp = &rqp->sr_rq;
up = vcp->vc_username;
ulen = strlen(up) + 1;
/*
* If userid is null we are attempting anonymous browse login
* so passwords must be zero length.
*/
if (ulen == 1)
plen = uniplen = 0;
mb_put_uint8(mbp, 0xff);
mb_put_uint8(mbp, 0);
mb_put_uint16le(mbp, 0);
@ -363,6 +394,8 @@ smb_smb_ssnsetup(struct smb_vc *vcp, struct smb_cred *scred)
free(encpass, M_SMBTEMP);
free(pbuf, M_SMBTEMP);
smb_rq_done(rqp);
if (error && upper == 1 && vcp->vc_sopt.sv_sm & SMB_SM_USER)
goto again;
return error;
}
@ -431,7 +464,29 @@ smb_smb_treeconnect(struct smb_share *ssp, struct smb_cred *scred)
struct smb_rq rq, *rqp = &rq;
struct mbchain *mbp;
char *pp, *pbuf, *encpass;
int error, plen, caseopt;
int error, plen, caseopt, upper;
upper = 0;
again:
#if 0
/* Disable Unicode for SMB_COM_TREE_CONNECT_ANDX requests */
if (SSTOVC(ssp)->vc_hflags2 & SMB_FLAGS2_UNICODE) {
vcp = SSTOVC(ssp);
if (vcp->vc_toserver) {
iconv_close(vcp->vc_toserver);
/* Use NULL until UTF-8 -> ASCII works */
vcp->vc_toserver = NULL;
}
if (vcp->vc_tolocal) {
iconv_close(vcp->vc_tolocal);
/* Use NULL until ASCII -> UTF-8 works*/
vcp->vc_tolocal = NULL;
}
vcp->vc_hflags2 &= ~SMB_FLAGS2_UNICODE;
}
#endif
ssp->ss_tid = SMB_TID_UNKNOWN;
error = smb_rq_alloc(SSTOCP(ssp), SMB_COM_TREE_CONNECT_ANDX, scred, &rqp);
@ -447,8 +502,20 @@ smb_smb_treeconnect(struct smb_share *ssp, struct smb_cred *scred)
} else {
pbuf = malloc(SMB_MAXPASSWORDLEN + 1, M_SMBTEMP, M_WAITOK);
encpass = malloc(24, M_SMBTEMP, M_WAITOK);
iconv_convstr(vcp->vc_toupper, pbuf, smb_share_getpass(ssp));
iconv_convstr(vcp->vc_toserver, pbuf, pbuf);
/*
* We try w/o uppercasing first so Samba mixed case
* passwords work. If that fails we come back and try
* uppercasing to satisfy OS/2 and Windows for Workgroups.
*/
if (upper++) {
iconv_convstr(vcp->vc_toupper, pbuf,
smb_share_getpass(ssp)/*,
SMB_MAXPASSWORDLEN*/);
} else {
strncpy(pbuf, smb_share_getpass(ssp),
SMB_MAXPASSWORDLEN);
pbuf[SMB_MAXPASSWORDLEN] = '\0';
}
if (vcp->vc_sopt.sv_sm & SMB_SM_ENCRYPT) {
plen = 24;
smb_encrypt(pbuf, vcp->vc_ch, encpass);
@ -490,6 +557,8 @@ smb_smb_treeconnect(struct smb_share *ssp, struct smb_cred *scred)
if (pbuf)
free(pbuf, M_SMBTEMP);
smb_rq_done(rqp);
if (error && upper == 1)
goto again;
return error;
}