diff options
Diffstat (limited to 'source/client/mount.cifs.c')
-rwxr-xr-x | source/client/mount.cifs.c | 153 |
1 files changed, 112 insertions, 41 deletions
diff --git a/source/client/mount.cifs.c b/source/client/mount.cifs.c index 8c23cc22123..a2f9ebf45ca 100755 --- a/source/client/mount.cifs.c +++ b/source/client/mount.cifs.c @@ -38,12 +38,16 @@ #include <fcntl.h> #define MOUNT_CIFS_VERSION_MAJOR "1" -#define MOUNT_CIFS_VERSION_MINOR "0" +#define MOUNT_CIFS_VERSION_MINOR "2" #ifndef MOUNT_CIFS_VENDOR_SUFFIX #define MOUNT_CIFS_VENDOR_SUFFIX "" #endif +#ifndef MS_MOVE +#define MS_MOVE 8192 +#endif + char * thisprogram; int verboseflag = 0; static int got_password = 0; @@ -113,19 +117,20 @@ static int open_cred_file(char * file_name) /* eat leading white space */ for(i=0;i<4096;i++) { - if(line_buf[i] == '\0') - break; - else if((line_buf[i] != ' ') && (line_buf[i] != '\t')) + if((line_buf[i] != ' ') && (line_buf[i] != '\t')) break; + /* if whitespace - skip past it */ line_buf++; } - if (strncasecmp("username",line_buf,8) == 0) { temp_val = strchr(line_buf + i,'='); if(temp_val) { /* go past equals sign */ temp_val++; - length = strlen(temp_val); + for(length = 0;length<4087;length++) { + if(temp_val[length] == '\n') + break; + } if(length > 4086) { printf("cifs.mount failed due to malformed username in credentials file"); memset(line_buf,0,4096); @@ -146,7 +151,10 @@ static int open_cred_file(char * file_name) if(temp_val) { /* go past equals sign */ temp_val++; - length = strlen(temp_val); + for(length = 0;length<65;length++) { + if(temp_val[length] == '\n') + break; + } if(length > 64) { printf("cifs.mount failed: password in credentials file too long\n"); memset(line_buf,0, 4096); @@ -157,9 +165,11 @@ static int open_cred_file(char * file_name) } else { if(mountpassword == NULL) { mountpassword = calloc(65,1); - } + } else + memset(mountpassword,0,64); if(mountpassword) { - strncpy(mountpassword,temp_val,64); + /* BB add handling for commas in password here */ + strncpy(mountpassword,temp_val,length); got_password = 1; } } @@ -227,7 +237,7 @@ static int get_password_from_file(int file_descript, char * filename) return rc; } -static int parse_options(char * options) +static int parse_options(char * options, int * filesys_flags) { char * data; char * percent_char = 0; @@ -394,7 +404,7 @@ static int parse_options(char * options) if (strcmp (data, "fmask") == 0) { printf ("WARNING: CIFS mount option 'fmask' is deprecated. Use 'file_mode' instead.\n"); - data = "file_mode"; + data = "file_mode"; /* BB fix this */ } } else if (strcmp(data, "dir_mode") == 0 || strcmp(data, "dmask")==0) { if (!value || !*value) { @@ -410,29 +420,50 @@ static int parse_options(char * options) printf ("WARNING: CIFS mount option 'dmask' is deprecated. Use 'dir_mode' instead.\n"); data = "dir_mode"; } + /* the following eight mount options should be + stripped out from what is passed into the kernel + since these eight options are best passed as the + mount flags rather than redundantly to the kernel + and could generate spurious warnings depending on the + level of the corresponding cifs vfs kernel code */ + } else if (strncmp(data, "nosuid", 6) == 0) { + *filesys_flags |= MS_NOSUID; + } else if (strncmp(data, "suid", 4) == 0) { + *filesys_flags &= ~MS_NOSUID; + } else if (strncmp(data, "nodev", 5) == 0) { + *filesys_flags |= MS_NODEV; + } else if (strncmp(data, "dev", 3) == 0) { + *filesys_flags &= ~MS_NODEV; + } else if (strncmp(data, "noexec", 6) == 0) { + *filesys_flags |= MS_NOEXEC; + } else if (strncmp(data, "exec", 4) == 0) { + *filesys_flags &= ~MS_NOEXEC; + } else if (strncmp(data, "ro", 2) == 0) { + *filesys_flags |= MS_RDONLY; + } else if (strncmp(data, "rw", 2) == 0) { + *filesys_flags &= ~MS_RDONLY; } /* else if (strnicmp(data, "port", 4) == 0) { - if (value && *value) { - vol->port = - simple_strtoul(value, &value, 0); - } - } else if (strnicmp(data, "rsize", 5) == 0) { - if (value && *value) { - vol->rsize = - simple_strtoul(value, &value, 0); - } - } else if (strnicmp(data, "wsize", 5) == 0) { - if (value && *value) { - vol->wsize = - simple_strtoul(value, &value, 0); - } - } else if (strnicmp(data, "version", 3) == 0) { - - } else if (strnicmp(data, "rw", 2) == 0) { - - } else - printf("CIFS: Unknown mount option %s\n",data); */ + if (value && *value) { + vol->port = + simple_strtoul(value, &value, 0); + } + } else if (strnicmp(data, "rsize", 5) == 0) { + if (value && *value) { + vol->rsize = + simple_strtoul(value, &value, 0); + } + } else if (strnicmp(data, "wsize", 5) == 0) { + if (value && *value) { + vol->wsize = + simple_strtoul(value, &value, 0); + } + } else if (strnicmp(data, "version", 3) == 0) { + } else { + printf("CIFS: Unknown mount option %s\n",data); + } */ /* nothing to do on those four mount options above. + Just pass to kernel and ignore them here */ - /* move to next option */ + /* move to next option */ data = next_keyword+1; /* put overwritten equals sign back */ @@ -440,7 +471,7 @@ static int parse_options(char * options) value--; *value = '='; } - + /* put previous overwritten comma back */ if(next_keyword) *next_keyword = ','; @@ -522,7 +553,9 @@ char * parse_server(char * unc_name) static struct option longopts[] = { { "all", 0, 0, 'a' }, - { "help", 0, 0, 'h' }, + { "help",0, 0, 'h' }, + { "move",0, 0, 'm' }, + { "bind",0, 0, 'b' }, { "read-only", 0, 0, 'r' }, { "ro", 0, 0, 'r' }, { "verbose", 0, 0, 'v' }, @@ -530,12 +563,11 @@ static struct option longopts[] = { { "read-write", 0, 0, 'w' }, { "rw", 0, 0, 'w' }, { "options", 1, 0, 'o' }, - { "types", 1, 0, 't' }, + { "type", 1, 0, 't' }, { "rsize",1, 0, 'R' }, { "wsize",1, 0, 'W' }, { "uid", 1, 0, '1'}, { "gid", 1, 0, '2'}, - { "uuid",1,0,'U' }, { "user",1,0,'u'}, { "username",1,0,'u'}, { "dom",1,0,'d'}, @@ -544,13 +576,14 @@ static struct option longopts[] = { { "pass",1,0,'p'}, { "credentials",1,0,'c'}, { "port",1,0,'P'}, + /* { "uuid",1,0,'U'}, */ /* BB unimplemented */ { NULL, 0, 0, 0 } }; int main(int argc, char ** argv) { int c; - int flags = MS_MANDLOCK | MS_MGC_VAL; + int flags = MS_MANDLOCK; /* no need to set legacy MS_MGC_VAL */ char * orgoptions = NULL; char * share_name = NULL; char * domain_name = NULL; @@ -615,6 +648,12 @@ int main(int argc, char ** argv) case 'n': ++nomtab; break; + case 'b': + flags |= MS_BIND; + break; + case 'm': + flags |= MS_MOVE; + break; case 'o': orgoptions = strdup(optarg); break; @@ -693,7 +732,7 @@ int main(int argc, char ** argv) ipaddr = parse_server(share_name); - if (orgoptions && parse_options(orgoptions)) + if (orgoptions && parse_options(orgoptions, &flags)) return 1; /* BB save off path and pop after mount returns? */ @@ -701,9 +740,10 @@ int main(int argc, char ** argv) if(chdir(mountpoint)) { printf("mount error: can not change directory into mount target %s\n",mountpoint); + return -1; } - if(stat (mountpoint, &statbuf)) { + if(stat (".", &statbuf)) { printf("mount error: mount point %s does not exist\n",mountpoint); return -1; } @@ -715,7 +755,11 @@ int main(int argc, char ** argv) if((getuid() != 0) && (geteuid() == 0)) { if((statbuf.st_uid == getuid()) && (S_IRWXU == (statbuf.st_mode & S_IRWXU))) { - printf("setuid mount allowed\n"); +#ifndef CIFS_ALLOW_USR_SUID + /* Do not allow user mounts to control suid flag + for mount unless explicitly built that way */ + flags |= MS_NOSUID | MS_NODEV; +#endif } else { printf("mount error: permission denied or not superuser and cifs.mount not installed SUID\n"); return -1; @@ -746,6 +790,12 @@ int main(int argc, char ** argv) optlen += strlen(mountpassword) + 6; options = malloc(optlen + 10); + if(options == NULL) { + printf("Could not allocate memory for mount options\n"); + return -1; + } + + options[0] = 0; strncat(options,"unc=",4); strcat(options,share_name); @@ -797,11 +847,32 @@ int main(int argc, char ** argv) mountent.mnt_fsname = share_name; mountent.mnt_dir = mountpoint; mountent.mnt_type = "cifs"; - mountent.mnt_opts = ""; + mountent.mnt_opts = malloc(200); + if(mountent.mnt_opts) { + memset(mountent.mnt_opts,0,200); + if(flags & MS_RDONLY) + strcat(mountent.mnt_opts,"ro"); + else + 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) + strcat(mountent.mnt_opts,",nosuid"); + if(flags & MS_NODEV) + strcat(mountent.mnt_opts,",nodev"); + if(flags & MS_SYNCHRONOUS) + strcat(mountent.mnt_opts,",synch"); + } mountent.mnt_freq = 0; mountent.mnt_passno = 0; rc = addmntent(pmntfile,&mountent); endmntent(pmntfile); + if(mountent.mnt_opts) + free(mountent.mnt_opts); } else { printf("could not update mount table\n"); } |