summaryrefslogtreecommitdiffstats
path: root/source/client/smbmnt.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/client/smbmnt.c')
-rw-r--r--source/client/smbmnt.c285
1 files changed, 285 insertions, 0 deletions
diff --git a/source/client/smbmnt.c b/source/client/smbmnt.c
new file mode 100644
index 00000000000..fa3cacb8640
--- /dev/null
+++ b/source/client/smbmnt.c
@@ -0,0 +1,285 @@
+/*
+ * smbmount.c
+ *
+ * Copyright (C) 1995-1998 by Paal-Kr. Engstad and Volker Lendecke
+ *
+ */
+
+#include "includes.h"
+
+#include <mntent.h>
+
+#include <asm/types.h>
+#include <asm/posix_types.h>
+#include <linux/smb.h>
+#include <linux/smb_mount.h>
+#include <asm/unistd.h>
+
+#ifndef MS_MGC_VAL
+/* This may look strange but MS_MGC_VAL is what we are looking for and
+ is what we need from <linux/fs.h> under libc systems and is
+ provided in standard includes on glibc systems. So... We
+ switch on what we need... */
+#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 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"
+ "-h print this help text\n");
+}
+
+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)
+ {
+ switch (opt)
+ {
+ 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;
+ }
+ 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;
+ }
+ break;
+ case 'f':
+ data->file_mode = strtol(optarg, NULL, 8);
+ break;
+ case 'd':
+ data->dir_mode = strtol(optarg, NULL, 8);
+ break;
+ case 's':
+ *share = optarg;
+ break;
+ default:
+ return -1;
+ }
+ }
+ return 0;
+
+}
+
+static char *
+fullpath(const char *p)
+{
+ char path[MAXPATHLEN];
+
+ if (strlen(p) > MAXPATHLEN-1)
+ {
+ return NULL;
+ }
+
+ if (realpath(p, path) == NULL)
+ {
+ return strdup(p);
+ }
+ return strdup(path);
+}
+
+/* Check whether user is allowed to mount on the specified mount point */
+static int
+mount_ok(SMB_STRUCT_STAT *st)
+{
+ if (!S_ISDIR(st->st_mode))
+ {
+ errno = ENOTDIR;
+ return -1;
+ }
+
+ if ( (getuid() != 0)
+ && ( (getuid() != st->st_uid)
+ || ((st->st_mode & S_IRWXU) != S_IRWXU)))
+ {
+ errno = EPERM;
+ return -1;
+ }
+
+ return 0;
+}
+
+int
+main(int argc, char *argv[])
+{
+ char *mount_point, *share_name = NULL;
+ FILE *mtab;
+ int fd, um;
+ 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'))
+ {
+ help();
+ return 0;
+ }
+
+ if (geteuid() != 0) {
+ fprintf(stderr, "%s must be installed suid root\n", progname);
+ exit(1);
+ }
+
+ if (argc < 2)
+ {
+ usage();
+ return 1;
+ }
+
+ mount_point = 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) {
+ fprintf(stderr, "cannot mount on %s: %s\n",
+ mount_point, strerror(errno));
+ exit(1);
+ }
+
+ data.version = SMB_MOUNT_VERSION;
+
+ /* 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();
+ return -1;
+ }
+
+ if (data.dir_mode == 0) {
+ data.dir_mode = data.file_mode;
+ if ((data.dir_mode & S_IRUSR) != 0)
+ data.dir_mode |= S_IXUSR;
+ if ((data.dir_mode & S_IRGRP) != 0)
+ data.dir_mode |= S_IXGRP;
+ if ((data.dir_mode & S_IROTH) != 0)
+ data.dir_mode |= S_IXOTH;
+ }
+
+ flags = MS_MGC_VAL;
+
+ if (mount(share_name, mount_point, "smbfs", flags, (char *)&data) < 0)
+ {
+ perror("mount error");
+ printf("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_type = "smbfs";
+ ment.mnt_opts = "";
+ ment.mnt_freq = 0;
+ ment.mnt_passno= 0;
+
+ mount_point = ment.mnt_dir;
+
+ if (mount_point == NULL)
+ {
+ fprintf(stderr, "Mount point too long\n");
+ return -1;
+ }
+
+ if ((fd = open(MOUNTED"~", O_RDWR|O_CREAT|O_EXCL, 0600)) == -1)
+ {
+ fprintf(stderr, "Can't get "MOUNTED"~ lock file");
+ return 1;
+ }
+ close(fd);
+
+ if ((mtab = setmntent(MOUNTED, "a+")) == NULL)
+ {
+ fprintf(stderr, "Can't open " MOUNTED);
+ return 1;
+ }
+
+ if (addmntent(mtab, &ment) == 1)
+ {
+ fprintf(stderr, "Can't write mount entry");
+ return 1;
+ }
+ if (fchmod(fileno(mtab), 0644) == -1)
+ {
+ fprintf(stderr, "Can't set perms on "MOUNTED);
+ return 1;
+ }
+ endmntent(mtab);
+
+ if (unlink(MOUNTED"~") == -1)
+ {
+ fprintf(stderr, "Can't remove "MOUNTED"~");
+ return 1;
+ }
+
+ return 0;
+}