summaryrefslogtreecommitdiff
path: root/source3/client/smbmnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/client/smbmnt.c')
-rw-r--r--source3/client/smbmnt.c201
1 files changed, 92 insertions, 109 deletions
diff --git a/source3/client/smbmnt.c b/source3/client/smbmnt.c
index fa3cacb864..b7e30c3967 100644
--- a/source3/client/smbmnt.c
+++ b/source3/client/smbmnt.c
@@ -1,7 +1,8 @@
/*
- * smbmount.c
+ * smbmnt.c
*
* Copyright (C) 1995-1998 by Paal-Kr. Engstad and Volker Lendecke
+ * extensively modified by Tridge
*
*/
@@ -23,27 +24,24 @@
#include <linux/fs.h>
#endif
-static char *progname;
-
-
-static void
-usage(void)
-{
- printf("usage: %s mount-point [options]\n", progname);
- printf("Try `%s -h' for more information\n", progname);
-}
+static uid_t mount_uid;
+static gid_t mount_gid;
+static int mount_ro;
+static unsigned mount_fmask;
+static unsigned mount_dmask;
+static int user_mount;
static void
help(void)
{
printf("\n");
- printf("usage: %s mount-point [options]\n", progname);
- printf("-u uid uid the mounted files get\n"
- "-g gid gid the mounted files get\n"
- "-f mode permission the files get (octal notation)\n"
- "-d mode permission the dirs get (octal notation)\n"
- "-P pid connection handler's pid\n\n"
- "-s share share name on server\n\n"
+ printf("usage: smbmnt mount-point [options]\n");
+ printf("-s share share name on server\n"
+ "-r mount read-only\n"
+ "-u uid mount as uid\n"
+ "-g gid mount as gid\n"
+ "-f mask permission mask for files\n"
+ "-d mask permission mask for directories\n"
"-h print this help text\n");
}
@@ -51,55 +49,32 @@ static int
parse_args(int argc, char *argv[], struct smb_mount_data *data, char **share)
{
int opt;
- struct passwd *pwd;
- struct group *grp;
- while ((opt = getopt (argc, argv, "u:g:f:d:s:")) != EOF)
+ while ((opt = getopt (argc, argv, "s:u:g:rf:d:")) != EOF)
{
switch (opt)
{
+ case 's':
+ *share = optarg;
+ break;
case 'u':
- if (isdigit(optarg[0]))
- {
- data->uid = atoi(optarg);
- }
- else
- {
- pwd = getpwnam(optarg);
- if (pwd == NULL)
- {
- fprintf(stderr, "Unknown user: %s\n",
- optarg);
- return 1;
- }
- data->uid = pwd->pw_uid;
- }
+ if (!user_mount) {
+ mount_uid = strtol(optarg, NULL, 0);
+ }
break;
case 'g':
- if (isdigit(optarg[0]))
- {
- data->gid = atoi(optarg);
- }
- else
- {
- grp = getgrnam(optarg);
- if (grp == NULL)
- {
- fprintf(stderr, "Unknown group: %s\n",
- optarg);
- return 1;
- }
- data->gid = grp->gr_gid;
- }
+ if (!user_mount) {
+ mount_gid = strtol(optarg, NULL, 0);
+ }
+ break;
+ case 'r':
+ mount_ro = 1;
break;
case 'f':
- data->file_mode = strtol(optarg, NULL, 8);
+ mount_fmask = strtol(optarg, NULL, 8);
break;
case 'd':
- data->dir_mode = strtol(optarg, NULL, 8);
- break;
- case 's':
- *share = optarg;
+ mount_dmask = strtol(optarg, NULL, 8);
break;
default:
return -1;
@@ -114,32 +89,39 @@ fullpath(const char *p)
{
char path[MAXPATHLEN];
- if (strlen(p) > MAXPATHLEN-1)
- {
+ if (strlen(p) > MAXPATHLEN-1) {
return NULL;
}
- if (realpath(p, path) == NULL)
- {
- return strdup(p);
+ if (realpath(p, path) == NULL) {
+ fprintf(stderr,"Failed to find real path for mount point\n");
+ exit(1);
}
return strdup(path);
}
-/* Check whether user is allowed to mount on the specified mount point */
-static int
-mount_ok(SMB_STRUCT_STAT *st)
+/* Check whether user is allowed to mount on the specified mount point. If it's
+ OK then we change into that directory - this prevents race conditions */
+static int mount_ok(char *mount_point)
{
- if (!S_ISDIR(st->st_mode))
- {
+ SMB_STRUCT_STAT st;
+
+ if (chdir(mount_point) != 0) {
+ return -1;
+ }
+
+ if (sys_stat(".", &st) != 0) {
+ return -1;
+ }
+
+ if (!S_ISDIR(st.st_mode)) {
errno = ENOTDIR;
return -1;
}
-
- if ( (getuid() != 0)
- && ( (getuid() != st->st_uid)
- || ((st->st_mode & S_IRWXU) != S_IRWXU)))
- {
+
+ if ((getuid() != 0) &&
+ ((getuid() != st.st_uid) ||
+ ((st.st_mode & S_IRWXU) != S_IRWXU))) {
errno = EPERM;
return -1;
}
@@ -147,53 +129,48 @@ mount_ok(SMB_STRUCT_STAT *st)
return 0;
}
-int
-main(int argc, char *argv[])
+ int main(int argc, char *argv[])
{
char *mount_point, *share_name = NULL;
FILE *mtab;
- int fd, um;
+ int fd;
unsigned int flags;
struct smb_mount_data data;
- SMB_STRUCT_STAT st;
struct mntent ment;
- progname = argv[0];
-
memset(&data, 0, sizeof(struct smb_mount_data));
- if ( (argc == 2)
- && (argv[1][0] == '-')
- && (argv[1][1] == 'h')
- && (argv[1][2] == '\0'))
- {
+ if (argc < 2) {
+ help();
+ exit(1);
+ }
+
+ if (argv[1][0] == '-') {
help();
- return 0;
+ exit(1);
+ }
+
+ if (getuid() != 0) {
+ user_mount = 1;
}
if (geteuid() != 0) {
- fprintf(stderr, "%s must be installed suid root\n", progname);
+ fprintf(stderr, "smbmnt must be installed suid root for direct user mounts (%d,%d)\n", getuid(), geteuid());
exit(1);
}
- if (argc < 2)
- {
- usage();
- return 1;
- }
+ mount_uid = getuid();
+ mount_gid = getgid();
+ mount_fmask = umask(0);
+ umask(mount_fmask);
+ mount_fmask = ~mount_fmask;
- mount_point = argv[1];
+ mount_point = fullpath(argv[1]);
argv += 1;
argc -= 1;
- if (sys_stat(mount_point, &st) == -1) {
- fprintf(stderr, "could not find mount point %s: %s\n",
- mount_point, strerror(errno));
- exit(1);
- }
-
- if (mount_ok(&st) != 0) {
+ if (mount_ok(mount_point) != 0) {
fprintf(stderr, "cannot mount on %s: %s\n",
mount_point, strerror(errno));
exit(1);
@@ -204,19 +181,17 @@ main(int argc, char *argv[])
/* getuid() gives us the real uid, who may umount the fs */
data.mounted_uid = getuid();
- data.uid = getuid();
- data.gid = getgid();
- um = umask(0);
- umask(um);
- data.file_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & ~um;
- data.dir_mode = 0;
-
if (parse_args(argc, argv, &data, &share_name) != 0) {
- usage();
+ help();
return -1;
}
- if (data.dir_mode == 0) {
+ data.uid = mount_uid;
+ data.gid = mount_gid;
+ data.file_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & mount_fmask;
+ data.dir_mode = (S_IRWXU|S_IRWXG|S_IRWXO) & mount_dmask;
+
+ if (mount_dmask == 0) {
data.dir_mode = data.file_mode;
if ((data.dir_mode & S_IRUSR) != 0)
data.dir_mode |= S_IXUSR;
@@ -228,15 +203,23 @@ main(int argc, char *argv[])
flags = MS_MGC_VAL;
- if (mount(share_name, mount_point, "smbfs", flags, (char *)&data) < 0)
+ if (mount_ro) flags |= MS_RDONLY;
+
+ if (mount(share_name, ".", "smbfs", flags, (char *)&data) < 0)
{
- perror("mount error");
- printf("Please refer to the smbmnt(8) manual page\n");
+ switch (errno) {
+ case ENODEV:
+ fprintf(stderr, "ERROR: smbfs filesystem not supported by the kernel\n");
+ break;
+ default:
+ perror("mount error");
+ }
+ fprintf(stderr, "Please refer to the smbmnt(8) manual page\n");
return -1;
}
ment.mnt_fsname = share_name ? share_name : "none";
- ment.mnt_dir = fullpath(mount_point);
+ ment.mnt_dir = mount_point;
ment.mnt_type = "smbfs";
ment.mnt_opts = "";
ment.mnt_freq = 0;