kern/78110: [BUGFIX] fixed multibyte treatment of Samba FS
(smb/ctx.c).
Daichi GOTO
daichi at FreeBSD.org
Sat Feb 26 09:40:15 GMT 2005
>Number: 78110
>Category: kern
>Synopsis: [BUGFIX] fixed multibyte treatment of Samba FS (smb/ctx.c).
>Confidential: no
>Severity: critical
>Priority: high
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: sw-bug
>Submitter-Id: current-users
>Arrival-Date: Sat Feb 26 09:40:14 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator: Daichi GOTO
>Release: FreeBSD 5.3-RELEASE-p5 i386
>Organization:
ONGS Inc.
>Environment:
System: FreeBSD parancell.ongs.co.jp 5.3-RELEASE-p5 FreeBSD 5.3-RELEASE-p5 #0: Thu Feb 3 14:43:53 JST 2005 root at parancell.ongs.co.jp:/usr/obj/usr/src/sys/GENERIC i386
>Description:
Current mount_smbfs can not treat multibyte characters correctly.
description as follow and those threads:
http://home.jp.freebsd.org/cgi-bin/showmail/FreeBSD-users-jp/73012
http://home.jp.freebsd.org/cgi-bin/showmail/FreeBSD-users-jp/73034
I had found that src/contrib/smbfs/lib/smb/ctx.c caused problem.
The ctx.c transforms charactor as 1 byte only. This is problem.
>How-To-Repeat:
Do mount_smbfs with -E EUC-JP:CP932 option. You cannot use it correctly.
>Fix:
Please merge patch as follow. I expect that this correction is merged by
FreeBSD 5.4-RELEASE.
diff -urN src.orig/contrib/smbfs/lib/smb/ctx.c src/contrib/smbfs/lib/smb/ctx.c
--- src.orig/contrib/smbfs/lib/smb/ctx.c Sun Jul 27 20:41:38 2003
+++ src/contrib/smbfs/lib/smb/ctx.c Fri Feb 25 22:55:12 2005
@@ -473,8 +473,6 @@
struct sockaddr *sap;
struct sockaddr_nb *salocal, *saserver;
char *cp;
- u_char cstbl[256];
- u_int i;
int error = 0;
ctx->ct_flags &= ~SMBCF_RESOLVED;
@@ -496,7 +494,7 @@
if (error)
return error;
if (ssn->ioc_localcs[0] == 0)
- strcpy(ssn->ioc_localcs, "default"); /* XXX: locale name ? */
+ strcpy(ssn->ioc_localcs, "ISO8859-1");
error = smb_addiconvtbl("tolower", ssn->ioc_localcs, nls_lower);
if (error)
return error;
@@ -504,18 +502,9 @@
if (error)
return error;
if (ssn->ioc_servercs[0] != 0) {
- for(i = 0; i < sizeof(cstbl); i++)
- cstbl[i] = i;
- nls_mem_toext(cstbl, cstbl, sizeof(cstbl));
- error = smb_addiconvtbl(ssn->ioc_servercs, ssn->ioc_localcs, cstbl);
- if (error)
- return error;
- for(i = 0; i < sizeof(cstbl); i++)
- cstbl[i] = i;
- nls_mem_toloc(cstbl, cstbl, sizeof(cstbl));
- error = smb_addiconvtbl(ssn->ioc_localcs, ssn->ioc_servercs, cstbl);
- if (error)
- return error;
+ error = kiconv_add_xlat16_cspairs
+ (ssn->ioc_localcs, ssn->ioc_servercs);
+ if (error) return error;
}
if (ctx->ct_srvaddr) {
error = nb_resolvehost_in(ctx->ct_srvaddr, &sap);
diff -urN src.orig/lib/libsmb/Makefile src/lib/libsmb/Makefile
--- src.orig/lib/libsmb/Makefile Sat Sep 28 09:25:31 2002
+++ src/lib/libsmb/Makefile Fri Feb 25 22:56:00 2005
@@ -12,6 +12,7 @@
nb.c nb_name.c nb_net.c nbns_rq.c
CONTRIBDIR= ${.CURDIR}/../../contrib/smbfs
CFLAGS+= -DSMB_CFG_FILE=\"/etc/nsmb.conf\" -I${CONTRIBDIR}/include
+LDFLAGS+= -lkiconv
.PATH: ${CONTRIBDIR}/lib/smb
diff -urN src.orig/sys/fs/smbfs/smbfs_smb.c src/sys/fs/smbfs/smbfs_smb.c
--- src.orig/sys/fs/smbfs/smbfs_smb.c Mon Jan 12 23:43:49 2004
+++ src/sys/fs/smbfs/smbfs_smb.c Fri Feb 25 22:53:06 2005
@@ -1449,8 +1449,8 @@
continue;
break;
}
- smbfs_fname_tolocal(SSTOVC(ctx->f_ssp), ctx->f_name, ctx->f_nmlen,
- ctx->f_dnp->n_mount->sm_caseopt);
+ smbfs_fname_tolocal(SSTOVC(ctx->f_ssp), ctx->f_name, &ctx->f_nmlen,
+ ctx->f_dnp->n_mount->sm_caseopt);
ctx->f_attr.fa_ino = smbfs_getino(ctx->f_dnp, ctx->f_name, ctx->f_nmlen);
return 0;
}
diff -urN src.orig/sys/fs/smbfs/smbfs_subr.c src/sys/fs/smbfs/smbfs_subr.c
--- src.orig/sys/fs/smbfs/smbfs_subr.c Sun Jun 15 00:24:54 2003
+++ src/sys/fs/smbfs/smbfs_subr.c Fri Feb 25 22:53:06 2005
@@ -316,13 +316,33 @@
}
int
-smbfs_fname_tolocal(struct smb_vc *vcp, char *name, int nmlen, int caseopt)
+smbfs_fname_tolocal(struct smb_vc *vcp, char *name, int *nmlen, int caseopt)
{
-/* if (caseopt & SMB_CS_UPPER)
- iconv_convmem(vcp->vc_toupper, name, name, nmlen);
- else if (caseopt & SMB_CS_LOWER)
- iconv_convmem(vcp->vc_tolower, name, name, nmlen);*/
- if (vcp->vc_tolocal)
- iconv_convmem(vcp->vc_tolocal, name, name, nmlen);
- return 0;
+ int copt = (caseopt == SMB_CS_LOWER ? KICONV_FROM_LOWER :
+ (caseopt == SMB_CS_UPPER ? KICONV_FROM_UPPER : 0));
+ int error = 0;
+ int ilen = *nmlen;
+ int olen;
+ char *ibuf = name;
+ char outbuf[SMB_MAXFNAMELEN];
+ char *obuf = outbuf;
+
+ if (vcp->vc_tolocal) {
+ olen = sizeof(outbuf);
+ bzero(outbuf, sizeof(outbuf));
+
+ /*
+ error = iconv_conv_case
+ (vcp->vc_tolocal, NULL, NULL, &obuf, &olen, copt);
+ if (error) return error;
+ */
+
+ error = iconv_conv_case
+ (vcp->vc_tolocal, &ibuf, &ilen, &obuf, &olen, copt);
+ if (!error) {
+ *nmlen = sizeof(outbuf) - olen;
+ memcpy(name, outbuf, *nmlen);
+ }
+ }
+ return error;
}
diff -urN src.orig/sys/fs/smbfs/smbfs_subr.h src/sys/fs/smbfs/smbfs_subr.h
--- src.orig/sys/fs/smbfs/smbfs_subr.h Wed Sep 18 18:27:04 2002
+++ src/sys/fs/smbfs/smbfs_subr.h Fri Feb 25 22:53:06 2005
@@ -177,7 +177,7 @@
int smbfs_smb_lookup(struct smbnode *dnp, const char *name, int nmlen,
struct smbfattr *fap, struct smb_cred *scred);
-int smbfs_fname_tolocal(struct smb_vc *vcp, char *name, int nmlen, int caseopt);
+int smbfs_fname_tolocal(struct smb_vc *vcp, char *name, int *nmlen, int caseopt);
void smb_time_local2server(struct timespec *tsp, int tzoff, u_long *seconds);
void smb_time_server2local(u_long seconds, int tzoff, struct timespec *tsp);
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list