Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 253241 Details for
Bug 370501
mounting CIFS subshare doesn't autoconvert prepath delimiters
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
patch -- fix several problems with subshare mounts
samba-3.2-mount.cifs-normalize-unc.patch (text/plain), 6.58 KB, created by
Jeff Layton
on 2007-11-09 18:55:48 UTC
(
hide
)
Description:
patch -- fix several problems with subshare mounts
Filename:
MIME Type:
Creator:
Jeff Layton
Created:
2007-11-09 18:55:48 UTC
Size:
6.58 KB
patch
obsolete
>From: Jeff Layton <jlayton@redhat.com> >To: linux-cifs-client@lists.samba.org, samba-technical@lists.samba.org >Subject: [PATCH] mount.cifs: fix subshare mount handling > >CIFS has a few problems when mounting subdirectories of shares: > >a) cifs.mount assumes that the prefixpath will always begin with a forward >slash. If it begins with a backslash, then it fails to parse out the >prefixpath and leaves it appended to the sharename. This causes the mount >to fail. > >b) if the prefixpath uses '/' as a delimiter, it doesn't convert that to >a "native" prefixpath ('\\' delimiter). The kernel will blindly stuff this >prefix at the beginning of a path when it builds one from a dentry, and >this confuses windows servers. > >c) When you mount a subdir of a share, mount.cifs munges the device string >so that you can't tell what the prefixpath is. So if I mount: > >//server/share/p1/p2/p3 > >...then /proc/mounts and mtab will show only: > >//server/share > >The following patch fixes all of these problems. It separates the "share_name" >from the "device_name", and passes the "share_name" as the unc= string, and >the device_name as the first arg to mount(). > >It also changes mount.cifs to use '\\' exclusively as a delimiter for the >unc= and prefixpath= options, and to use '/' exclusively as a delimiter in >the device string (seemingly necessary since the kernel doesn't deal well with >backslashes in the device string). > >Thoughts? > >Signed-off-by: Jeff Layton <jlayton@redhat.com> > >Index: samba3/source/client/mount.cifs.c >=================================================================== >--- samba3/source/client/mount.cifs.c (revision 25913) >+++ samba3/source/client/mount.cifs.c (working copy) >@@ -62,6 +62,8 @@ > #define MS_BIND 4096 > #endif > >+#define MAX_UNC_LEN 1024 >+ > #define CONST_DISCARD(type, ptr) ((type) ((void *) (ptr))) > > const char *thisprogram; >@@ -73,7 +75,6 @@ > static int got_unc = 0; > static int got_uid = 0; > static int got_gid = 0; >-static int free_share_name = 0; > static char * user_name = NULL; > static char * mountpassword = NULL; > char * domain_name = NULL; >@@ -751,13 +752,14 @@ > static char * parse_server(char ** punc_name) > { > char * unc_name = *punc_name; >- int length = strnlen(unc_name,1024); >+ char *tmp; >+ int length = strnlen(unc_name, MAX_UNC_LEN); > char * share; > char * ipaddress_string = NULL; > struct hostent * host_entry = NULL; > struct in_addr server_ipaddr; > >- if(length > 1023) { >+ if(length > (MAX_UNC_LEN - 1)) { > printf("mount error: UNC name too long"); > return NULL; > } >@@ -776,7 +778,6 @@ > /* check for nfs syntax ie server:share */ > share = strchr(unc_name,':'); > if(share) { >- free_share_name = 1; > *punc_name = (char *)malloc(length+3); > if(*punc_name == NULL) { > /* put the original string back if >@@ -784,9 +785,9 @@ > *punc_name = unc_name; > return NULL; > } >- > *share = '/'; > strncpy((*punc_name)+2,unc_name,length); >+ free(unc_name); > unc_name = *punc_name; > unc_name[length+2] = 0; > goto continue_unc_parsing; >@@ -797,18 +798,26 @@ > } > } else { > continue_unc_parsing: >- unc_name[0] = '/'; >- unc_name[1] = '/'; >+ unc_name[0] = '\\'; >+ unc_name[1] = '\\'; > unc_name += 2; >- if ((share = strchr(unc_name, '/')) || >- (share = strchr(unc_name,'\\'))) { >+ >+ /* convert any '/' in unc to '\\' */ >+ tmp = unc_name; >+ while(tmp) { >+ tmp = strchr(tmp, '/'); >+ if (tmp) >+ *tmp = '\\'; >+ } >+ >+ if ((share = strchr(unc_name,'\\'))) { > *share = 0; /* temporarily terminate the string */ > share += 1; > if(got_ip == 0) { > host_entry = gethostbyname(unc_name); > } >- *(share - 1) = '/'; /* put the slash back */ >- if ((prefixpath = strchr(share, '/'))) { >+ *(share - 1) = '\\'; /* put delimiter back */ >+ if ((prefixpath = strchr(share, '\\'))) { > *prefixpath = 0; /* permanently terminate the string */ > if (!strlen(++prefixpath)) > prefixpath = NULL; /* this needs to be done explicitly */ >@@ -873,6 +882,25 @@ > { NULL, 0, NULL, 0 } > }; > >+/* convert a string to uppercase. return false if the string >+ * wasn't ASCII or was a NULL ptr */ >+static int >+uppercase_string(char *string) >+{ >+ if (!string) >+ return 0; >+ >+ while (*string) { >+ /* check for unicode */ >+ if ((unsigned char) string[0] & 0x80) >+ return 0; >+ *string = toupper((unsigned char) *string); >+ string++; >+ } >+ >+ return 1; >+} >+ > int main(int argc, char ** argv) > { > int c; >@@ -885,6 +913,7 @@ > char * options = NULL; > char * resolved_path = NULL; > char * temp; >+ char * dev_name; > int rc; > int rsize = 0; > int wsize = 0; >@@ -920,8 +949,16 @@ > printf(" node: %s machine: %s sysname %s domain %s\n", sysinfo.nodename,sysinfo.machine,sysinfo.sysname,sysinfo.domainname); > #endif */ > if(argc > 2) { >- share_name = argv[1]; >+ dev_name = argv[1]; >+ share_name = strndup(argv[1], MAX_UNC_LEN); >+ if (share_name == NULL) { >+ fprintf(stderr, "%s: %s", argv[0], strerror(ENOMEM)); >+ exit(1); >+ } > mountpoint = argv[2]; >+ } else { >+ mount_cifs_usage(); >+ exit(1); > } > > /* add sharename in opts string as unc= parm */ >@@ -1061,7 +1098,7 @@ > } > } > >- if((argc < 3) || (share_name == NULL) || (mountpoint == NULL)) { >+ if((argc < 3) || (dev_name == NULL) || (mountpoint == NULL)) { > mount_cifs_usage(); > exit(1); > } >@@ -1219,10 +1256,17 @@ > } > if(verboseflag) > printf("\nmount.cifs kernel mount options %s \n",options); >- if(mount(share_name, mountpoint, "cifs", flags, options)) { >+ >+ /* convert all '\\' to '/' so that /proc/mounts looks pretty */ >+ temp = dev_name; >+ while(*temp) { >+ if (*temp == '\\') >+ *temp = '/'; >+ ++temp; >+ } >+ >+ if(mount(dev_name, mountpoint, "cifs", flags, options)) { > /* remember to kill daemon on error */ >- char * tmp; >- > switch (errno) { > case 0: > printf("mount failed but no error number set\n"); >@@ -1233,12 +1277,9 @@ > case ENXIO: > if(retry == 0) { > retry = 1; >- tmp = share_name; >- while (*tmp && !(((unsigned char)tmp[0]) & 0x80)) { >- *tmp = toupper((unsigned char)*tmp); >- tmp++; >- } >- if(!*tmp) { >+ if (uppercase_string(dev_name) && >+ uppercase_string(share_name) && >+ uppercase_string(prefixpath)) { > printf("retrying with upper case share name\n"); > goto mount_retry; > } >@@ -1252,7 +1293,7 @@ > } else { > pmntfile = setmntent(MOUNTED, "a+"); > if(pmntfile) { >- mountent.mnt_fsname = share_name; >+ mountent.mnt_fsname = dev_name; > mountent.mnt_dir = mountpoint; > mountent.mnt_type = CONST_DISCARD(char *,"cifs"); > mountent.mnt_opts = (char *)malloc(220); >@@ -1312,9 +1353,7 @@ > free(resolved_path); > } > >- if(free_share_name) { >- free(share_name); >- } >+ free(share_name); > return rc; > } >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 370501
:
251461
|
251491
|
252171
|
252681
|
253241
|
256911