From 2f5f6e2a1ce25b9d0e2df800387ab9deea0c754e Mon Sep 17 00:00:00 2001 From: bp Date: Mon, 16 Sep 2002 10:50:38 +0000 Subject: Implement support for mixed case passwords. Obtained from: Darwin MFC after: 2 weeks --- sys/netsmb/smb_conn.h | 1 + sys/netsmb/smb_smb.c | 83 ++++++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 77 insertions(+), 7 deletions(-) diff --git a/sys/netsmb/smb_conn.h b/sys/netsmb/smb_conn.h index a2a2df7..7fb48eb 100644 --- a/sys/netsmb/smb_conn.h +++ b/sys/netsmb/smb_conn.h @@ -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). diff --git a/sys/netsmb/smb_smb.c b/sys/netsmb/smb_smb.c index 37fb091..2730149 100644 --- a/sys/netsmb/smb_smb.c +++ b/sys/netsmb/smb_smb.c @@ -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 @@ bad: 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 @@ bad: if (pbuf) free(pbuf, M_SMBTEMP); smb_rq_done(rqp); + if (error && upper == 1) + goto again; return error; } -- cgit v1.1