summaryrefslogtreecommitdiff
path: root/source/client/mount.cifs.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/client/mount.cifs.c')
-rwxr-xr-xsource/client/mount.cifs.c153
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");
}