From ba54ba03262e851ddbecfdfc160a25a692b078e2 Mon Sep 17 00:00:00 2001 From: Steve French Date: Mon, 28 Nov 2005 05:43:21 +0000 Subject: r11938: Fix cifs to handle non-numeric uid and gid parameters and merge trunk and SAMBA_3 versions of mount.cifs and cleanup cifs vfs help. Modified version of patch from Olaf Kirch for Novell Bug 120601 (This used to be commit 0981552deab9f73d2f784e5da52878ffdf845031) --- source3/client/mount.cifs.c | 164 ++++++++++++++++++++++++++++++++------------ 1 file changed, 122 insertions(+), 42 deletions(-) (limited to 'source3/client') diff --git a/source3/client/mount.cifs.c b/source3/client/mount.cifs.c index 5750deb31c..ed88c92c62 100755 --- a/source3/client/mount.cifs.c +++ b/source3/client/mount.cifs.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -39,7 +40,7 @@ #include #define MOUNT_CIFS_VERSION_MAJOR "1" -#define MOUNT_CIFS_VERSION_MINOR "8" +#define MOUNT_CIFS_VERSION_MINOR "10" #ifndef MOUNT_CIFS_VENDOR_SUFFIX #define MOUNT_CIFS_VENDOR_SUFFIX "" @@ -83,11 +84,16 @@ static void mount_cifs_usage(void) printf(" to a local directory.\n\nOptions:\n"); printf("\tuser=\n\tpass=\n\tdom=\n"); printf("\nLess commonly used options:"); - printf("\n\tcredentials=,guest,perm,noperm,setuids,nosetuids,rw,ro,\n\tsep=,iocharset=,suid,nosuid,exec,noexec,serverino,\n\tdirectio,mapchars,nomapchars"); - printf("\n\nOptions not needed for servers supporting CIFS Unix extensions\n\t(e.g. most Samba versions):"); - printf("\n\tuid=,gid=,dir_mode=,file_mode="); + printf("\n\tcredentials=,guest,perm,noperm,setuids,nosetuids,rw,ro,"); + printf("\n\tsep=,iocharset=,suid,nosuid,exec,noexec,serverino,"); + printf("\n\tdirectio,mapchars,nomapchars,nolock,servernetbiosname="); + printf("\n\nOptions not needed for servers supporting CIFS Unix extensions"); + printf("\n\t(e.g. unneeded for mounts to most Samba versions):"); + printf("\n\tuid=,gid=,dir_mode=,file_mode=,sfu"); printf("\n\nRarely used options:"); - printf("\n\tport=,rsize=,wsize=,unc=,ip=,\n\tdev,nodev,nouser_xattr,netbiosname,hard,soft,intr,nointr,noacl"); + printf("\n\tport=,rsize=,wsize=,unc=,ip=,"); + printf("\n\tdev,nodev,nouser_xattr,netbiosname=,hard,soft,intr,"); + printf("\n\tnointr,ignorecase,noposixpaths,noacl"); printf("\n\nOptions are described in more detail in the manual page"); printf("\n\tman 8 mount.cifs\n"); printf("\nTo display the version number of the mount helper:"); @@ -127,8 +133,10 @@ static int open_cred_file(char * file_name) if(fs == NULL) return errno; line_buf = malloc(4096); - if(line_buf == NULL) + if(line_buf == NULL) { + fclose(fs); return -ENOMEM; + } while(fgets(line_buf,4096,fs)) { /* parse line from credential file */ @@ -282,21 +290,23 @@ static int get_password_from_file(int file_descript, char * filename) return rc; } -static int parse_options(char * options, int * filesys_flags) +static int parse_options(char ** optionsp, int * filesys_flags) { char * data; char * percent_char = NULL; char * value = NULL; char * next_keyword = NULL; + char * out = NULL; + int out_len = 0; + int word_len; int rc = 0; - if (!options) + if (!optionsp || !*optionsp) return 1; - else - data = options; + data = *optionsp; if(verboseflag) - printf("parsing options: %s\n", options); + printf("parsing options: %s\n", data); /* BB fixme check for separator override BB */ @@ -314,7 +324,7 @@ static int parse_options(char * options, int * filesys_flags) /* temporarily null terminate end of keyword=value pair */ if(next_keyword) - *next_keyword = 0; + *next_keyword++ = 0; /* temporarily null terminate keyword to make keyword and value distinct */ if ((value = strchr(data, '=')) != NULL) { @@ -324,7 +334,7 @@ static int parse_options(char * options, int * filesys_flags) if (strncmp(data, "users",5) == 0) { if(!value || !*value) { - strncpy(data,",,,,,",5); + goto nocopy; } } else if (strncmp(data, "user_xattr",10) == 0) { /* do nothing - need to skip so not parsed as user name */ @@ -336,10 +346,7 @@ static int parse_options(char * options, int * filesys_flags) printf("\nskipping empty user mount parameter\n"); /* remove the parm since it would otherwise be confusing to the kernel code which would think it was a real username */ - data[0] = ','; - data[1] = ','; - data[2] = ','; - data[3] = ','; + goto nocopy; } else { printf("username specified with no parameter\n"); return 1; /* needs_arg; */ @@ -458,10 +465,34 @@ static int parse_options(char * options, int * filesys_flags) } else if (strncmp(data, "uid", 3) == 0) { if (value && *value) { got_uid = 1; + if (!isdigit(*value)) { + struct passwd *pw; + static char temp[32]; + + if (!(pw = getpwnam(value))) { + printf("bad user name \"%s\"\n", value); + exit(1); + } + sprintf(temp, "%u", pw->pw_uid); + value = temp; + endpwent(); + } } } else if (strncmp(data, "gid", 3) == 0) { if (value && *value) { got_gid = 1; + if (!isdigit(*value)) { + struct group *gr; + static char temp[32]; + + if (!(gr = getgrnam(value))) { + printf("bad group name \"%s\"\n", value); + exit(1); + } + sprintf(temp, "%u", gr->gr_gid); + value = temp; + endpwent(); + } } /* fmask and dmask synonyms for people used to smbfs syntax */ } else if (strcmp(data, "file_mode") == 0 || strcmp(data, "fmask")==0) { @@ -504,6 +535,9 @@ static int parse_options(char * options, int * filesys_flags) *filesys_flags &= ~MS_NOSUID; } else if (strncmp(data, "nodev", 5) == 0) { *filesys_flags |= MS_NODEV; + } else if ((strncmp(data, "nobrl", 5) == 0) || + (strncmp(data, "nolock", 6) == 0)) { + *filesys_flags &= ~MS_MANDLOCK; } else if (strncmp(data, "dev", 3) == 0) { *filesys_flags &= ~MS_NODEV; } else if (strncmp(data, "noexec", 6) == 0) { @@ -513,11 +547,7 @@ static int parse_options(char * options, int * filesys_flags) } else if (strncmp(data, "guest", 5) == 0) { got_password=1; /* remove the parm since it would otherwise be logged by kern */ - data[0] = ','; - data[1] = ','; - data[2] = ','; - data[3] = ','; - data[4] = ','; + goto nocopy; } else if (strncmp(data, "ro", 2) == 0) { *filesys_flags |= MS_RDONLY; } else if (strncmp(data, "rw", 2) == 0) { @@ -545,21 +575,29 @@ static int parse_options(char * options, int * filesys_flags) } */ /* nothing to do on those four mount options above. Just pass to kernel and ignore them here */ - /* move to next option */ - data = next_keyword+1; + /* Copy (possibly modified) option to out */ + word_len = strlen(data); + if (value) + word_len += 1 + strlen(value); - /* put overwritten equals sign back */ - if(value) { - value--; - *value = '='; + out = realloc(out, out_len + word_len + 2); + if (out == NULL) { + perror("malloc"); + exit(1); } - - /* put previous overwritten comma back */ - if(next_keyword) - *next_keyword = ','; /* BB handle sep= */ + + if (out_len) + out[out_len++] = ','; + if (value) + sprintf(out + out_len, "%s=%s", data, value); else - data = NULL; + sprintf(out + out_len, "%s", data); + out_len = strlen(out); + +nocopy: + data = next_keyword; } + *optionsp = out; return 0; } @@ -570,13 +608,15 @@ static void check_for_comma(char ** ppasswrd) char *pass; int i,j; int number_of_commas = 0; - int len = strlen(*ppasswrd); + int len; if(ppasswrd == NULL) return; else (pass = *ppasswrd); + len = strlen(pass); + for(i=0;i 1023) { printf("mount error: UNC name too long"); @@ -715,6 +754,13 @@ static char * parse_server(char ** punc_name) if(share) { free_share_name = 1; *punc_name = malloc(length+3); + if(*punc_name == NULL) { + /* put the original string back if + no memory left */ + *punc_name = unc_name; + return NULL; + } + *share = '/'; strncpy((*punc_name)+2,unc_name,length); unc_name = *punc_name; @@ -744,8 +790,7 @@ continue_unc_parsing: return NULL; } if(host_entry == NULL) { - printf("mount error: could not find target server. TCP name %s not found ", unc_name); - printf(" rc = %d\n",rc); + printf("mount error: could not find target server. TCP name %s not found\n", unc_name); return NULL; } else { /* BB should we pass an alternate version of the share name as Unicode */ @@ -905,10 +950,44 @@ int main(int argc, char ** argv) wsize = atoi(optarg); break; case '1': - uid = atoi(optarg); + if (isdigit(*optarg)) { + char *ep; + + uid = strtoul(optarg, &ep, 10); + if (*ep) { + printf("bad uid value \"%s\"\n", optarg); + exit(1); + } + } else { + struct passwd *pw; + + if (!(pw = getpwnam(optarg))) { + printf("bad user name \"%s\"\n", optarg); + exit(1); + } + uid = pw->pw_uid; + endpwent(); + } break; case '2': - gid = atoi(optarg); + if (isdigit(*optarg)) { + char *ep; + + gid = strtoul(optarg, &ep, 10); + if (*ep) { + printf("bad gid value \"%s\"\n", optarg); + exit(1); + } + } else { + struct group *gr; + + if (!(gr = getgrnam(optarg))) { + printf("bad user name \"%s\"\n", optarg); + exit(1); + } + gid = gr->gr_gid; + endpwent(); + } break; case 'u': got_user = 1; @@ -954,7 +1033,7 @@ int main(int argc, char ** argv) get_password_from_file(0, getenv("PASSWD_FILE")); } - if (orgoptions && parse_options(orgoptions, &flags)) + if (orgoptions && parse_options(&orgoptions, &flags)) return -1; ipaddr = parse_server(&share_name); if((ipaddr == NULL) && (got_ip == 0)) { @@ -1018,6 +1097,9 @@ mount_retry: optlen = 0; if(share_name) optlen += strlen(share_name) + 4; + else { + printf("No server share name specified\n"); + } if(user_name) optlen += strlen(user_name) + 6; if(ipaddr) @@ -1126,8 +1208,6 @@ mount_retry: strcat(mountent.mnt_opts,"rw"); if(flags & MS_MANDLOCK) strcat(mountent.mnt_opts,",mand"); - else - strcat(mountent.mnt_opts,",nomand"); if(flags & MS_NOEXEC) strcat(mountent.mnt_opts,",noexec"); if(flags & MS_NOSUID) -- cgit