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 256911 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 (try 2)
0001-mount.cifs-fix-handling-of-subdirectories-of-shares.patch (text/plain), 7.77 KB, created by
Jeff Layton
on 2007-11-13 14:36:34 UTC
(
hide
)
Description:
patch -- fix several problems with subshare mounts (try 2)
Filename:
MIME Type:
Creator:
Jeff Layton
Created:
2007-11-13 14:36:34 UTC
Size:
7.77 KB
patch
obsolete
>To: "Steve French" <smfrench@gmail.com> >Cc: linux-cifs-client@lists.samba.org, samba-technical@lists.samba.org >From: Jeff Layton <jlayton@redhat.com> >Subject: [PATCH] mount.cifs: fix several problems when mounting subdirectories of shares > >This is essentially the same patch as I posted yesterday. The only >difference is that I added the replace_char helper function and now >have the code call it instead of doing the conversion internally. > >Thoughts? > >-------[snip]------- > >CIFS has a few problems when mounting subdirectories of shares: > >a) mount.cifs 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 into the beginning of a path when it builds one from a dentry, >and this confuses windows servers (samba doesn't seem to care). > >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 > >d) If the client has to retry the mount with an uppercase sharename, it >doesn't also uppercase the prefixpath (not sure if that's a real issue, >but it seems inconsistent). > >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(), and to >setmntent(). > >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). > >Signed-off-by: Jeff Layton <jlayton@redhat.com> >--- > source/client/mount.cifs.c | 90 +++++++++++++++++++++++++++++++------------- > 1 files changed, 64 insertions(+), 26 deletions(-) > >diff --git a/source/client/mount.cifs.c b/source/client/mount.cifs.c >index eb45ae5..d21b0fe 100644 >--- a/source/client/mount.cifs.c >+++ b/source/client/mount.cifs.c >@@ -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_ip = 0; > 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; >@@ -747,17 +748,27 @@ static char * check_for_domain(char **ppuser) > return domainnm; > } > >+/* replace all occurances of "from" in a string with "to" */ >+static void replace_char(char *string, char from, char to) >+{ >+ while (string) { >+ string = strchr(string, from); >+ if (string) >+ *string = to; >+ } >+} >+ > /* Note that caller frees the returned buffer if necessary */ > static char * parse_server(char ** punc_name) > { > char * unc_name = *punc_name; >- int length = strnlen(unc_name,1024); >+ 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 +787,6 @@ static char * parse_server(char ** punc_name) > /* 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 +794,9 @@ static char * parse_server(char ** punc_name) > *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 +807,21 @@ static char * parse_server(char ** punc_name) > } > } 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 '\\' */ >+ replace_char(unc_name, '/', '\\'); >+ >+ 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 +886,25 @@ static struct option longopts[] = { > { 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 +917,7 @@ int main(int argc, char ** argv) > char * options = NULL; > char * resolved_path = NULL; > char * temp; >+ char * dev_name; > int rc; > int rsize = 0; > int wsize = 0; >@@ -920,8 +953,16 @@ int main(int argc, char ** argv) > 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 +1102,7 @@ int main(int argc, char ** argv) > } > } > >- if((argc < 3) || (share_name == NULL) || (mountpoint == NULL)) { >+ if((argc < 3) || (dev_name == NULL) || (mountpoint == NULL)) { > mount_cifs_usage(); > exit(1); > } >@@ -1219,10 +1260,12 @@ mount_retry: > } > if(verboseflag) > printf("\nmount.cifs kernel mount options %s \n",options); >- if(mount(share_name, mountpoint, "cifs", flags, options)) { >- /* remember to kill daemon on error */ >- char * tmp; > >+ /* convert all '\\' to '/' so that /proc/mounts looks pretty */ >+ replace_char(dev_name, '\\', '/'); >+ >+ if(mount(dev_name, mountpoint, "cifs", flags, options)) { >+ /* remember to kill daemon on error */ > switch (errno) { > case 0: > printf("mount failed but no error number set\n"); >@@ -1233,12 +1276,9 @@ mount_retry: > 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 +1292,7 @@ mount_retry: > } 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 +1352,7 @@ mount_exit: > free(resolved_path); > } > >- if(free_share_name) { >- free(share_name); >- } >+ free(share_name); > return rc; > } > >-- >1.5.3.3 >
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